From 712b28fb939ae81ad51708ff35c724b18a853cee Mon Sep 17 00:00:00 2001 From: Mikita Hradovich Date: Mon, 5 Oct 2026 22:56:16 +0200 Subject: [PATCH] ci: close the gaps in the Codecov upload Restore the per-lane execution data check that #1162's rewrite dropped, so a lane passing without agent data no longer uploads a partial baseline. Skip the upload outside scylladb/java-driver, count JaCoCo partials as hits to match the job summary, turn off the CLI's non-Java plugins and fix the stale job name in codecov.yml. Fixes #1206 Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/tests@v1.yml | 32 +++++++++++++++++++++++++++++--- README-dev.md | 7 ++++--- codecov.yml | 12 ++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests@v1.yml b/.github/workflows/tests@v1.yml index d39c950c304..61c443250e1 100644 --- a/.github/workflows/tests@v1.yml +++ b/.github/workflows/tests@v1.yml @@ -494,9 +494,10 @@ jobs: continue-on-error: true timeout-minutes: 20 # continue-on-error reports this job to the jobs that need it as a success - # even when it failed, so the Codecov upload reads this instead. + # even when it failed, so the Codecov upload reads this instead. The lanes + # check is continue-on-error of its own, so it is read separately. outputs: - built: ${{ steps.aggregate.outcome == 'success' && steps.upload-report.outcome == 'success' }} + built: ${{ steps.lanes.outcome == 'success' && steps.aggregate.outcome == 'success' && steps.upload-report.outcome == 'success' }} # Only needs to read the checkout; same-run artifacts are handled by the # Actions runtime token rather than GITHUB_TOKEN. Scoped on this job alone @@ -580,6 +581,27 @@ jobs: done find . -name 'jacoco-*.exec' -printf '%p\t%s bytes\n' + # A lane can pass without its JaCoCo agent having recorded anything. The + # report still renders for diagnosis, but is not handed to Codecov. + - name: Check that every lane handed over execution data + id: lanes + continue-on-error: true + run: | + shopt -s nullglob + missing=() + for lane in coverage-exec/*/; do + found=0 + for exec_file in "$lane"*.exec; do + [[ -s "$exec_file" ]] && found=1 + done + lane_name="$(basename "$lane")" + [[ $found -eq 1 ]] || missing+=("${lane_name#coverage-exec-}") + done + if [[ ${#missing[@]} -gt 0 ]]; then + echo "::error::No execution data from ${missing[*]}; this report is incomplete, so it is not uploaded to Codecov." + exit 1 + fi + - name: Aggregate coverage id: aggregate run: make coverage-report @@ -600,12 +622,14 @@ jobs: # apart, so a failed JDK 11 leg, which records no coverage, holds the upload # back as well. Pull requests from forks get no secrets and upload without a # token; neither that nor a Dependabot run, which gets no CODECOV_TOKEN, - # fails on a refused upload. + # fails on a refused upload. A fork's own push runs have no token and no + # Codecov project, so they skip the job. codecov: name: Upload coverage to Codecov runs-on: ubuntu-latest needs: [unit-tests, cassandra-integration-tests, scylla-integration-tests, coverage-report] if: >- + github.repository == 'scylladb/java-driver' && needs.unit-tests.result == 'success' && needs.cassandra-integration-tests.result == 'success' && needs.scylla-integration-tests.result == 'success' && @@ -633,4 +657,6 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} files: coverage-report/jacoco.xml disable_search: true + # The CLI's gcov, Xcode and coverage.py plugins have nothing to find here. + plugins: noop fail_ci_if_error: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]') }} diff --git a/README-dev.md b/README-dev.md index 8cd60c06afb..e0a034d602c 100644 --- a/README-dev.md +++ b/README-dev.md @@ -79,9 +79,10 @@ as an artifact. That job is `continue-on-error`, so a flaky integration test cos data rather than adding a second failure to the pull request. Collecting from the existing lanes rather than a dedicated workflow keeps the Scylla suite from being run twice. -When every test lane passed, the next job uploads that `jacoco.xml` to -[Codecov](https://codecov.io/gh/scylladb/java-driver), which comments the coverage delta on the -pull request. Its statuses are informational, so a drop never blocks a merge. +When every test lane passed and handed over execution data, the next job uploads that `jacoco.xml` +to [Codecov](https://codecov.io/gh/scylladb/java-driver), which comments the coverage delta on the +pull request. Its statuses are informational, so a drop never blocks a merge. The upload runs only +in scylladb/java-driver; a fork's push runs skip it. Only the lanes on `COVERAGE_JAVA_VERSION` (a workflow-level variable, JDK 17) are instrumented. javac 11 and javac 17 do not emit the same bytes for the same source even under `--release 11` -- diff --git a/codecov.yml b/codecov.yml index 202d7aa54ef..48150813ab8 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,5 +1,5 @@ -# Codecov configuration for the upload in the "Coverage report" job of -# .github/workflows/tests@v1.yml. +# Codecov configuration for the upload in the "Upload coverage to Codecov" job +# of .github/workflows/tests@v1.yml. # Reference: https://docs.codecov.com/docs/codecov-yaml # # There are no path fixes: each package/sourcefile pair in jacoco.xml names @@ -19,6 +19,14 @@ codecov: # own lanes. max_report_age: false +parsers: + jacoco: + # Counts a line with partly covered branches as covered, as JaCoCo's own + # line counter and the "Coverage report" job summary do. The cost: Codecov + # no longer marks such lines partial, so a half-tested condition counts + # fully toward patch coverage. The report artifact still shows it. + partials_as_hits: true + coverage: status: # Informational: report the delta, never fail a pull request on it. The