Summary
apps/me branch coverage differs between local and GitHub Actions for the same test target, causing threshold failures in CI.
Observed values:
- Local (
pnpm test -F f3-me): branch coverage reports 35.41%.
- CI (
test-coverage job on GitHub Actions): branch coverage reports 35.03%.
This discrepancy is enough to fail when the threshold is calibrated from local runs.
Impact
- CI can fail even when local runs pass.
autoUpdate-driven thresholds recorded locally can become incompatible with CI.
- Developers lose confidence in local reproducibility for coverage gates.
Evidence
From failing Actions logs:
ERROR: Coverage for branches (35.03%) does not meet global threshold (35.41%)
Local CI-mode repro:
- Running with
CI=true locally reproduces the lower CI number (35.03%) and failure against 35.41.
Reproduction
- Ensure Node version from
.nvmrc.
- Run locally:
pnpm test -F f3-me
- Note branch coverage (commonly
35.41% in non-CI env).
- Run with CI flag:
CI=true pnpm test -F f3-me
- Branch coverage drops to
35.03% (matches GitHub Actions).
- Compare against configured threshold in
apps/me/vitest.config.ts.
Likely Root Cause
Coverage denominator/branch map differs when CI=true.
apps/me/src/env.ts has CI-sensitive logic:
skipValidation: !!process.env.CI || ...
This introduces different branch execution/coverage behavior between local default runs and CI runs.
Suggested Resolution
- Calibrate
apps/me thresholds using CI-mode runs (CI=true) rather than default local runs.
- Prefer stable thresholds for this package (avoid auto drift), e.g. set
autoUpdate: false once CI-aligned values are chosen.
- Optionally document a repo convention: coverage threshold updates must be generated under CI-equivalent env.
Follow-ups (optional)
- Add a small script/target for standardized coverage recalibration under
CI=true.
- Add a short testing guide note explaining why CI-mode coverage can differ.
Summary
apps/mebranch coverage differs between local and GitHub Actions for the same test target, causing threshold failures in CI.Observed values:
pnpm test -F f3-me): branch coverage reports35.41%.test-coveragejob on GitHub Actions): branch coverage reports35.03%.This discrepancy is enough to fail when the threshold is calibrated from local runs.
Impact
autoUpdate-driven thresholds recorded locally can become incompatible with CI.Evidence
From failing Actions logs:
ERROR: Coverage for branches (35.03%) does not meet global threshold (35.41%)Local CI-mode repro:
CI=truelocally reproduces the lower CI number (35.03%) and failure against35.41.Reproduction
.nvmrc.pnpm test -F f3-me35.41%in non-CI env).CI=true pnpm test -F f3-me35.03%(matches GitHub Actions).apps/me/vitest.config.ts.Likely Root Cause
Coverage denominator/branch map differs when
CI=true.apps/me/src/env.tshas CI-sensitive logic:skipValidation: !!process.env.CI || ...This introduces different branch execution/coverage behavior between local default runs and CI runs.
Suggested Resolution
apps/methresholds using CI-mode runs (CI=true) rather than default local runs.autoUpdate: falseonce CI-aligned values are chosen.Follow-ups (optional)
CI=true.