Skip to content

Commit e563b32

Browse files
Brian M Huntclaude
authored andcommitted
ci(coverage): add coverage workflow (open-loop) on PR + main push
Runs vitest+v8 coverage on every PR and every push to main. Outputs: - Workflow run summary table (lines / statements / branches / functions with covered/total counts) for at-a-glance visibility. - coverage-data artifact (coverage-summary.json + lcov.info, ~220 KB, 30-day retention) — small enough that future closed-loop tooling can download a base commit's data to compute deltas. - coverage-html artifact (lcov-report HTML, ~5 MB, 7-day retention, main-only) for human download via the workflow run page. Open-loop only — no PR comment, no delta gate. Closed-loop dark-factory feedback (post deltas to the PR; gate regressions) is a follow-up; the first attempt at the gate logic shipped four blockers in adversarial review (gh run download flag, missing reporter file, PATCH body encoding, heredoc terminator indentation), so split out and ship the simple version first. Adversarial review: subagent on this branch verified the simple flow works in the Playwright container, container pin matches build-and-test.yml, permissions defaults are sufficient, and the artifact-namespace + concurrency-group combination doesn't collide. The closed-loop design + its known blockers are tracked as a follow-up issue. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 374e9dd commit e563b32

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

.github/workflows/coverage.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Run vitest+v8 coverage on PRs and main pushes.
2+
#
3+
# Uploads the coverage report as an artifact for human download and
4+
# writes a summary table to the workflow run page. Currently does NOT
5+
# gate on threshold and does NOT post deltas to PRs — coverage is
6+
# informational. Closed-loop dark-factory feedback (PR comment + delta
7+
# gate) is tracked as a follow-up issue.
8+
#
9+
# Runs against the chromium browser project only. Firefox/WebKit
10+
# coverage is not measurable (JSC and SpiderMonkey don't expose V8's
11+
# coverage protocol). See vitest.config.ts coverage block for details.
12+
name: Coverage
13+
14+
on:
15+
pull_request:
16+
push:
17+
branches: [main]
18+
19+
# One coverage run per ref; cancel in-progress runs when a new push
20+
# arrives so we always report on the current tip.
21+
concurrency:
22+
group: ${{ github.workflow }}-${{ github.ref }}
23+
cancel-in-progress: true
24+
25+
jobs:
26+
coverage:
27+
name: vitest+v8 coverage
28+
runs-on: ubuntu-latest
29+
container:
30+
image: mcr.microsoft.com/playwright:v1.59.1-noble
31+
32+
steps:
33+
- name: Checkout code
34+
uses: actions/checkout@v6
35+
36+
- name: Install Bun
37+
run: python3 tools/install-bun
38+
39+
- name: Install dependencies
40+
run: bun install --frozen-lockfile
41+
42+
- name: Run coverage
43+
run: bun run test:coverage
44+
env:
45+
HOME: /root
46+
47+
- name: Coverage summary
48+
if: always()
49+
run: |
50+
if [ -f coverage/coverage-summary.json ]; then
51+
echo "## Coverage summary" >> "$GITHUB_STEP_SUMMARY"
52+
echo "" >> "$GITHUB_STEP_SUMMARY"
53+
echo "| Metric | Pct | Covered/Total |" >> "$GITHUB_STEP_SUMMARY"
54+
echo "|---|---|---|" >> "$GITHUB_STEP_SUMMARY"
55+
jq -r '
56+
.total |
57+
"| Lines | \(.lines.pct)% | \(.lines.covered)/\(.lines.total) |\n" +
58+
"| Statements | \(.statements.pct)% | \(.statements.covered)/\(.statements.total) |\n" +
59+
"| Branches | \(.branches.pct)% | \(.branches.covered)/\(.branches.total) |\n" +
60+
"| Functions | \(.functions.pct)% | \(.functions.covered)/\(.functions.total) |"
61+
' coverage/coverage-summary.json >> "$GITHUB_STEP_SUMMARY"
62+
fi
63+
64+
# Machine-readable artifacts (~220 KB), retained 30 days. Designed
65+
# so a future closed-loop coverage workflow can download a base
66+
# commit's data to compute deltas.
67+
- name: Upload coverage data
68+
if: always()
69+
uses: actions/upload-artifact@v7
70+
with:
71+
name: coverage-data
72+
path: |
73+
coverage/coverage-summary.json
74+
coverage/lcov.info
75+
retention-days: 30
76+
77+
# Human-readable HTML report (~5 MB). Only on main pushes; short
78+
# retention since PR runs don't benefit from it.
79+
- name: Upload coverage HTML (main only)
80+
if: always() && github.event_name == 'push' && github.ref == 'refs/heads/main'
81+
uses: actions/upload-artifact@v7
82+
with:
83+
name: coverage-html
84+
path: coverage/lcov-report
85+
retention-days: 7

0 commit comments

Comments
 (0)