Skip to content

ci: retry the Codecov upload, and never let it fail a green run - #6012

Merged
renecannao merged 3 commits into
GH-Actionsfrom
ci/codecov-retry
Aug 9, 2026
Merged

ci: retry the Codecov upload, and never let it fail a green run#6012
renecannao merged 3 commits into
GH-Actionsfrom
ci/codecov-retry

Conversation

@renecannao

@renecannao renecannao commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

CI-mysql84-gr-g8 failed on #5998 with every test passing:

SUMMARY: 'tests' PASS 1/402 : FAIL 0/402 : SKIP 401/402
SUMMARY: ret_rc = [0]
##[error]Codecov: Failed to get OIDC token with url: https://codecov.io.
  Error Message: Request timeout: /37//idtoken/...

The only failing step was Upload coverage to Codecov. fail_ci_if_error: false does not cover this — the timeout happens while minting the GitHub OIDC token, before any upload — so the action fails the step and the step fails the job. A transient blip reds a run whose tests were entirely green.

Changes (47 workflows)

  1. Three attempts, chained on steps.codecov_N.outcome == 'failure', with 15 s / 45 s backoff.
  2. continue-on-error: true on each, so even three failures leave the job green; a ::warning:: is emitted instead. Coverage must never gate correctness.
  3. fail_ci_if_error: true — review catch, and without it most of this PR was inert: with it false, the action swallows upload errors, outcome stays success, and retries 1–2 are dead code. Only the OIDC failure fails the step regardless, so the retries would have covered exactly one failure mode.
  4. codecov-action pinned to a full commit SHA — SonarCloud flagged 94 new githubactions:S7637, all from duplicating an already-unpinned reference. Pinning all 141 refs clears the 94 new findings and the 47 pre-existing ones. Behaviourally a no-op today (v4v4.6.0b9fd7d16…), but a future repoint of the tag can no longer change what runs with our token.

outcome (not conclusion) is the field the retries branch on — continue-on-error rewrites conclusion to success, which would make them dead code.

All 47 files re-parse as valid YAML; the generated step chain was verified structurally.

Summary by CodeRabbit

  • Bug Fixes
    • Improved coverage-report uploads with up to three attempts, including delays between retries.
    • Coverage upload failures no longer fail test or validation workflows.
    • Added clear warnings when coverage uploads remain unsuccessful after all retries.
    • Uploads now run only when a valid coverage report is available and the workflow has not been cancelled.
    • Improved failure reporting and diagnostics to make upload issues easier to identify.

CI-mysql84-gr-g8 failed on #5998 with every test passing:

    SUMMARY: 'tests' PASS 1/402 : FAIL 0/402 : SKIP 401/402
    SUMMARY: ret_rc = [0]
    ##[error]Codecov: Failed to get OIDC token with url: https://codecov.io.
      Error Message: Request timeout: /37//idtoken/...

The only failing step was 'Upload coverage to Codecov'. fail_ci_if_error:
false does not cover this: the timeout happens while minting the GitHub
OIDC token, before any upload is attempted, so the action fails the step
and the step fails the job. A transient token-endpoint blip therefore reds
a run whose tests were entirely green -- which is exactly the kind of false
red that trains people to ignore CI.

Two changes to all 47 workflows that upload coverage:

  - Three attempts, chained on steps.codecov_N.outcome == 'failure', with
    15s and 45s waits between them. The observed failure is a transient
    request timeout, so a retry is very likely to succeed.

  - continue-on-error: true on each attempt, so even three failures leave
    the job green. Coverage reporting must never gate correctness. A
    ::warning:: annotation is emitted instead, so the loss is visible
    without being fatal.

outcome (not conclusion) is the right field to branch on: with
continue-on-error the conclusion is rewritten to success, while outcome
keeps the real result.

The explanatory comment block is kept only on the first attempt; the
retries carry the identical 'with:' block without it.
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

CI workflows now pin Codecov actions, gate uploads on coverage and cancellation state where configured, retry failed uploads after 15 and 45 seconds, and warn after three failures. Upload failures remain non-fatal to test jobs.

Changes

Codecov upload resilience

Layer / File(s) Summary
Upload gating and failure handling
.github/workflows/ci-basictests.yml, .github/workflows/ci-legacy-*.yml, .github/workflows/ci-mariadb10-galera-*.yml, .github/workflows/ci-mysql*.yml, .github/workflows/ci-no-infra-g1.yml, .github/workflows/ci-pgsql-socket-g1.yml, .github/workflows/ci-set_parser_algorithm_3-g1.yml, .github/workflows/ci-taptests-pgsql-cluster.yml
Codecov steps now use identifiers, coverage conditions, pinned action revisions, explicit failure reporting, and continue-on-error.
Delayed retry sequence
.github/workflows/ci-basictests.yml, .github/workflows/ci-legacy-*.yml, .github/workflows/ci-mariadb10-galera-*.yml, .github/workflows/ci-mysql*.yml, .github/workflows/ci-no-infra-g1.yml, .github/workflows/ci-pgsql-socket-g1.yml, .github/workflows/ci-set_parser_algorithm_3-g1.yml, .github/workflows/ci-taptests-pgsql-cluster.yml
Failed uploads trigger retries after 15 and 45 seconds. Each retry reuses the Codecov configuration. A warning runs after three failed attempts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Poem

