ci: Coverage Floor — opt-in pre_measured_coverage_artifact#73
Merged
Conversation
Adds a new optional input `pre_measured_coverage_artifact` to the Coverage Floor reusable. When set, the reusable: - Downloads an artifact of that name from the same workflow_run - Reads `coverage-percent.txt` (single-line numeric) from the artifact - Skips the language-specific install + test invocation entirely - Runs only the floor comparison + seed + sticky-comment logic Use case: repos that already run pytest --cov (or go cover / vitest) in their own CI workflow can have Coverage Floor read the result instead of re-running the whole test suite. Saves ~50% of Coverage Floor's per-run minutes for these repos. Background: GitHub Actions hit 90% of the May 2026 budget on the topcoder1 account. Audit traced the top burners to Coverage Floor + CI running the same pytest invocation twice across ~20 fleet repos (webcrawl alone: ~290 min/wk Coverage Floor + ~287 min/wk CI test job, mostly the same work). This change is the architectural fix. Implementation: - New input `pre_measured_coverage_artifact: string`, default empty (existing behavior preserved) - New step `Download pre-measured coverage artifact` gated on the input being non-empty - All language setup steps (setup-python/go/node, install uv, git cross-org config) gated to skip when the input is set - Existing `Measure coverage` step renamed to `Measure coverage` / id `measure_fresh`, gated `if: input == ''` - New step `Read coverage from pre-measured artifact` / id `measure_cached`, gated `if: input != ''` - All downstream consumers updated to read `steps.measure_fresh.outputs.measured || steps.measure_cached.outputs.measured` (GHA's `||` returns the first truthy value, so only the running step's output is consulted) Backwards compatibility: 100%. Existing ~20 fleet callers don't pass the new input, get identical behavior. The self-test of this reusable (selftest/sample.py at 99% coverage) also unaffected. Caller migration plan: opt-in per repo. First proof point is topcoder1/webcrawl (separate PR — see [topcoder1/webcrawl#TBD]). After 1 week of clean runs there, port to remaining ~12 repos via a rollout script in scripts/install-coverage-floor-dedup.sh. Side note: services_postgres and services_redis declarations remain at the job level (GHA doesn't support conditional services). When pre_measured is set, these still spin up but unused — ~5-10 sec overhead per run. Acceptable for now; could be refactored later by splitting into two jobs gated on input. Auto-merge rationale: change to a shared reusable workflow that ~20 callers reference. Touches .github/workflows/** which is high-risk per claude-author-automerge.yml policy — manual click-merge required. actionlint passes. Backwards-compatible by design. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Coverage Floor — mode:
|
|
No issues found. Logic is sound: skipped-step outputs are correctly falsy for the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new optional input
pre_measured_coverage_artifactto the Coverage Floor reusable. When set, the reusable downloads acoverage-percent.txtfrom the named artifact, parses the percentage, and skips the install + test step entirely — runs only the floor comparison + seed + sticky-comment logic.Why
GitHub Actions hit 90% of the May 2026 budget on the topcoder1 account on 2026-05-23. The fleet audit traced the top burn to Coverage Floor + CI running the same
pytest --covinvocation twice across ~20 repos. webcrawl alone: ~290 min/wk on Coverage Floor + ~287 min/wk on CI's test job, mostly the same work.This change is the architectural fix. ~50% reduction in Coverage Floor minutes for any repo that opts in.
Design doc
Full architecture write-up + alternatives considered:
proposals/2026-05-23-coverage-floor-dedup-design.mdin product-center (not yet committed there — local-only for now, but the relevant excerpt:needs:dependencyBackwards compatibility
100%. Existing ~20 fleet callers don't pass the new input → identical behavior. Self-test of this reusable (selftest/sample.py @ 99% coverage) also unaffected. Defaults preserved everywhere.
What changes in this PR
pre_measured_coverage_artifact: string(default empty)Download pre-measured coverage artifactgatedif: input != ''Measure coveragestep renamed to idmeasure_fresh, gatedif: input == ''Read coverage from pre-measured artifactidmeasure_cached, gatedif: input != ''${{ steps.measure_fresh.outputs.measured || steps.measure_cached.outputs.measured }}— GHA's||returns the first truthy value, so only the running step's output is consultedDiff: +71/-11 lines in
.github/workflows/coverage-floor.yml, nothing else touched.Follow-up PRs
topcoder1/webcrawl): wires up the opt-in as the proof point. Will be filed in parallel; its first CI run will fail until this PR merges (the new input doesn't exist on@mainyet).scripts/install-coverage-floor-dedup.sh.Side note (out of scope)
The
services_postgresandservices_redisdeclarations remain at job level (GHA doesn't support conditional services). Whenpre_measuredis set, these still spin up but unused — ~5-10 sec overhead per run. Acceptable; could refactor later by splitting into two jobs gated on input.Auto-merge rationale
Change to a shared reusable workflow that ~20 callers reference. Touches
.github/workflows/**— high-risk perclaude-author-automerge.ymlpolicy → manual click-merge required. actionlint clean. Backwards-compatible by design.Test plan
pull_requesttrigger runs against selftest/sample.py @ 99% coverage; newif:gates evaluate to "run the existing path" because input is empty)🤖 Generated with Claude Code