Skip to content

Commit a3eb485

Browse files
committed
ci: enforce coverage
1 parent dfdb9e5 commit a3eb485

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

.github/workflows/ci.yml

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ jobs:
145145
needs: setup
146146
permissions:
147147
contents: read
148+
outputs:
149+
coverage_result: ${{ steps.coverage-summary.outputs.coverage_result }}
148150

149151
steps:
150152
- name: Checkout repository
@@ -168,10 +170,46 @@ jobs:
168170
fi
169171
170172
- name: Run tests with coverage
171-
continue-on-error: true
173+
id: run-tests
172174
run: |
173175
echo "Running tests with coverage..."
174-
npm run test:coverage --if-present || npm test --if-present || echo "::warning::Tests failed but continuing workflow"
176+
npm run test:coverage --if-present || npm test --if-present || echo "::warning::No test:coverage or test script; skipping"
177+
178+
- name: Coverage (threshold + summary)
179+
id: coverage-summary
180+
if: always()
181+
run: |
182+
MIN=80
183+
# Vitest: detect by config (handles its own thresholds); brittle uses Istanbul + nyc check.
184+
if [ -f vitest.config.js ] || [ -f vitest.config.ts ]; then
185+
if [ -f coverage/coverage-final.json ]; then
186+
if [ "${{ steps.run-tests.outcome }}" = "success" ]; then
187+
STATUS_CELL="✅ PASS"
188+
else
189+
STATUS_CELL="❌ FAIL (coverage below threshold in vitest.config.js)"
190+
fi
191+
echo "coverage_result=$STATUS_CELL Vitest (thresholds in vitest.config.js)" >> "$GITHUB_OUTPUT"
192+
else
193+
echo "coverage_result=⚠️ No coverage report" >> "$GITHUB_OUTPUT"
194+
fi
195+
elif [ -f coverage/coverage-final.json ]; then
196+
mkdir -p .nyc_output
197+
cp coverage/coverage-final.json .nyc_output/out.json
198+
set +e
199+
echo "Running nyc check-coverage (threshold ${MIN}%)..."
200+
npx --yes nyc check-coverage --lines=$MIN --statements=$MIN --functions=$MIN --branches=$MIN
201+
EXIT=$?
202+
set -e
203+
echo "Running nyc report (text-summary)..."
204+
npx --yes nyc report --reporter=text-summary 2>&1 | tee report-summary.txt
205+
PCT=$(sed -n 's/^Lines[^:]*: *\([0-9.]*\)%.*/\1/p' report-summary.txt)
206+
[ -z "$PCT" ] && PCT="—"
207+
[ $EXIT -eq 0 ] && ICON="✅" || ICON="❌"
208+
echo "coverage_result=$ICON Coverage ${PCT}% (min ${MIN}%)" >> "$GITHUB_OUTPUT"
209+
exit $EXIT
210+
else
211+
echo "coverage_result=⚠️ No coverage report" >> "$GITHUB_OUTPUT"
212+
fi
175213
176214
- name: Run build (optional)
177215
continue-on-error: true
@@ -265,6 +303,7 @@ jobs:
265303
R_SUPPLY: ${{ needs.supply-chain.result || 'skipped' }}
266304
R_LINT: ${{ needs.lint.result || 'skipped' }}
267305
R_TEST: ${{ needs.test-and-sonarqube.result || 'skipped' }}
306+
COVERAGE: ${{ needs.test-and-sonarqube.outputs.coverage_result || '—' }}
268307
run: |
269308
{
270309
echo "## 📊 CI Pipeline Summary"
@@ -280,6 +319,7 @@ jobs:
280319
[ "${R_SUPPLY}" != "skipped" ] && echo "- 🔐 Supply Chain: ${R_SUPPLY:-?}"
281320
[ "${R_LINT}" != "skipped" ] && echo "- ✨ Lint: ${R_LINT:-?}"
282321
[ "${R_TEST}" != "skipped" ] && echo "- 🧪 Test & SonarQube: ${R_TEST:-?}"
322+
echo "- 📊 Coverage: ${COVERAGE}"
283323
echo ""
284324
echo "### 🔧 Pipeline"
285325
echo "- ✅ Dependency review (PR only)"

0 commit comments

Comments
 (0)