Skip to content

Commit dfb63cf

Browse files
author
Nathan Gillett
committed
Harden tiered coverage gate and release workflow
Signed-off-by: Nathan Gillett <nathan@intentproof.io>
1 parent 12a3f7c commit dfb63cf

3 files changed

Lines changed: 46 additions & 8 deletions

File tree

.github/workflows/release-pypi.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ jobs:
4242
- name: Install dependencies
4343
run: pip install -e ".[dev]"
4444

45-
- name: Run tests with coverage
46-
run: pytest -q
47-
4845
- name: Enforce coverage threshold
4946
run: bash ./scripts/run-coverage-gate.sh
5047

scripts/check-coverage.sh

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ if [[ -z "${TOTAL_MIN:-}" ]]; then
2323
exit 2
2424
fi
2525

26-
if [[ ! -f "$COVERAGE_JSON" ]]; then
27-
echo "coverage json not found: $COVERAGE_JSON (run pytest with --cov first)" >&2
26+
if [[ ! -f "${ROOT}/${COVERAGE_JSON}" ]]; then
27+
echo "coverage json not found: ${ROOT}/${COVERAGE_JSON} (run pytest with --cov first)" >&2
2828
exit 2
2929
fi
3030

@@ -64,9 +64,12 @@ for file_path, entry in data.get("files", {}).items():
6464
stmts = int(summary.get("num_statements", 0))
6565
if stmts == 0:
6666
continue
67-
pct = float(summary.get("percent_covered", 0))
6867
total += stmts
69-
covered += int(round(stmts * pct / 100.0))
68+
file_covered = summary.get("covered_lines")
69+
if file_covered is None:
70+
missing = entry.get("missing_lines") or summary.get("missing_lines") or []
71+
file_covered = stmts - len(missing)
72+
covered += int(file_covered)
7073
print(covered, total)
7174
PY
7275
}
@@ -92,7 +95,8 @@ while IFS= read -r rule; do
9295
$(stats_for_prefix "$prefix")
9396
EOF
9497
if [[ "$t" -eq 0 ]]; then
95-
echo " ${prefix} (min ${min}%): no statements in profile, skipped"
98+
echo " ${prefix} (min ${min}%): no statements in profile, FAIL" >&2
99+
fail=1
96100
continue
97101
fi
98102
report_threshold " ${prefix}" "$c" "$t" "$min" || fail=1
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
# Regression test: critical tiers must fail when a prefix matches nothing.
3+
set -euo pipefail
4+
5+
root="$(mktemp -d)"
6+
trap 'rm -rf "$root"' EXIT
7+
8+
mkdir -p "$root/scripts"
9+
cp "$(dirname "$0")/check-coverage.sh" "$root/scripts/"
10+
11+
cat >"$root/scripts/coverage-tiers.conf" <<'EOF'
12+
TOTAL_MIN=50
13+
CRITICAL_RULES=(
14+
"95:src/intentproof/missing/"
15+
)
16+
EOF
17+
18+
cat >"$root/coverage.json" <<'EOF'
19+
{
20+
"files": {
21+
"src/intentproof/canon.py": {
22+
"summary": {
23+
"covered_lines": 2,
24+
"num_statements": 2,
25+
"percent_covered": 66.66666666666666
26+
}
27+
}
28+
}
29+
}
30+
EOF
31+
32+
if bash "$root/scripts/check-coverage.sh" "$root/coverage.json" >/dev/null 2>&1; then
33+
echo "FAIL: expected gate to fail for missing critical prefix" >&2
34+
exit 1
35+
fi
36+
37+
echo "PASS: missing critical prefix fails the gate"

0 commit comments

Comments
 (0)