@@ -3,6 +3,8 @@ name: Coverage Badge
33on :
44 push :
55 branches : [ main ]
6+ pull_request :
7+ branches : [ main ]
68 workflow_dispatch : {}
79
810permissions :
@@ -25,14 +27,12 @@ jobs:
2527 run : npm ci
2628
2729 - name : Run tests with coverage
28- run : |
29- npm test -- --coverage --reporter=default
30+ run : npm run test:coverage
3031
3132 - name : Parse coverage percentage
3233 id : coverage
3334 run : |
34- # Look for line coverage in lcov report or summary
35- PCT=$(grep -E "^Statements" coverage/coverage-summary.json || true)
35+ # Pull statement coverage percentage from Vitest json-summary
3636 if [ -f coverage/coverage-summary.json ]; then
3737 PCT=$(node -e "console.log(require('./coverage/coverage-summary.json').total.statements.pct)")
3838 else
@@ -41,20 +41,31 @@ jobs:
4141 echo "coverage=$PCT" >> $GITHUB_OUTPUT
4242
4343 - name : Generate badge
44+ if : ${{ always() }}
4445 run : |
4546 PCT=${{ steps.coverage.outputs.coverage }}
4647 COLOR=yellow
4748 if [ "${PCT%.*}" -ge 80 ]; then COLOR=green; elif [ "${PCT%.*}" -ge 65 ]; then COLOR=yellowgreen; elif [ "${PCT%.*}" -lt 50 ]; then COLOR=red; fi
4849 echo "Generating badge for $PCT% -> $COLOR"
4950 mkdir -p .github/badges
50- cat <<' SVG' > .github/badges/coverage.svg
51- <svg xmlns='http://www.w3.org/2000/svg' width='120' height='20' role='img' aria-label='coverage: $PCT%'><linearGradient id='s' x2='0' y2='100%'><stop offset='0' stop-color='#bbb' stop-opacity='.1'/><stop offset='1' stop-opacity='.1'/></linearGradient><mask id='m'><rect width='120' height='20' rx='3' fill='#fff'/></mask><g mask='url(#m)'><rect width='62' height='20' fill='#555'/><rect x='62' width='58' height='20' fill='$COLOR'/><rect width='120' height='20' fill='url(#s)'/></g><g fill='#fff' text-anchor='middle' font-family='Verdana,Geneva,DejaVu Sans,sans-serif' text-rendering='geometricPrecision' font-size='11'><text x='31' y='14'>coverage</text><text x='90' y='14'>$PCT%</text></g></svg>
51+ cat <<SVG > .github/badges/coverage.svg
52+ <svg xmlns='http://www.w3.org/2000/svg' width='120' height='20' role='img' aria-label='coverage: ${ PCT} %'><linearGradient id='s' x2='0' y2='100%'><stop offset='0' stop-color='#bbb' stop-opacity='.1'/><stop offset='1' stop-opacity='.1'/></linearGradient><mask id='m'><rect width='120' height='20' rx='3' fill='#fff'/></mask><g mask='url(#m)'><rect width='62' height='20' fill='#555'/><rect x='62' width='58' height='20' fill='${ COLOR} '/><rect width='120' height='20' fill='url(#s)'/></g><g fill='#fff' text-anchor='middle' font-family='Verdana,Geneva,DejaVu Sans,sans-serif' text-rendering='geometricPrecision' font-size='11'><text x='31' y='14'>coverage</text><text x='90' y='14'>${ PCT} %</text></g></svg>
5253 SVG
5354
5455 - name : Commit badge
56+ if : ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
5557 run : |
5658 git config user.name 'github-actions'
5759 git config user.email 'actions@github.com'
5860 git add .github/badges/coverage.svg
5961 git commit -m "chore: update coverage badge" || echo "No changes"
60- git push
62+ git push || echo "Note: push to main was blocked (likely branch protection). Badge will update after a maintainer merges a PR."
63+
64+ - name : Upload coverage artifact (PRs only)
65+ if : ${{ github.event_name == 'pull_request' }}
66+ uses : actions/upload-artifact@v4
67+ with :
68+ name : coverage-report
69+ path : |
70+ coverage/**
71+ .github/badges/coverage.svg
0 commit comments