A rabbit checks each coverage hop,
Then waits and tries when uploads stop.
Fifteen seconds, then forty-five,
Three attempts keep the tests alive.
A warning marks the final drop.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: retrying Codecov uploads without failing an otherwise successful CI run.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/codecov-retry

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci-basictests.yml:
- Around line 321-323: Configure every codecov_1, codecov_2, and codecov_3
upload step to set fail_ci_if_error to true while retaining continue-on-error:
true, so upload failures produce failure outcomes and trigger retries without
failing the job. Apply this change in
.github/workflows/ci-basictests.yml:321-323,
.github/workflows/ci-legacy-clickhouse-g1.yml:237-239,
.github/workflows/ci-legacy-g1.yml:304-306,
.github/workflows/ci-legacy-g2-genai.yml:250-252,
.github/workflows/ci-mysql84-g4.yml:304-306,
.github/workflows/ci-mysql84-g5.yml:234-236,
.github/workflows/ci-mysql84-g6.yml:236-238,
.github/workflows/ci-mysql84-g7.yml:236-238,
.github/workflows/ci-mysql84-g8.yml:236-238,
.github/workflows/ci-mysql84-g9.yml:236-238,
.github/workflows/ci-mysql84-gr-g1.yml:229-231, and
.github/workflows/ci-mysql84-gr-g2.yml:229-231.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a5edd882-11a8-4f57-8584-93d285b88cc8

📥 Commits

Reviewing files that changed from the base of the PR and between 75e7207 and e14441e.

📒 Files selected for processing (47)
  • .github/workflows/ci-basictests.yml
  • .github/workflows/ci-legacy-clickhouse-g1.yml
  • .github/workflows/ci-legacy-g1.yml
  • .github/workflows/ci-legacy-g2-genai.yml
  • .github/workflows/ci-legacy-g2.yml
  • .github/workflows/ci-legacy-g3.yml
  • .github/workflows/ci-legacy-g4.yml
  • .github/workflows/ci-legacy-g5.yml
  • .github/workflows/ci-legacy-g6.yml
  • .github/workflows/ci-legacy-g7.yml
  • .github/workflows/ci-legacy-g8.yml
  • .github/workflows/ci-legacy-g9.yml
  • .github/workflows/ci-mariadb10-galera-g1.yml
  • .github/workflows/ci-mariadb10-galera-g2.yml
  • .github/workflows/ci-mariadb10-galera-g3.yml
  • .github/workflows/ci-mariadb10-galera-g4.yml
  • .github/workflows/ci-mariadb10-galera-g5.yml
  • .github/workflows/ci-mariadb10-galera-g6.yml
  • .github/workflows/ci-mariadb10-galera-g7.yml
  • .github/workflows/ci-mariadb10-galera-g8.yml
  • .github/workflows/ci-mariadb10-galera-g9.yml
  • .github/workflows/ci-mysql56-single-g1.yml
  • .github/workflows/ci-mysql84-g1.yml
  • .github/workflows/ci-mysql84-g2.yml
  • .github/workflows/ci-mysql84-g3.yml
  • .github/workflows/ci-mysql84-g4.yml
  • .github/workflows/ci-mysql84-g5.yml
  • .github/workflows/ci-mysql84-g6.yml
  • .github/workflows/ci-mysql84-g7.yml
  • .github/workflows/ci-mysql84-g8.yml
  • .github/workflows/ci-mysql84-g9.yml
  • .github/workflows/ci-mysql84-gr-g1.yml
  • .github/workflows/ci-mysql84-gr-g2.yml
  • .github/workflows/ci-mysql84-gr-g3.yml
  • .github/workflows/ci-mysql84-gr-g4.yml
  • .github/workflows/ci-mysql84-gr-g5.yml
  • .github/workflows/ci-mysql84-gr-g6.yml
  • .github/workflows/ci-mysql84-gr-g7.yml
  • .github/workflows/ci-mysql84-gr-g8.yml
  • .github/workflows/ci-mysql84-gr-g9.yml
  • .github/workflows/ci-mysql90-gr-g1.yml
  • .github/workflows/ci-mysql93-gr-g1.yml
  • .github/workflows/ci-mysql95-gr-g1.yml
  • .github/workflows/ci-no-infra-g1.yml
  • .github/workflows/ci-pgsql-socket-g1.yml
  • .github/workflows/ci-set_parser_algorithm_3-g1.yml
  • .github/workflows/ci-taptests-pgsql-cluster.yml
