Skip to content

Commit bb2c5ce

Browse files
synleclaude
andcommitted
ci(coverage): add frontend + Rust coverage job with v7.0.2 baseline floors
Mirrors the file-explorer pattern: a dedicated `coverage` job runs on ubuntu-22.04, fails the build when test coverage drops below a pinned floor, posts both reports to the run-page step summary, and uploads the HTML/lcov reports as a 14-day artifact. Frontend (Vitest, v8 provider) — thresholds in vite.config.ts: lines ≥ 36, statements ≥ 35, branches ≥ 24, functions ≥ 32 (baseline: lines 37.8 / stmts 36.93 / branches 25.32 / funcs 33.33) Rust (cargo-llvm-cov, --lib) — thresholds as CLI flags in build.yml: lines ≥ 43, functions ≥ 49, regions ≥ 45 (baseline: lines 44.11 / funcs 50.13 / regions 46.13) Floors trail baseline by ~1pt to absorb coincidental flakes. Raise as coverage improves; never lower. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
1 parent 5a7e4b0 commit bb2c5ce

4 files changed

Lines changed: 312 additions & 6 deletions

File tree

.github/workflows/build.yml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,122 @@ jobs:
106106
compression-level: 9
107107
if-no-files-found: ignore
108108

109+
coverage:
110+
# Coverage runs on a single OS (Linux is cheapest) — the numbers
111+
# don't vary meaningfully across platforms because the test suite
112+
# is platform-agnostic. Thresholds are pinned to the v7.0.2 baseline
113+
# minus a ~1pt safety margin against coincidental flakes. Real
114+
# regressions below the floor fail the build; raise these as
115+
# coverage improves.
116+
runs-on: ubuntu-22.04
117+
steps:
118+
- uses: actions/checkout@v4
119+
120+
- name: Setup Node
121+
uses: actions/setup-node@v4
122+
with:
123+
node-version: 20
124+
125+
- name: Setup Rust
126+
uses: dtolnay/rust-toolchain@stable
127+
with:
128+
components: llvm-tools-preview
129+
130+
- name: Install Linux dependencies
131+
run: |
132+
sudo apt-get update
133+
sudo apt-get install -y \
134+
libwebkit2gtk-4.1-dev \
135+
libappindicator3-dev \
136+
librsvg2-dev \
137+
patchelf \
138+
libxdo-dev \
139+
libssl-dev
140+
141+
- name: Install npm dependencies
142+
run: npm install
143+
144+
- name: Install cargo-llvm-cov
145+
uses: taiki-e/install-action@cargo-llvm-cov
146+
147+
# Vitest coverage thresholds live in vite.config.ts under
148+
# `test.coverage.thresholds`. The `--coverage` flag fails the
149+
# run when any of statements / branches / functions / lines
150+
# falls below its configured floor. `tee` keeps the full
151+
# output for the step-summary block below.
152+
- name: Frontend coverage (Vitest)
153+
id: frontend_cov
154+
run: |
155+
set -o pipefail
156+
npm run test:coverage 2>&1 | tee /tmp/frontend-cov.txt
157+
158+
- name: Rust coverage (cargo-llvm-cov)
159+
id: rust_cov
160+
working-directory: src-tauri
161+
# Floors mirror the v7.0.2 baseline (Regions 46.13%,
162+
# Functions 50.13%, Lines 44.11%) minus a ~1pt safety margin.
163+
# Raise these as coverage improves.
164+
run: |
165+
set -o pipefail
166+
cargo llvm-cov --lib --summary-only \
167+
--fail-under-lines 43 \
168+
--fail-under-functions 49 \
169+
--fail-under-regions 45 \
170+
2>&1 | tee /tmp/rust-cov.txt
171+
172+
# Upload the full HTML / lcov reports as an artifact so reviewers
173+
# can drill into per-file line-level coverage when the run-page
174+
# summary's totals aren't enough. Vitest writes to `coverage/`;
175+
# cargo-llvm-cov to `src-tauri/target/llvm-cov-target/`.
176+
- name: Upload coverage reports
177+
if: always()
178+
uses: actions/upload-artifact@v4
179+
with:
180+
name: coverage-reports
181+
path: |
182+
coverage/
183+
src-tauri/target/llvm-cov-target/html/
184+
retention-days: 14
185+
if-no-files-found: ignore
186+
187+
# Surface both reports on the workflow's run page. `if: always()`
188+
# ensures the summary still posts when the threshold check fails
189+
# — that's exactly when a human wants to see the numbers.
190+
- name: Post coverage to step summary
191+
if: always()
192+
run: |
193+
{
194+
echo "## Test coverage — \`$GITHUB_SHA\`"
195+
echo
196+
echo "### Frontend (Vitest, v8 provider)"
197+
echo
198+
echo '```text'
199+
if [ -f /tmp/frontend-cov.txt ]; then
200+
awk '/^=+ Coverage summary =+$/,/^=+$/' /tmp/frontend-cov.txt \
201+
|| tail -n 8 /tmp/frontend-cov.txt
202+
else
203+
echo "(frontend coverage did not run)"
204+
fi
205+
echo '```'
206+
echo
207+
echo "Thresholds (from \`vite.config.ts → test.coverage.thresholds\`):"
208+
echo "lines ≥ 36, statements ≥ 35, branches ≥ 24, functions ≥ 32."
209+
echo
210+
echo "### Rust (cargo-llvm-cov)"
211+
echo
212+
echo '```text'
213+
if [ -f /tmp/rust-cov.txt ]; then
214+
awk '/^Filename/,/^TOTAL/' /tmp/rust-cov.txt \
215+
|| tail -n 30 /tmp/rust-cov.txt
216+
else
217+
echo "(rust coverage did not run)"
218+
fi
219+
echo '```'
220+
echo
221+
echo "Thresholds (from \`build.yml\` cargo-llvm-cov flags):"
222+
echo "lines ≥ 43, functions ≥ 49, regions ≥ 45."
223+
} >> "$GITHUB_STEP_SUMMARY"
224+
109225
# Post a comment on PRs with download links for each platform's build artifacts
110226
pr_comment:
111227
if: github.event_name == 'pull_request'

package-lock.json

Lines changed: 171 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"preview": "vite preview",
99
"test": "vitest run",
1010
"test:watch": "vitest",
11+
"test:coverage": "vitest run --coverage",
1112
"tauri": "tauri"
1213
},
1314
"dependencies": {
@@ -25,6 +26,7 @@
2526
"@types/react": "^19.2.14",
2627
"@types/react-dom": "^19.2.3",
2728
"@vitejs/plugin-react": "^4.3.4",
29+
"@vitest/coverage-v8": "^4.1.5",
2830
"jsdom": "^29.0.2",
2931
"prettier": "^3.8.2",
3032
"typescript": "^5.6.3",

0 commit comments

Comments
 (0)