From 7f90b275e5b2df40412bf9b4151b15279ce951ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Fri, 15 May 2026 22:57:41 +0200 Subject: [PATCH] =?UTF-8?q?ci:=20#795=20=E2=80=94=20add=20weekly=20cargo?= =?UTF-8?q?=20llvm-cov=20coverage=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `.github/workflows/coverage.yml`. Runs Mondays at 04:00 UTC and on `workflow_dispatch`. Non-blocking: the goal is visibility into which functions in `perry-codegen` / `perry-transform` / `perry-runtime` have 0% test coverage so we can target the gaps. Steps: - Install `cargo-llvm-cov` via `taiki-e/install-action`. - Run `cargo llvm-cov` with the same `--exclude` list as the existing `cargo-test` job (perry-ui-{macos,ios,visionos,tvos,watchos,gtk4,android,windows} + perry-jsruntime) so it builds on the Linux runner. - Emit three views: an HTML report (uploaded as `coverage-html` artifact, 90-day retention), an `lcov.info` file (for IDE / external tooling, same retention), and a `summary-only` text dump that's written into `$GITHUB_STEP_SUMMARY` so the headline numbers show up on the job page without downloading the artifact. - `continue-on-error: true` on the coverage step + `if: always()` on the upload steps so a per-crate test failure doesn't suppress the rest of the report. Uses a distinct `Swatinem/rust-cache` key (`-coverage`) since the instrumented build can't share objects with the regular test cache. --- .github/workflows/coverage.yml | 124 +++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000..c041426a --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,124 @@ +name: Coverage + +# Weekly cargo-llvm-cov sweep. Non-blocking by design — the goal is +# visibility into which functions in perry-codegen / perry-transform / +# perry-runtime have 0% test coverage so we can fill the gaps, not a +# regression gate. (#795 / part of #793.) + +on: + schedule: + # Mondays at 04:00 UTC — runs after the Sunday-night benchmark + # window so we don't fight a 1-vCPU runner with two long jobs. + - cron: "0 4 * * 1" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: coverage-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + +jobs: + llvm-cov: + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - uses: actions/checkout@v6 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: llvm-tools-preview + + - uses: Swatinem/rust-cache@v2 + with: + # Separate key from the main test cache — llvm-cov rebuilds + # the workspace with instrumentation, so its objects can't + # be reused for the regular test job. + shared-key: ${{ runner.os }}-perry-coverage + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@v3 + with: + tool: cargo-llvm-cov + + - name: Run coverage + # Mirrors the `cargo-test` job's exclude list (host-only UI + # backends + perry-jsruntime). `--no-fail-fast` keeps the + # report comprehensive even if one crate's tests fail — + # this is a visibility job, not a gate. + run: | + cargo llvm-cov --workspace --no-fail-fast \ + --exclude perry-ui-macos \ + --exclude perry-ui-ios \ + --exclude perry-ui-visionos \ + --exclude perry-ui-tvos \ + --exclude perry-ui-watchos \ + --exclude perry-ui-gtk4 \ + --exclude perry-ui-android \ + --exclude perry-ui-windows \ + --exclude perry-jsruntime \ + --html --output-dir target/llvm-cov-html + cargo llvm-cov report --no-fail-fast \ + --exclude perry-ui-macos \ + --exclude perry-ui-ios \ + --exclude perry-ui-visionos \ + --exclude perry-ui-tvos \ + --exclude perry-ui-watchos \ + --exclude perry-ui-gtk4 \ + --exclude perry-ui-android \ + --exclude perry-ui-windows \ + --exclude perry-jsruntime \ + --lcov --output-path target/lcov.info + cargo llvm-cov report --no-fail-fast \ + --exclude perry-ui-macos \ + --exclude perry-ui-ios \ + --exclude perry-ui-visionos \ + --exclude perry-ui-tvos \ + --exclude perry-ui-watchos \ + --exclude perry-ui-gtk4 \ + --exclude perry-ui-android \ + --exclude perry-ui-windows \ + --exclude perry-jsruntime \ + --summary-only > target/summary.txt + # Don't fail the workflow on a non-zero exit — the artifacts + # below are still useful, and a missing test in one crate + # shouldn't suppress the rest of the report. + continue-on-error: true + + - name: Print summary to job log + if: always() + run: | + echo "## Coverage summary" >> "$GITHUB_STEP_SUMMARY" + if [[ -f target/summary.txt ]]; then + { + echo '```' + cat target/summary.txt + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + else + echo "_(summary.txt not produced — see logs.)_" >> "$GITHUB_STEP_SUMMARY" + fi + + - name: Upload HTML report + if: always() + uses: actions/upload-artifact@v7 + with: + name: coverage-html + path: target/llvm-cov-html + if-no-files-found: warn + retention-days: 90 + + - name: Upload lcov.info + if: always() + uses: actions/upload-artifact@v7 + with: + name: coverage-lcov + path: target/lcov.info + if-no-files-found: warn + retention-days: 90