📜 Review details
🔇 Additional comments (35)
.github/workflows/ci-legacy-g2.yml (1)

309-311: LGTM!

Also applies to: 327-375

.github/workflows/ci-legacy-g3.yml (1)

304-306: LGTM!

Also applies to: 353-401

.github/workflows/ci-legacy-g4.yml (1)

305-307: LGTM!

Also applies to: 354-402

.github/workflows/ci-legacy-g5.yml (1)

302-304: LGTM!

Also applies to: 351-399

.github/workflows/ci-legacy-g6.yml (1)

304-306: LGTM!

Also applies to: 353-401

.github/workflows/ci-mysql84-gr-g3.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql84-gr-g4.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql84-gr-g5.yml (1)

227-229: LGTM!

Also applies to: 276-324

.github/workflows/ci-mysql84-gr-g6.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql84-gr-g7.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql84-gr-g8.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql84-gr-g9.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-legacy-g7.yml (1)

304-306: LGTM!

Also applies to: 353-401

.github/workflows/ci-legacy-g8.yml (1)

236-238: LGTM!

Also applies to: 285-333

.github/workflows/ci-legacy-g9.yml (1)

236-238: LGTM!

Also applies to: 285-333

.github/workflows/ci-mariadb10-galera-g1.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mariadb10-galera-g2.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql90-gr-g1.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql93-gr-g1.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql95-gr-g1.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-no-infra-g1.yml (1)

303-305: LGTM!

Also applies to: 352-400

.github/workflows/ci-pgsql-socket-g1.yml (1)

236-238: LGTM!

Also applies to: 285-333

.github/workflows/ci-set_parser_algorithm_3-g1.yml (1)

236-238: LGTM!

Also applies to: 285-333

.github/workflows/ci-taptests-pgsql-cluster.yml (1)

266-282: LGTM!

Also applies to: 284-314, 330-332

.github/workflows/ci-mariadb10-galera-g3.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mariadb10-galera-g4.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mariadb10-galera-g5.yml (1)

227-229: LGTM!

Also applies to: 276-324

.github/workflows/ci-mariadb10-galera-g6.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mariadb10-galera-g7.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mariadb10-galera-g8.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mariadb10-galera-g9.yml (1)

229-231: LGTM!

Also applies to: 278-326

.github/workflows/ci-mysql56-single-g1.yml (1)

242-244: LGTM!

Also applies to: 291-339

.github/workflows/ci-mysql84-g1.yml (1)

304-306: LGTM!

Also applies to: 353-401

.github/workflows/ci-mysql84-g2.yml (1)

304-306: LGTM!

Also applies to: 353-401

.github/workflows/ci-mysql84-g3.yml (1)

304-306: LGTM!

Also applies to: 353-401

Comment thread .github/workflows/ci-basictests.yml
Review catch, and it would have made most of the previous commit inert.

With 'fail_ci_if_error: false' the action swallows upload errors and the
step outcome stays 'success', so 'steps.codecov_N.outcome == "failure"'
never matches and retries 1 and 2 are dead code. Only the OIDC token
failure that motivated this work fails the step regardless -- that one is
raised before any upload is attempted -- so the retries would have covered
exactly one failure mode and silently skipped every other.

Setting it true makes every Codecov failure visible to the retry chain.
The job is still kept green by 'continue-on-error: true' on all three
attempts, which is the property that actually matters: coverage reporting
must never gate correctness. After three failures the run stays green and
emits a ::warning:: annotation.

185 occurrences across 47 workflows, plus the stale rationale comment on
each first attempt, which still credited fail_ci_if_error for the
never-fail-the-job behaviour that continue-on-error now provides.
SonarCloud reported 94 new githubactions:S7637 issues on this branch ('Use
full commit SHA hash for this dependency'), all of them the same thing:
duplicating the upload step for the retry chain tripled the number of
references to an already-unpinned action, so 47 files x 2 new copies became
94 new findings.

Waiving them would be the wrong call. The rule is real -- codecov-action
runs with the job token, and a mutable tag can be repointed at arbitrary
code -- and the duplication is mine, so the noise is mine to clear.

Pinning all 141 references to the commit v4 already resolves to fixes both
the 94 new findings and the 47 pre-existing ones, leaving zero.

Behaviourally this is a no-op today: v4 currently points at v4.6.0, which
is b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238, so the same code runs before
and after. What changes is that a future repoint of the v4 tag no longer
silently changes what executes with our token. The version is kept visible
as a trailing '# v4.6.0' comment so bumps stay deliberate and reviewable.

The remaining 'codecov-action@v4' matches in these files are prose inside
the permissions comment, not action references.
@renecannao
renecannao merged commit 8a77264 into GH-Actions Aug 9, 2026
1 check passed
@sonarqubecloud

sonarqubecloud Bot commented Aug 9, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant