Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/actions/run-eden-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ runs:
run: EDEN_TEST_STOP=n ./eden test ./tests/workflow -s ${{ inputs.suite }} -v debug
shell: bash
working-directory: "./eden"
- name: Collect coverage
if: always()
run: |
mkdir -p eden_coverage
./eden eve collect-coverage --output-dir ./eden_coverage || true
ls -la eden_coverage/ || true
shell: bash
working-directory: "./eden"
- name: Upload coverage artifact
if: always() && hashFiles('./eden/eden_coverage/eden_e2e_coverage.txt') != ''
uses: actions/upload-artifact@v4
with:
name: covdata-${{ inputs.suite }}-fs-${{ inputs.file_system }}-tpm-${{ inputs.tpm_enabled }}-attempt-${{ github.run_attempt }}
path: ./eden/eden_coverage/
if-no-files-found: warn
retention-days: 7
- name: Collect info
if: failure()
uses: ./eden/.github/actions/collect-info
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/eden.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
run_tests:
name: Execute Eden test workflow
uses: ./.github/workflows/test.yml
secrets: inherit
with:
eve_image: "lfedge/eve:16.6.0"
eve_kubevirt_image: "lfedge/eve:0.0.0-master-75241279-kubevirt-amd64"
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,51 @@ jobs:
eve_artifact_name: ${{ inputs.eve_artifact_name }}
artifact_run_id: ${{ inputs.artifact_run_id }}
require_virtualization: true

coverage-merge:
name: Merge coverage
needs: [smoke, networking, storage, lps-loc, eve-upgrade, user-apps, virtualization]
if: always()
runs-on: ubuntu-22.04
steps:
- uses: actions/setup-go@v3
with:
go-version: '1.24'
- name: Download per-job covdata artifacts
uses: actions/download-artifact@v4
with:
pattern: covdata-*
path: covdata-raw
- name: Merge covdata
run: |
set -e
mkdir -p covdata-merged
# Each artifact directory contains eden_e2e_coverage.txt and a
# covdata/coverage/ subtree with covmeta.* / covcounters.* files.
# Discover every GOCOVERDIR-shaped directory by looking for covmeta.*.
mapfile -t covdirs < <(find covdata-raw -name 'covmeta.*' -printf '%h\n' | sort -u)
if [ ${#covdirs[@]} -eq 0 ]; then
echo "::warning::No raw covdata found across jobs"
exit 0
fi
inputs=$(IFS=,; echo "${covdirs[*]}")
go tool covdata merge -i="$inputs" -o covdata-merged
go tool covdata textfmt -i=covdata-merged -o combined_coverage.txt
go tool cover -func=combined_coverage.txt | tee coverage-summary.txt
- name: Upload merged covdata
if: always() && hashFiles('combined_coverage.txt') != ''
uses: actions/upload-artifact@v4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now mandatory to have a codecov TOKEN in order to upload coverage data. See https://github.com/lf-edge/eve/blob/dc7f587911a2a3d39a459e1150f5758c51429e10/.github/workflows/publish.yml#L294 for reference.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — added an "Upload coverage to Codecov" step to the coverage-merge job using codecov/codecov-action@v6.0.0 with token: ${{ secrets.CODECOV_TOKEN }}, matching the EVE publish.yml reference. Since test.yml is a reusable workflow, eden.yml now passes secrets: inherit so the token reaches it. (This assumes CODECOV_TOKEN is configured as a secret on lf-edge/eden — let me know if it still needs to be added on the repo side.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed CODECOV_TOKEN is already configured on lf-edge/eden, so this works on push-to-master. Fork PRs get no secrets, so I set fail_ci_if_error: false to skip cleanly there.

with:
name: covdata-merged
path: |
covdata-merged/
combined_coverage.txt
coverage-summary.txt
retention-days: 30
- name: Upload coverage to Codecov
if: always() && hashFiles('combined_coverage.txt') != ''
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: combined_coverage.txt
fail_ci_if_error: false
24 changes: 13 additions & 11 deletions pkg/openevec/coverage.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,28 @@ func (openEVEC *OpenEVEC) CollectEveCoverage(outputDir string) error {
log.Warnf("EVE coverage: %v; proceeding with whatever was written", err)
}

// Copy binary coverage files from EVE to a local temp directory.
tmpDir, err := os.MkdirTemp("", "eve-coverage-*")
if err != nil {
return fmt.Errorf("cannot create temp dir: %w", err)
// Copy binary coverage files from EVE into <outputDir>/covdata so that
// callers wanting to merge coverage across multiple runs (e.g. across
// the Eden CI matrix) have access to the raw covmeta.* / covcounters.*
// files needed by `go tool covdata merge`.
covdataDir := filepath.Join(outputDir, "covdata")
if err := os.MkdirAll(covdataDir, 0755); err != nil {
return fmt.Errorf("cannot create covdata dir %s: %w", covdataDir, err)
}
defer os.RemoveAll(tmpDir)

log.Infof("EVE coverage: copying %s from EVE to %s",
defaults.DefaultEveCoverageDir, tmpDir)
defaults.DefaultEveCoverageDir, covdataDir)
if err := openEVEC.SdnForwardSCPDirFromEve(
defaults.DefaultEveCoverageDir, tmpDir); err != nil {
defaults.DefaultEveCoverageDir, covdataDir); err != nil {
return fmt.Errorf("cannot copy coverage data from EVE: %w", err)
}

// The SCP copies the directory itself, so the files land under
// tmpDir/coverage/. Point covdata at that sub-directory.
coverSubDir := filepath.Join(tmpDir, filepath.Base(defaults.DefaultEveCoverageDir))
// covdataDir/coverage/. Point covdata at that sub-directory.
coverSubDir := filepath.Join(covdataDir, filepath.Base(defaults.DefaultEveCoverageDir))
if _, err := os.Stat(coverSubDir); os.IsNotExist(err) {
// Fallback: files landed directly in tmpDir.
coverSubDir = tmpDir
// Fallback: files landed directly in covdataDir.
coverSubDir = covdataDir
}

// Convert binary coverage format → Go text profile format.
Expand Down
Loading