Skip to content

Commit c41da96

Browse files
ci(coverage): gate PRs on 100% patch coverage + 95% project floor (#32)
Adds diff-cover patch-coverage enforcement to the coverage workflow: every changed line in a PR must be covered by a test (--fail-under=100), and the total project coverage must stay >=95%. Go coverage is converted to Cobertura via gocover-cobertura so diff-cover can read it. Gated to pull_request events (push has no base_ref). New permanent org mandate. Co-authored-by: Claude <noreply@anthropic.com>
1 parent fbf2200 commit c41da96

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

.github/workflows/coverage.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ jobs:
1717
- uses: actions/checkout@v4
1818
with:
1919
path: common
20+
# Full history so diff-cover can resolve origin/<base_ref> for the
21+
# patch-coverage gate below (shallow clones lack the base commit).
22+
fetch-depth: 0
2023
- uses: actions/checkout@v4
2124
with:
2225
repository: InstaNode-dev/proto
@@ -34,3 +37,39 @@ jobs:
3437
files: common/coverage.out
3538
flags: common
3639
fail_ci_if_error: false
40+
41+
# ------------------------------------------------------------------
42+
# Org patch-coverage mandate: every changed line in a PR diff must be
43+
# covered by a test (100%), and the project floor stays >=95%.
44+
# Tool: diff-cover (https://github.com/Bachmann1234/diff-cover) reads a
45+
# Cobertura report + the git diff vs the base branch.
46+
# ------------------------------------------------------------------
47+
- uses: actions/setup-python@v5
48+
if: github.event_name == 'pull_request'
49+
with:
50+
python-version: '3.12'
51+
- name: Install diff-cover + cobertura converter
52+
if: github.event_name == 'pull_request'
53+
run: |
54+
pip install diff-cover
55+
go install github.com/boumenot/gocover-cobertura@latest
56+
- name: Convert coverage to Cobertura
57+
if: github.event_name == 'pull_request'
58+
working-directory: common
59+
run: $(go env GOPATH)/bin/gocover-cobertura < coverage.out > coverage.xml
60+
- name: Patch coverage gate (100% of changed lines)
61+
if: github.event_name == 'pull_request'
62+
working-directory: common
63+
run: |
64+
git fetch origin "${{ github.base_ref }}" --depth=1 || true
65+
diff-cover coverage.xml \
66+
--compare-branch="origin/${{ github.base_ref }}" \
67+
--fail-under=100
68+
- name: Project coverage floor (>=95% total)
69+
if: github.event_name == 'pull_request'
70+
working-directory: common
71+
run: |
72+
total=$(go tool cover -func=coverage.out | tail -1 | awk '{print $3}' | tr -d '%')
73+
echo "Total project coverage: ${total}%"
74+
awk -v t="$total" 'BEGIN { exit (t+0 >= 95) ? 0 : 1 }' \
75+
|| { echo "::error::Project coverage ${total}% is below the 95% floor"; exit 1; }

0 commit comments

Comments
 (0)