Skip to content

ci: drop stale coverage objects before the Rust workspace test step - #4751

Open
QuantumExplorer wants to merge 1 commit into
v4.3-devfrom
claude/frosty-khayyam-5b98bf
Open

QuantumExplorer wants to merge 1 commit into
v4.3-devfrom
claude/frosty-khayyam-5b98bf

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 14, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

codecov/project fails on PRs whose rust coverage drops several percent in crates the PR never touched (seen on #4748: base 83.52% vs head 75.95%, with dpp at -6.74%, drive -3.73%, drive-proof-verifier -5.58%, none of them changed). The head report had ~30k more instrumented lines with fewer hits than the base for the same test set, and the extra lines were comments, attributes, struct fields and blank lines marked as misses, with function signature lines marked as misses while their bodies were hits.

The cause is the retained coverage build, not the runner OS. cargo llvm-cov report collects its objects by walking target/llvm-cov-target/debug and passing every executable whose name matches a workspace package or target to llvm-cov (report.rs object_files). The test step runs cargo llvm-cov nextest --no-report, and --no-report implies --no-clean, so the cargo clean -p <members> cargo-llvm-cov would otherwise run first is skipped. Every version bump, Cargo.lock change or toolchain bump re-keys all test binaries under a new hash and leaves the old ones in deps/, where they are read forever. Those stale binaries carry coverage regions from the tree they were built from and have no counts in the current profile; llvm-cov keeps the first record it meets per function, so files that changed since pick up misses (and lose hits) unrelated to the code under test.

The per-flag totals of recent v4.2-dev pushes track each runner's leftovers, not its OS:

Commit Runner target/ at job start rust flag
1a16988 mac-runner-brian 118 GB 74.87%
a474ccd mac-runner-brian 23 GB (guard had wiped it) 83.74%
01d9447 mac-runner-pasta 120 GB 74.73%
5659f3d mac-runner-pasta 20 GB (guard had wiped it) 83.78%
66efe32 ubuntu-server-2 57 GB 83.46%
0b764f3 (#4748 head) ubuntu-runner-1 94 GB 75.95%

Both #4748 runs used rustc 1.98.1; the cargo-llvm-cov versions differed (0.9.0 vs 0.8.7) but the changelog between them has nothing relevant, and both versions walk the directory the same way. Per-OS codecov flags or pinning the job to one OS would not have fixed this.

What was done?

  • New step Drop stale coverage objects in tests-rs-workspace.yml, right before the test step and gated like the other "tests will run" steps. It rebuilds cargo-llvm-cov's own name filter from cargo metadata --no-deps and deletes the matching executables (test binaries, uplifted bins, examples, workspace cdylibs) in debug/, debug/deps and debug/examples. Rlibs, rmeta, dep-info and the ~700 dependency crates stay, so only the workspace's own test, bin and example targets recompile and the retained build keeps its value.
  • Remove stale coverage data now also deletes target/lcov-tree-hash. A PR run regenerates the lcov files but never rewrites the marker, so a later run of the marker's tree could have reused another tree's report through the tree-hash shortcut.
  • Comments at both retention notes updated to point at the new step. The runs-on comment is unchanged and still accurate. .codecov.yml is untouched; the patch status target is not weakened.

How Has This Been Tested?

  • actionlint and a YAML parse of the workflow pass.
  • The step's script was extracted and run against a scratch cargo target directory seeded with current and stale test binaries (two hashes each, produced by changing RUSTFLAGS between builds). It removed the four executables and kept the rlibs, rmeta, dep-info and object files; the following cargo test --no-run rebuilt only the two current binaries and the stale hashes did not come back. The missing-directory path exits 0 with a message.
  • Confirmed experimentally that cargo does not touch fingerprint invoked.timestamp files on fresh builds, so there is no timestamp-based way to keep only the current binaries; dropping all workspace executables is the simplest correct option. A zero-rebuild variant (cargo llvm-cov show-env plus cargo nextest list --message-format json to keep only current binaries) is possible if the recompile cost matters.
  • What only CI can confirm: on a runner with a large retained target/ (ubuntu-runner-1 is the best candidate) the new step should log several thousand dropped objects and the rust flag should land near 83.5%. Expect the test step's build phase to grow by roughly one workspace test-target compile; it was 1 min 08 s on both runners before this change.

Breaking Changes

None.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved CI coverage reporting by removing stale build artifacts and coverage markers before generating reports.
    • Prevented coverage reports from including objects produced by previous source trees.

cargo-llvm-cov builds the report from every executable it finds under
target/llvm-cov-target/debug whose name matches a workspace package or
target, not from the binaries the current run built. Because the test
step runs with --no-report (which implies --no-clean) nothing ever
removes the test binaries that a version bump, Cargo.lock change or
toolchain bump re-keyed under a new hash, so they keep being read as
coverage objects. Their regions describe the tree they were built from
and carry no counts, so files that changed since pick up misses on
comment, attribute and blank lines and lose hits on signature lines.

That made the `rust` codecov flag swing between ~74% and ~84% depending
on what a runner's retained target/ happened to hold (the same mac went
74.87% -> 83.74% within hours after the disk guard wiped it), and failed
codecov/project on PRs that never touched the affected crates. It is a
property of the retained build, not of the runner OS.

Remove the executables (test binaries, uplifted bins, examples and
workspace cdylibs) before the test step, using the same name filter
cargo-llvm-cov applies, so the report can only see this run's objects.
The workspace rlibs and the dependency cache stay, so only the
workspace's own test, bin and example targets recompile.

Also drop target/lcov-tree-hash together with the lcov files: a PR run
regenerates the reports without rewriting the marker, so a later run of
the marker's tree could have reused another tree's coverage.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 14, 2026
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: cd6e8529-ef9c-4f92-a633-05c5c9f8563e

📥 Commits

Reviewing files that changed from the base of the PR and between 28e7045 and 02984cb.

📒 Files selected for processing (1)
  • .github/workflows/tests-rs-workspace.yml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The CI workflow now removes stale coverage markers and workspace executables before collecting coverage. Comments describe when pruning occurs and how retained executables are handled between runs.

Changes

Coverage cleanup

Layer / File(s) Summary
Stale coverage pruning
.github/workflows/tests-rs-workspace.yml
The workflow deletes the target/lcov-tree-hash marker and removes stale workspace test, benchmark, example, binary, and cdylib executables before coverage collection. Cached dependency artifacts remain. Comments document the cleanup sequence.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: pastapastapasta

Merge Risk: ⚪ Minimal · up to 02984

The coverage cleanup is scoped to stale executable outputs and does not leave an established failure path for the subsequent CI test and reporting steps. It is ready to merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a CI step that removes stale coverage objects before the Rust workspace test step.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/frosty-khayyam-5b98bf

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thepastaclaw

thepastaclaw commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

✅ Final review complete — no blockers (commit 02984cb) · triage: low · Phase 2 only (queue backlog)

@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.41%. Comparing base (9361d4c) to head (02984cb).
⚠️ Report is 17 commits behind head on v4.3-dev.

Additional details and impacted files
@@             Coverage Diff              @@
##           v4.3-dev    #4751      +/-   ##
============================================
+ Coverage     83.05%   83.41%   +0.36%     
============================================
  Files          2843     2846       +3     
  Lines        390754   390452     -302     
============================================
+ Hits         324523   325685    +1162     
+ Misses        66231    64767    -1464     
Components Coverage Δ
dpp 83.81% <ø> (+0.13%) ⬆️
drive 84.48% <ø> (+0.38%) ⬆️
drive-abci 86.21% <ø> (+0.25%) ⬆️
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 70.49% <ø> (-0.04%) ⬇️
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 38.55% <ø> (+5.01%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final validation — Phase 2 only (queue backlog)

The workflow change correctly removes stale workspace coverage executables while preserving dependency artifacts, and it invalidates the retained lcov tree marker whenever fresh coverage is required. The cleanup is gated consistently with the test path and uses metadata-derived workspace/package target names, so I found no in-scope correctness or architecture issues.

Review provenance

Source: reviewer 1: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 2: gpt-6-astra (agent: phase2-reviewer, role: architecture-layering); final verifier: gpt-6-astra (agent: astra-verifier, role: final-verifier)

  • Triage: low by gpt-6-astra (effort low) — This is a contained CI workflow change that removes stale coverage executables and marker data, with no impact on production behavior or critical surfaces, and its shell logic is straightforward to validate.
  • Phase 1 reviewers: not run (skipped for throughput: 25 PRs queued, above the 10 limit)
  • Fresh verifier: gpt-6-astra — final-verifier; agent astra-verifier
  • Phase 2 reviewers: gpt-6-astra — general (completed, effort medium); agent phase2-reviewer, gpt-6-astra — architecture-layering (completed, effort medium); agent phase2-reviewer

@QuantumExplorer
QuantumExplorer changed the base branch from v4.2-dev to v4.3-dev September 16, 2026 03:52
@github-actions github-actions Bot modified the milestones: v4.2.0, v4.3.0 Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants