Repository navigation
Coverage #48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Coverage | |
| # Dogfoods bashunit's own --coverage engine. Nightly (and on manual dispatch) it | |
| # measures how much of src/ the unit suite exercises, uploads the LCOV report as | |
| # a build artifact, and publishes a shields.io endpoint badge to the orphan | |
| # `badges` branch (which the README badge reads). | |
| # | |
| # This is an OPTIONAL, non-blocking job: it never runs on push or pull_request, | |
| # so it is not a status check on any commit and cannot gate merges. Coverage is | |
| # CPU-heavy, so a scheduled cadence keeps it off the critical path. | |
| # | |
| # The coverage engine's own meta-tests (tests/unit/coverage_*_test.sh) are | |
| # excluded from the measured run: executing them under --coverage double- | |
| # instruments src/coverage.sh and corrupts their assertions. | |
| on: | |
| schedule: | |
| # Nightly at 04:17 UTC (odd minute to avoid the top-of-hour scheduler rush). | |
| - cron: "17 4 * * *" | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: coverage-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| coverage: | |
| name: "Measure and publish coverage" | |
| runs-on: ubuntu-latest | |
| # Coverage instruments every executed line across the whole unit suite, so | |
| # the run is inherently heavy. This is a nightly, non-blocking job, so a | |
| # generous timeout is free insurance against slow runners. | |
| timeout-minutes: 40 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup Config | |
| run: cp .env.example .env | |
| - name: Install jq | |
| run: sudo apt-get update && sudo apt-get install -y jq | |
| - name: Run coverage on the unit suite | |
| # Coverage instrumentation is CPU-heavy; --parallel --jobs auto keeps the | |
| # run well under the job timeout on the multi-core runner. Parallel LCOV | |
| # aggregation is deterministic (same total as a sequential run). | |
| run: | | |
| files=$(ls tests/unit/*_test.sh | grep -v '/coverage_') | |
| # shellcheck disable=SC2086 | |
| ./bashunit --coverage --parallel --jobs auto \ | |
| --coverage-report coverage/lcov.info --coverage-paths src $files | |
| - name: Upload LCOV report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-lcov | |
| path: coverage/lcov.info | |
| if-no-files-found: error | |
| - name: Publish coverage badge | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| pct=$(bash tools/coverage_percent.sh coverage/lcov.info) | |
| color=red | |
| if [ "$pct" -ge 90 ]; then color=brightgreen | |
| elif [ "$pct" -ge 75 ]; then color=green | |
| elif [ "$pct" -ge 60 ]; then color=yellowgreen | |
| elif [ "$pct" -ge 40 ]; then color=yellow | |
| elif [ "$pct" -ge 20 ]; then color=orange | |
| fi | |
| echo "Coverage: ${pct}% (${color})" | |
| mkdir -p badge | |
| printf '{"schemaVersion":1,"label":"coverage","message":"%s%%","color":"%s"}\n' \ | |
| "$pct" "$color" > badge/coverage.json | |
| cat badge/coverage.json | |
| cd badge | |
| git init -q | |
| git checkout -q -b badges | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add coverage.json | |
| git commit -q -m "chore(coverage): update badge to ${pct}%" | |
| git push -f "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" badges |