Skip to content

Commit 6da67bd

Browse files
sudoshiruvnet
andcommitted
ci(backend): enforce a coverage floor with pcov + explicit clover parse
Backend CI ran coverage: none, so there was no coverage gate. Enables pcov, writes a clover report from the Pest run, and adds an explicit floor check that parses the project-level aggregate metrics (xpath) and fails below the floor — robust rather than relying on Pest's exit code or log-string matching. Initial floor is a conservative 25% (a 315-test-file suite clears this with wide margin) and is a one-way ratchet toward 80% as coverage grows. Backend job timeout raised 35 to 45 minutes to absorb pcov instrumentation overhead. Parse logic verified locally against synthetic clover (40% vs 25% floor passes; 40% vs 50% floor fails). Co-Authored-By: claude-flow <ruv@ruv.net>
1 parent 4c01c83 commit 6da67bd

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ jobs:
1919
backend:
2020
name: Backend (Laravel)
2121
runs-on: ubuntu-latest
22-
timeout-minutes: 35
22+
# 45 (was 35): pcov coverage instrumentation adds overhead to the Pest run.
23+
timeout-minutes: 45
2324
services:
2425
postgres:
2526
image: pgvector/pgvector:pg16
@@ -74,7 +75,7 @@ jobs:
7475
with:
7576
php-version: "8.4"
7677
extensions: pdo_pgsql, pgsql, redis, bcmath, intl, mbstring, pcntl, zip
77-
coverage: none
78+
coverage: pcov
7879

7980
- name: Install Composer dependencies
8081
working-directory: backend
@@ -118,6 +119,7 @@ jobs:
118119
php artisan migrate --force
119120
set +e
120121
./vendor/bin/pest \
122+
--coverage-clover=coverage.xml \
121123
--do-not-fail-on-skipped \
122124
--do-not-fail-on-warning \
123125
--do-not-fail-on-phpunit-warning \
@@ -143,6 +145,31 @@ jobs:
143145
exit "$pest_status"
144146
fi
145147
148+
- name: Enforce coverage floor
149+
working-directory: backend
150+
run: |
151+
# Robust, explicit floor: parse the clover report's project-level
152+
# aggregate metrics rather than relying on Pest's exit code / log text.
153+
# Conservative initial floor; ratchet up toward 80% as coverage grows.
154+
# NEVER lower this value — it is a one-way ratchet.
155+
php -r '
156+
$floor = 25.0;
157+
$f = "coverage.xml";
158+
if (!is_file($f)) { fwrite(STDERR, "coverage.xml not found — coverage was not collected\n"); exit(1); }
159+
$xml = simplexml_load_file($f);
160+
$nodes = $xml->xpath("/coverage/project/metrics");
161+
if (!$nodes) { fwrite(STDERR, "no project metrics in clover report\n"); exit(1); }
162+
$m = end($nodes);
163+
$stmts = (int) $m["statements"];
164+
$covered = (int) $m["coveredstatements"];
165+
$pct = $stmts > 0 ? ($covered / $stmts) * 100.0 : 0.0;
166+
printf("Line coverage: %.2f%% (%d/%d statements); floor %.1f%%\n", $pct, $covered, $stmts, $floor);
167+
if ($pct + 1e-9 < $floor) {
168+
fwrite(STDERR, sprintf("::error::Coverage %.2f%% is below the %.1f%% floor\n", $pct, $floor));
169+
exit(1);
170+
}
171+
'
172+
146173
frontend:
147174
name: Frontend (React)
148175
runs-on: ubuntu-latest

0 commit comments

Comments
 (0)