Skip to content

ci: scoped Rust test fast path for wallet-only PRs#4003

Merged
QuantumExplorer merged 2 commits into
v4.1-devfrom
claude/confident-bhaskara-67cc3d
Jul 4, 2026
Merged

ci: scoped Rust test fast path for wallet-only PRs#4003
QuantumExplorer merged 2 commits into
v4.1-devfrom
claude/confident-bhaskara-67cc3d

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Jul 4, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

A PR touching only the platform-wallet crates (e.g. #3985) triggers the full Rust CI: clippy --workspace, coverage-instrumented tests over ~22 packages, and the whole-workspace lint battery — even though the wallet crates are a near-leaf of the workspace graph. Nothing outside rs-unified-sdk-ffi depends on them, so a wallet-only change provably cannot break any other crate, yet every wallet PR pays the full-workspace wall-clock.

Separately, the rs-packages filter files had no entry for packages/rs-platform-wallet-storage/** at all — a storage-only PR matched no filter, left rs-packages == '[]', and ran zero Rust tests.

What was done?

  • New tests-rs-wallet.yml (reusable, called from tests.yml): on the same self-hosted macOS runner it runs cargo fmt --check --all, cargo machete, the immutable-structure check, scoped clippy over platform-wallet + platform-wallet-storage + platform-wallet-ffi + rs-unified-sdk-ffi (the last preserves the downstream-compile check clippy --workspace provided), cargo nextest run over the three wallet crates with the same -E 'not test(~shield)' filter the full job uses for them, and wallet-scoped doctests when doc examples changed. Coverage upload is intentionally omitted (codecov never gates the merge).
  • Scope detection in tests.yml's changes job sets rs-scope=wallet only when all of the following hold, otherwise full:
    • the event is a same-repo pull request — fork PRs keep the full path (whose Ubuntu backup jobs cover them when UBUNTU_BACKUP_ENABLED is set), and push/schedule runs are never downgraded (they have no reliable base SHA; the nightly full run stays full);
    • every changed file is under a wallet crate directory (packages/swift-sdk/** is ignored — not part of the Rust workspace); anything else, including Cargo.lock, forces the full run;
    • the diff against the PR base succeeds — computed with --no-renames so a file moved out of another crate still counts as a change to that crate; any diff failure falls back to full.
  • Reverse-dependency closure guard: a cargo metadata step in the wallet workflow fails if any workspace crate other than rs-unified-sdk-ffi starts depending (transitively) on the wallet crates, so the scoped --package lists can't silently go stale. Verified locally: passes today, and correctly fails (listing the new dependents) when a dependency edge is injected.
  • rs-workspace-tests and rs-wallet-tests are mutually exclusive via rs-scope; swift-sdk-build now gates on whichever one actually ran (skipped ≠ failure).
  • Added the missing platform-wallet-storage entries to rs-packages-no-workflows.yml (and its sibling filter files), fixing the pre-existing zero-tests gap for storage-only PRs.

An adversarial multi-angle review of the first draft surfaced (and this version fixes): fork-PR/zero-CI green runs, nightly/push downgrade via last-commit-only scoping, the git rename-detection hole, missing doctest coverage, an unenforced closure invariant, and a too-tight timeout for cold builds (~77% of the workspace dependency graph, including the orchard/halo2 stack, still compiles in the scoped job).

Known trade-offs (documented in the workflow header): no Ubuntu backup jobs in the wallet workflow (if UBUNTU_BACKUP_ENABLED — currently false — is turned on, wallet PRs still depend on the mac runner being online), and scoped -p builds feature-unify shared deps differently than --workspace builds, so the shared target/ carries an extra artifact flavor.

How Has This Been Tested?

  • YAML validated for all five changed files.
  • The closure-guard step was extracted from the workflow YAML exactly as Actions would dedent it and executed against real cargo metadata: positive case passes; a doctored metadata (fake dash-sdk → platform-wallet edge) correctly fails with the expected message.
  • The scope step was executed with substituted event contexts: schedule → full, fork PR → full, same-repo PR with unfetchable base SHA → full (fail-closed), same-repo PR with a real non-wallet diff → full.
  • The classifier loop was exercised with representative file lists: wallet+Swift (the fix(platform-wallet): release UTXO reservation when broadcast fails #3985 shape) → wallet; storage-only → wallet; wallet+Cargo.lock → full; Swift-only → full.
  • This PR itself touches workflow files, so it takes the full-workspace path; the fast path first exercises on the next wallet-only PR.

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

  • New Features
    • Added faster Rust CI for changes limited to wallet-related crates, with a dedicated wallet-only test path.
    • Expanded CI coverage to include the new wallet storage package in change detection.
  • Bug Fixes
    • Tightened CI checks to verify wallet dependency relationships and prevent incorrect wallet-only test routing.
    • Improved failure handling so downstream builds only block when relevant Rust jobs actually run and fail.

Same-repo PRs that touch only the platform-wallet crates
(rs-platform-wallet, rs-platform-wallet-ffi, rs-platform-wallet-storage;
Swift sources ignored) now skip the full Rust workspace job and run a
scoped tests-rs-wallet.yml workflow instead: fmt, machete,
immutable-structure check, clippy over the wallet crates plus their sole
dependent rs-unified-sdk-ffi, nextest over the wallet crates, and
wallet-scoped doctests when doc examples changed.

Safety rails baked in after review:
- fast path restricted to same-repo pull requests (fork PRs and
  push/schedule runs always take the full path, keeping the Ubuntu
  backup machinery and nightly full runs intact)
- scope diff uses --no-renames so a file moved out of another crate
  still counts against that crate; any diff failure falls back to full
- a cargo-metadata closure guard fails the job if any new workspace
  crate starts depending on the wallet crates
- timeout matches the full job (cold builds still compile ~77% of the
  workspace dependency graph)

Also adds the missing platform-wallet-storage entries to the rs-packages
filter files (previously a storage-only PR matched no filter and ran
zero Rust tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added this to the v4.1.0 milestone Jul 4, 2026
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eeab8a2e-1cd0-4516-9c27-0f09fdf8eb52

📥 Commits

Reviewing files that changed from the base of the PR and between 9792593 and 5910d47.

📒 Files selected for processing (7)
  • .github/package-filters/rs-packages-direct.yml
  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
  • .github/scripts/check-wallet-closure.py
  • .github/workflows/tests-rs-wallet.yml
  • .github/workflows/tests-rs-workspace.yml
  • .github/workflows/tests.yml

📝 Walkthrough

Walkthrough

This PR introduces a wallet-only Rust CI fast path. It adds package filters for a new platform-wallet-storage crate, a Python script validating a wallet reverse-dependency closure invariant, a new tests-rs-wallet.yml workflow, and routing logic in tests.yml to select between full workspace and wallet-only Rust test scopes based on PR diff contents.

Changes

Wallet-scoped CI fast path

Layer / File(s) Summary
Package filter entries
.github/package-filters/rs-packages-direct.yml, .github/package-filters/rs-packages-no-workflows.yml, .github/package-filters/rs-packages.yml
Adds platform-wallet-storage filter groups pointing to packages/rs-platform-wallet-storage/**, linked to the existing platform-wallet anchor.
Closure checker script
.github/scripts/check-wallet-closure.py
New script computes transitive reverse dependents of wallet crates via cargo metadata and fails if they diverge from an expected set.
Closure check wired into workspace workflow
.github/workflows/tests-rs-workspace.yml
Adds a step invoking the closure checker in the existing macOS test job.
New wallet-only workflow
.github/workflows/tests-rs-wallet.yml
Adds a workflow_call workflow with a macOS job running closure checks, formatting/machete checks, append_only/immutable doc-tag enforcement, scoped clippy, scoped nextest run, and conditional scoped doctests.
Scope routing in top-level workflow
.github/workflows/tests.yml
Adds an rs-scope step deciding wallet vs full scope from PR diff, gates rs-workspace-tests and a new rs-wallet-tests job accordingly, and updates swift-sdk-build dependencies/failure gating and path filters.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PR as Pull Request
  participant TestsYml as tests.yml
  participant ScopeStep as rs-scope step
  participant WalletWF as tests-rs-wallet.yml
  participant WorkspaceWF as tests-rs-workspace.yml
  participant ClosureScript as check-wallet-closure.py

  PR->>TestsYml: trigger CI
  TestsYml->>ScopeStep: compute rs-scope
  ScopeStep->>ScopeStep: inspect diff (fork/non-PR -> full)
  alt scope == wallet
    ScopeStep-->>TestsYml: scope=wallet
    TestsYml->>WalletWF: run rs-wallet-tests
    WalletWF->>ClosureScript: verify closure invariant
    ClosureScript-->>WalletWF: OK / fail
    WalletWF-->>TestsYml: job result
  else scope == full
    ScopeStep-->>TestsYml: scope=full
    TestsYml->>WorkspaceWF: run rs-workspace-tests
    WorkspaceWF->>ClosureScript: verify closure invariant
    ClosureScript-->>WorkspaceWF: OK / fail
    WorkspaceWF-->>TestsYml: job result
  end
  TestsYml->>TestsYml: gate swift-sdk-build on Rust job results
Loading

Possibly related PRs

  • dashpay/platform#3663: Both PRs modify the same CI package-filter YAML files to add/expand platform-wallet* filter anchors used by Rust workflow selection.

Suggested labels: ready for final review

Suggested reviewers: lklimek

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/confident-bhaskara-67cc3d

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 Jul 4, 2026

Copy link
Copy Markdown
Collaborator

✅ Review complete (commit 5910d47)

@codecov

codecov Bot commented Jul 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.19%. Comparing base (6bedef2) to head (5910d47).
⚠️ Report is 4 commits behind head on v4.1-dev.

Additional details and impacted files
@@             Coverage Diff              @@
##           v4.1-dev    #4003      +/-   ##
============================================
+ Coverage     87.18%   87.19%   +0.01%     
============================================
  Files          2632     2636       +4     
  Lines        327563   327822     +259     
============================================
+ Hits         285593   285852     +259     
  Misses        41970    41970              
Components Coverage Δ
dpp 87.70% <ø> (ø)
drive 86.14% <ø> (ø)
drive-abci 89.45% <ø> (ø)
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.20% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 49.55% <ø> (ø)
🚀 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.

Code Review

The CI fast path is well-designed and mostly correct. Two in-scope suggestions worth noting: the reverse-dependency closure guard cannot catch the PR that introduces a violation (it only runs on the wallet fast path, but any new non-wallet dependent forces scope=full and skips the guard), and the swift-sdk-changed filter was not extended to include the newly promoted platform-wallet-storage crate.

🟡 2 suggestion(s)

Source: reviewers claude/opus and codex/gpt-5.5; verifier claude/opus.

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `.github/workflows/tests.yml`:
- [SUGGESTION] .github/workflows/tests.yml:316-324: Closure guard cannot catch the PR that adds a new wallet dependent
  The reverse-dependency closure guard lives in `tests-rs-wallet.yml`, which only runs when `rs-scope == 'wallet'`. The scope classifier in tests.yml (lines 155-168) marks any non-wallet path as `non_wallet=true` and forces `scope=full`. A PR that introduces a new dependency from a non-wallet crate on `platform-wallet`, `platform-wallet-ffi`, or `platform-wallet-storage` necessarily edits a non-wallet `Cargo.toml`, so `rs-wallet-tests` is skipped and the guard never runs on the offending PR. The invariant is only enforced later, on an unrelated wallet-only PR that happens to trigger the fast path — by which point the merge that violated the invariant is already in. Run the closure check from the full Rust path as well (or as a separate lightweight job gated on Rust package metadata changes) so the invariant fails at the point it is broken, not on the next wallet-only contributor.
- [SUGGESTION] .github/workflows/tests.yml:209-210: swift-sdk-changed filter missing platform-wallet-storage
  This PR promotes `platform-wallet-storage` to a first-class wallet crate in `.github/package-filters/*.yml`, in the scoped `--package` lists in `tests-rs-wallet.yml`, and in the closure guard's `wallet = {...}` set. The inline `swift-sdk-changed` filter here still lists only `packages/rs-platform-wallet/**` and `packages/rs-platform-wallet-ffi/**`. Today no crate on the Swift SDK compile path depends on `platform-wallet-storage`, so skipping `swift-sdk-build` for a storage-only PR is currently correct. But as soon as `platform-wallet` or `platform-wallet-ffi` starts depending on `platform-wallet-storage` (its implied purpose), a storage-only PR will be classified `scope=wallet`, run `rs-wallet-tests`, and silently skip `swift-sdk-build` even though the Swift SDK compile could break. Add `packages/rs-platform-wallet-storage/**` to this filter now to keep the invariant aligned with the storage-crate promotion; the closure guard checks workspace dependents but does not cross-check this filter.

Comment thread .github/workflows/tests.yml
Review follow-ups from thepastaclaw on #4003:

- The reverse-dependency closure guard only ran on the wallet fast
  path, but a PR introducing a new wallet dependent always edits a
  non-wallet Cargo.toml and takes the full path — so the guard could
  never fire on the offending PR. Extract it to
  .github/scripts/check-wallet-closure.py and run it from both
  tests-rs-workspace.yml (catches the violating PR) and
  tests-rs-wallet.yml (protects against a stale scoped list).
- Add packages/rs-platform-wallet-storage/** to the swift-sdk-changed
  filter, keeping it aligned with the storage crate's promotion in the
  rs-packages filter files.
- Add the closure script to the rs-workflows trigger list so edits to
  it are exercised by CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@QuantumExplorer QuantumExplorer left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reviewed

@QuantumExplorer QuantumExplorer merged commit d4cd204 into v4.1-dev Jul 4, 2026
16 of 17 checks passed
@QuantumExplorer QuantumExplorer deleted the claude/confident-bhaskara-67cc3d branch July 4, 2026 22:16

@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.

Code Review

The latest push resolves both prior suggestions. The wallet reverse-dependency closure check was extracted to .github/scripts/check-wallet-closure.py and is now invoked from tests-rs-workspace.yml (where new non-wallet dependents actually go, fixing the guard's blind spot) as well as tests-rs-wallet.yml (as a stale-scoped-list guard). The swift-sdk-changed filter in tests.yml now includes packages/rs-platform-wallet-storage/**, and the rs-workflows filter covers the new script. No carried-forward prior findings and no new latest-delta findings.

Source: reviewers: claude-general (opus), codex-general (gpt-5.5); verifier: claude (opus).

bezibalazs pushed a commit that referenced this pull request Jul 5, 2026
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
bezibalazs added a commit that referenced this pull request Jul 5, 2026
… clippy lints

The scoped Rust test fast path (#4003) enforces that the wallet crates'
reverse-dependency closure matches an allowlist; rs-unified-sdk-jni is a
new dependent. Add it to EXPECTED_DEPENDENTS and the scoped clippy
package list, and clean up the lints the -D warnings gate surfaces in
the crate (ptr::slice_from_raw_parts_mut casts, repeat_n, boxed_local on
the sign-completion helper, two doc-comment rewraps).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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