Skip to content

Commit bcfe4da

Browse files
committed
ci(coverage): gate PRs on 100% patch coverage
Adds diff-cover patch-coverage enforcement: every changed line in a PR must be covered by a test (--fail-under=100 vs origin/master). The node test runner is re-run with --enable-source-maps so the built-in lcov reporter maps coverage back to the src/*.ts sources (paths + line numbers) via the emitted .js.map files — otherwise lcov reports dist-test/*.js and the gate no-ops. Node 22 kept. New org mandate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 63f2718 commit bcfe4da

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

.github/workflows/coverage.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ jobs:
1515
timeout-minutes: 10
1616
steps:
1717
- uses: actions/checkout@v4
18+
with:
19+
# Full history so diff-cover can resolve origin/<base_ref>.
20+
fetch-depth: 0
1821
- uses: actions/setup-node@v4
1922
with:
2023
# >=22 for --test-coverage-exclude support (added 22.5.0).
@@ -26,3 +29,46 @@ jobs:
2629
if: always()
2730
with:
2831
fail_ci_if_error: false
32+
33+
# ------------------------------------------------------------------
34+
# Org patch-coverage mandate: every changed line in a PR diff must be
35+
# covered by a test (100%). Tool: diff-cover
36+
# (https://github.com/Bachmann1234/diff-cover).
37+
#
38+
# The node test runner reports coverage on the COMPILED JS in dist-test/.
39+
# `--enable-source-maps` makes the built-in lcov reporter rewrite both
40+
# the file paths and the line numbers back to the original TypeScript
41+
# sources (src/*.ts) via the emitted .js.map files, so diff-cover lines
42+
# up with the PR diff. Without it, lcov emits dist-test/src/*.js with
43+
# JS line numbers and the gate silently no-ops.
44+
# ------------------------------------------------------------------
45+
- name: Generate lcov mapped to TS sources
46+
if: github.event_name == 'pull_request'
47+
run: |
48+
npm run pretest
49+
mkdir -p coverage
50+
node --enable-source-maps --test --experimental-test-coverage \
51+
--test-coverage-exclude='dist-test/test/**' \
52+
--test-coverage-exclude='dist/**' \
53+
--test-coverage-exclude='node_modules/**' \
54+
--test-reporter=lcov --test-reporter-destination=coverage/lcov.info \
55+
--test-reporter=spec --test-reporter-destination=stdout \
56+
dist-test/test/integration.test.js \
57+
dist-test/test/live-smoke.test.js \
58+
dist-test/test/client-unit.test.js \
59+
dist-test/test/index-unit.test.js \
60+
dist-test/test/tools-unit.test.js
61+
- uses: actions/setup-python@v5
62+
if: github.event_name == 'pull_request'
63+
with:
64+
python-version: '3.12'
65+
- name: Install diff-cover
66+
if: github.event_name == 'pull_request'
67+
run: pip install diff-cover
68+
- name: Patch coverage gate (100% of changed lines)
69+
if: github.event_name == 'pull_request'
70+
run: |
71+
git fetch origin "${{ github.base_ref }}" --depth=1 || true
72+
diff-cover coverage/lcov.info \
73+
--compare-branch="origin/${{ github.base_ref }}" \
74+
--fail-under=100

0 commit comments

Comments
 (0)