Skip to content

ci(coverage): enforce PR coverage floor in pytest, not via Codecov (LAB-3609) - #291

Merged
27Bslash6 merged 1 commit into
mainfrom
agent/mark-s/f1d5703d6348
Sep 14, 2026
Merged

27Bslash6 merged 1 commit into
mainfrom
agent/mark-s/f1d5703d6348

Conversation

@27Bslash6

@27Bslash6 27Bslash6 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

What & why

The PR coverage floor cachekit-py declares (codecov.yml: project auto ± 2%, patch 80%, carryforward: true on every flag) is computed only from coverage.xml reaching Codecov. Any path where that upload is dropped or skipped (a fork PR's tokenless 429, a Codecov/keybase outage) leaves the declared floor stale-green or absent — on exactly the least-trusted contributions.

This moves the total-coverage floor into the test job itself: --cov-fail-under=82 on the final PR pytest invocation. A PR whose combined coverage falls below the floor now fails the Tests job inside pytest, with no dependency on the Codecov upload. Codecov keeps the finer-grained new-code (patch) status as a reporting-only signal.

Closes LAB-3609.

The floor: --cov-fail-under=82

Placed on the final --cov-append invocation (tests/critical/) so it evaluates the combined tests/unit + tests/critical cumulative total, not the first sub-suite alone. (Confirmed in the run below: the unit-only intermediate TOTAL is 82.70%, the combined --cov-append TOTAL is 84.50% — a config-level [tool.coverage.report] fail_under would gate the 82.70% intermediate at the wrong point, which is why the flag lives on the final invocation.)

Derivation

Rule (mirrors codecov.yml's declared 2% project tolerance, not a new number): PR-run floor = lowest cumulative TOTAL across the PR matrix on a same-repo PR run, minus 2, floored to a whole percent. The PR matrix is Python 3.12 only (ci.yml: pull_request["3.12"]), so the "matrix" is one version.

Python Combined --cov-append TOTAL (unit + critical) Source
3.12 84.50% this PR's CI run — Tests (Python 3.12)

floor(84.50 − 2) = floor(82.50) = 82.

Proof of failure (floor above measured → red inside pytest)

Local reproduction of the exact PR path (unit, then critical --cov-append) on py3.12, with the floor set above the measured total:

$ uv run pytest tests/unit/ ... --cov=src/cachekit ...
$ uv run pytest tests/critical/ ... --cov-append --cov-fail-under=90 ...
TOTAL                                                7077   1017   2062    229  84.20%
FAIL Required test coverage of 90% not reached. Total coverage: 84.20%
$ echo $?
1

pytest exits non-zero with FAIL Required test coverage of N% not reached, in the test step — before the Upload coverage to Codecov step would run.

Proof of pass

This PR's own CI is green on every Python version in the PR matrix (3.12) with --cov-fail-under=82 in place — Tests (Python 3.12), 2m10s, Required test coverage of 82% reached. Total coverage: 84.50%.

Floor independent of Codecov

The coverage pass/fail is decided in the Run tests (PRs) step, which runs before Upload coverage to Codecov in the same job (verified in the run log's step order). With the upload step's outcome held constant, the job's red/green on coverage is already settled by the pytest --cov-fail-under step; the upload's success no longer gates the floor.

Other changes

  • Makefile test-cov: floor 60 → 82, mirroring the CI floor. That target runs the full suite (≥ the PR path's unit+critical coverage), so it clears the floor with margin; a comment records the contract to keep the two literals in step.
  • ci.yml residual-risk comment: rewritten — the total floor is now enforced locally; Codecov solely owns the patch (new-code) status, which stays carryforward-capable (the narrowed, accepted residual). The old "the real fix … tracked separately" pointer is removed now that the fix has landed.
  • CONTRIBUTING.md: documents the enforced total floor. The literal itself is not repeated in the doc (it points at ci.yml), so the value has exactly two authoritative homes — ci.yml and the Makefile — both under the "keep in step" contract.

Scope

Total-coverage safety net only. Patch-level (diff) coverage stays a Codecov patch status (not enforced locally — out of scope). codecov.yml targets/flags/carryforward untouched. The push-to-main full-suite path is not a PR gate and is left uncapped.

…AB-3609)

Add --cov-fail-under=82 to the final PR pytest invocation so the combined
unit+critical total is gated inside the job, independent of the Codecov
upload succeeding. A dropped/degraded upload (fork-PR tokenless 429, Codecov
outage) can no longer answer the total-coverage question with a stale
carryforward. Codecov keeps the finer-grained new-code (patch) status.

- .github/workflows/ci.yml: floor on the --cov-append final run; residual-risk
  comment rewritten (total floor now local; Codecov owns patch).
- Makefile: test-cov floor 60 -> 82, mirrors CI (full suite clears it).
- CONTRIBUTING.md: document the enforced total floor.

82 = current main PR-path cumulative TOTAL 84.20% (py3.12, only PR matrix
version) minus codecov.yml declared 2% tolerance, floored.
@kodus-27b

kodus-27b Bot commented Sep 14, 2026

Copy link
Copy Markdown

Kody Review Complete

Great news! 🎉
No issues were found that match your current review configurations.

Keep up the excellent work! 🚀

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Business Logic

Access your configuration settings here.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: 7fe7bb8c-14af-447f-a219-81c094ddc7f3

📥 Commits

Reviewing files that changed from the base of the PR and between 15a24de and 196d7bc.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • CONTRIBUTING.md
  • Makefile

Included review availability: 1 review is currently available. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.


Walkthrough

The pull request raises the enforced total pytest coverage threshold from 60% to 82% in local and CI commands. It also documents the distinction between pytest total coverage enforcement and Codecov patch coverage reporting.

Changes

Coverage threshold enforcement

Layer / File(s) Summary
Enforce the 82% coverage threshold
.github/workflows/ci.yml, Makefile
The critical CI test command and make test-cov now fail below 82% total coverage. Comments link both thresholds to the pull-request coverage floor.
Document coverage responsibilities
.github/workflows/ci.yml, CONTRIBUTING.md
The documentation states that pytest enforces total coverage, while Codecov reports patch coverage and retains its documented fork-upload and CLI signature-check limitations.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 196d7

The 82% total-coverage floor is consistently enforced in pull-request CI and the local coverage target, with no actionable merge-blocking risk identified.

🚥 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. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
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.
Title check ✅ Passed The title clearly identifies the main change: enforcing the pull request coverage floor in pytest instead of Codecov. It is concise and specific.
Description check ✅ Passed The description provides detailed motivation, implementation scope, coverage-floor derivation, test evidence, and residual-risk context. It does not reproduce the template headings or explicitly compl…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/mark-s/f1d5703d6348

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

@27Bslash6
27Bslash6 merged commit 284fa7e into main Sep 14, 2026
39 checks passed
@27Bslash6
27Bslash6 deleted the agent/mark-s/f1d5703d6348 branch September 14, 2026 07:52
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