Skip to content

Commit cd84239

Browse files
janedbalondrejmirtes
authored andcommitted
Add PR-affected-lines coverage gate via shipmonk/coverage-guard
Draft. Adds a pull_request-only job that runs the test suite with pcov coverage (mirroring the existing paratest coverage step), computes the GitHub three-dot diff (base...head) for the PR, and runs `coverage-guard check --patch` so only lines the PR changed are gated. Co-Authored-By: Claude Code
1 parent 92a35f5 commit cd84239

2 files changed

Lines changed: 121 additions & 0 deletions

File tree

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
2+
#
3+
# DRAFT — patch (PR-affected lines only) coverage gate via shipmonk/coverage-guard.
4+
# See https://github.com/shipmonk-rnd/coverage-guard
5+
#
6+
# Only runs on pull_request: it gates the lines the PR changed, so it has no
7+
# meaning on push to a maintained branch.
8+
9+
name: "Patch coverage"
10+
11+
on:
12+
pull_request:
13+
paths-ignore:
14+
- 'compiler/**'
15+
- 'apigen/**'
16+
- 'changelog-generator/**'
17+
- 'issue-bot/**'
18+
19+
concurrency:
20+
group: patch-coverage-${{ github.head_ref || github.run_id }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
patch-coverage:
25+
name: "Patch coverage"
26+
runs-on: ubuntu-latest
27+
timeout-minutes: 60
28+
29+
steps:
30+
- name: Harden the runner (Audit all outbound calls)
31+
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
32+
with:
33+
egress-policy: audit
34+
35+
# The default refs/pull/N/merge checkout: the coverage report and the
36+
# diff below are both taken on the merge commit, so their line numbers
37+
# refer to the same tree. Its first parent is the base branch tip, so
38+
# fetch-depth: 2 is enough for the diff. (A pull_request run does not
39+
# exist for a PR that conflicts with its base.)
40+
- name: "Checkout"
41+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
42+
with:
43+
fetch-depth: 2
44+
45+
- name: "Install PHP"
46+
uses: "shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc" # v2.37.1
47+
with:
48+
coverage: "pcov"
49+
php-version: "8.3"
50+
tools: pecl
51+
extensions: ds,mbstring
52+
ini-file: development
53+
ini-values: memory_limit=-1
54+
55+
- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0
56+
57+
- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0
58+
with:
59+
working-directory: "tests/"
60+
61+
# coverage-guard is not yet a dependency; install it ad-hoc for the gate.
62+
# If we decide to keep this, move it into require-dev instead.
63+
- name: "Install coverage-guard"
64+
run: composer require --dev shipmonk/coverage-guard --ignore-platform-reqs
65+
66+
# Mirror the proven-green coverage step from `make infection` /
67+
# the mutation-testing job (paratest + pcov over the whole suite), but
68+
# emit clover so coverage-guard can read it. paratest merges the
69+
# per-worker coverage for us, so no `coverage-guard merge` step is needed.
70+
- name: "Tests with coverage"
71+
run: |
72+
php -d pcov.enabled=1 tests/vendor/bin/paratest \
73+
--runner WrapperRunner \
74+
--passthru-php="'-d' 'pcov.enabled=1'" \
75+
--coverage-clover=coverage/clover.xml
76+
77+
# The merge commit against its first parent is exactly what merging
78+
# the PR changes on the base branch, with the "+" line numbers in the
79+
# coordinate system of the coverage report collected above.
80+
- name: "Compute PR diff"
81+
run: |
82+
git diff HEAD^1 HEAD > changes.patch
83+
echo "----- changed files -----"
84+
git diff --name-only HEAD^1 HEAD
85+
86+
- name: "Check patch coverage"
87+
run: vendor/bin/coverage-guard check coverage/clover.xml --patch changes.patch
88+
89+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
90+
if: ${{ !cancelled() }}
91+
with:
92+
name: patch-coverage
93+
path: |
94+
coverage/clover.xml
95+
changes.patch

‎coverage-guard.php‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php declare(strict_types = 1);
2+
3+
// DRAFT config for shipmonk/coverage-guard — https://github.com/shipmonk-rnd/coverage-guard
4+
//
5+
// Used by .github/workflows/patch-coverage.yml to gate coverage on the lines a
6+
// PR changes. Thresholds below are a starting point, tune to taste.
7+
8+
use ShipMonk\CoverageGuard\Config;
9+
use ShipMonk\CoverageGuard\Rule\EnforceCoverageForMethodsRule;
10+
11+
$config = new Config();
12+
13+
// The coverage report is produced by PHPUnit/paratest on the same runner that
14+
// runs the gate, so the absolute file paths inside clover.xml already live
15+
// under this directory — git root is enough, no path mapping needed.
16+
// (The monorepo needs addCoveragePathMapping() only because PHPUnit there runs
17+
// inside a container at a different WORKDIR than the checkout.)
18+
$config->setGitRoot(__DIR__);
19+
20+
$config->addRule(new EnforceCoverageForMethodsRule(
21+
requiredCoveragePercentage: 50,
22+
minMethodChangePercentage: 50,
23+
minExecutableLines: 5,
24+
));
25+
26+
return $config;

0 commit comments

Comments
 (0)