GH-78: Enforce the coverage target and audit resolved dependencies in CI - #132
Merged
Conversation
Two CI gaps the issue names.
Coverage was documented as a definition of done ("coverage >= 90 %") but never
machine-checked: the coverage script produced an HTML report nothing read. A new
`coverage` job runs the suite under pcov, emits a Clover report, and a small
gate script (`.github/scripts/coverage-gate.php`) reads its project-level line
metrics and fails the build below the threshold. The gate is a single job on one
interpreter - line coverage does not vary by PHP version - and the threshold
(90) is passed as an argument so the target lives in one place. Current line
coverage is 97.97 %, so the gate passes with headroom while catching a future
regression below 90 %. The gate rejects a non-numeric or out-of-range threshold
and a missing/unparsable report with exit 2, so a misconfiguration fails loud
rather than silently disabling the gate.
The dependency audit ran nowhere. dependency-review only inspects what a pull
request changes, so an advisory published against an existing dependency was
never caught. A new `composer-audit` job in security.yml resolves dependencies
fresh - this library does not commit composer.lock, so it audits the set a
consumer install produces, not a lock file - and runs `composer audit` on every
push and pull request AND on the existing weekly cron.
The gate script is covered by the existing PHPStan-max analysis of
`.github/scripts/` and was verified on every path (pass at 90, below-threshold,
non-numeric and out-of-range thresholds, missing and malformed reports).
AGENTS.md now records that the coverage target is machine-enforced.
Note for the maintainer: the two new jobs report red on failure but do not block
a merge until they are added to the protected branch's required status checks
("Coverage gate", "Composer audit") - a branch-protection change this commit
cannot make.
Verified: the ci:test suite is green (505 tests); the manifest validates; the
resolved-set audit reports no advisories; the coverage gate reports 97.97 %
which clears the 90 % target.
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Owner
Author
|
/gemini review |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
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.
Overview
Closes #78. Two CI gaps: the documented "coverage ≥ 90 %" definition of done was never machine-checked, and
composer auditran nowhere (dependency-review only inspects what a PR changes).Coverage gate
A new
coveragejob (PHP 8.3, pcov) runs the suite, emits a Clover report, and.github/scripts/coverage-gate.phpreads its project-level line metrics and fails the build below the threshold. Single interpreter — line coverage does not vary by PHP version. The threshold (90) is an argument so it lives in one place; a non-numeric or out-of-range threshold, or a missing/unparsable report, exits non-zero so a misconfiguration fails loud rather than silently disabling the gate. Current line coverage is 97.97 %.Dependency audit
A new
composer-auditjob insecurity.ymlruns on every push, PR, and the existing weekly cron. This library does not commitcomposer.lock, so the job resolves fresh against the declared constraints — the set a consumer install produces — and audits that, rather than a lock file that is not shipped.Maintainer action required
The two new jobs report red on failure but do not block a merge until they are added to
main's required status checks. Please add the contextsCoverage gateandComposer auditto branch protection (the existing required set is onlybuild (8.3/8.4/8.5)) — a change this PR cannot make.Verification
ci:testgreen (505 tests); the manifest validates; the resolved-set audit reports no advisories; the coverage gate reports 97.97 % ≥ 90 %. The gate script passes PHPStan level max and was verified on every path (pass, below-threshold, non-numeric/out-of-range threshold, missing/malformed report). Reviewed by the workflow, shell, PHP and Codex reviewers; their findings (the--locked-without-a-lockfile break, threshold validation, libxml warning suppression) are folded in.🤖 Generated with Claude Code