[PM-29567] Pin binary cargo tools via cargo-run-bin#1143
Conversation
🔍 SDK Breaking Change DetectionSDK Version:
Breaking change detection uses the build of the SDK from this branch, including any incompatibities pre-existing on or merged into this branch. Check the workflow logs to confirm. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1143 +/- ##
==========================================
+ Coverage 84.10% 84.12% +0.01%
==========================================
Files 446 446
Lines 58768 58817 +49
==========================================
+ Hits 49428 49478 +50
+ Misses 9340 9339 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Add a [workspace.metadata.bin] block to the root Cargo.toml listing every binary cargo tool used by CI and scripts/lint.sh. CI and developers bootstrap cargo-run-bin once and invoke any tool via `cargo bin <tool>`, so dev versions stay in sync with CI. scripts/lint.sh switches from PATH lookups (with manual install hints) to `cargo bin <tool>` invocations; the lint matrix drops its per-check install steps in favor of one shared cargo-run-bin install. The other workflows (check-powerset, build-rust-crates, build-android, version-bump, rust-test) get the same treatment. Renovate's regex managers now target the manifest plus the cargo-run-bin bootstrap pin, replacing the four per-tool workflow regex managers.
02cc617 to
af6ce05
Compare
The clippy lint step set RUSTFLAGS=-D warnings for the whole step, which leaked into the from-source builds of clippy-sarif/sarif-fmt triggered by `cargo bin` in the same step. A warning in their transitive dependency serde-sarif then became a hard error and failed the build. Pass -D warnings to clippy directly instead, so the deny level applies only to the linted crates and not to the tool builds.
cargo-dylint invokes dylint-link as rustc's linker, found by name on PATH. Running it via `cargo bin cargo-dylint` fails: cargo-run-bin prepends a shim directory to PATH, and the dylint-link shim re-runs `cargo bin dylint-link`, which resolves the project root from the current directory. During linking the cwd is inside support/lints or a dependency's source dir, none of which declare [workspace.metadata.bin], so the shim fails with "No binaries configured". Build the tools and invoke the cargo-dylint binary directly with the real dylint-link binary on PATH (via an absolute path, so it resolves regardless of which directory cargo-dylint links from). Build only the two tools dylint needs rather than `cargo bin --install`, which builds every pinned tool including some that don't compile on this toolchain (e.g. cross).
af14a21 to
c5cc1f9
Compare
cargo-run-bin builds its tools into .bin, which was not cached, so every lint check rebuilt its tools from source each run. Cache .bin with a dedicated actions/cache step rather than via rust-cache's cache-directories. rust-cache keys every matrix check under one shared job-based key (so only the first check to save wins, and the others rebuild their tools anyway) and folds in the Cargo.lock hash (which rotates every day or two). The tools depend only on their pinned versions and the toolchain, so key on Cargo.toml + rust-toolchain.toml per check instead, with restore-keys for graceful fallback.
c5cc1f9 to
9170a1c
Compare
|
| ### Installation | ||
|
|
||
| The tools each check needs (and pinned versions) are installed in the lint workflow above. The | ||
| underlying tools are: |
There was a problem hiding this comment.
Thank you, this step especially was weird to look up from the lint workflow and last time I setup my machine I was unaware of the pinned versions, as complaints about missing tools, came up while I was building the SDK locally.
…nary cargo tools via cargo-run-bin (bitwarden/sdk-internal#1143)



🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-29567
📔 Objective
Add a [workspace.metadata.bin] block to the root Cargo.toml listing every binary cargo tool used by CI and scripts/lint.sh. CI and developers bootstrap cargo-run-bin once and invoke any tool via
cargo bin <tool>, so dev versions stay in sync with CI.scripts/lint.sh switches from PATH lookups (with manual install hints) to
cargo bin <tool>invocations; the lint matrix drops its per-check install steps in favor of one shared cargo-run-bin install. The other workflows (check-powerset, build-rust-crates, build-android, version-bump, rust-test) get the same treatment.Renovate's regex managers now target the manifest plus the cargo-run-bin bootstrap pin, replacing the four per-tool workflow regex managers.
Follow-up fixes to get the lint matrix green
Moving the tools under cargo-run-bin surfaced two lint failures and one efficiency gap, fixed here:
clippy: the clippy step set
RUSTFLAGS: -D warningsfor the whole step, which leaked into the from-source builds ofclippy-sarif/sarif-fmtthatcargo bintriggers in that step — a warning in their transitive dependencyserde-sarifthen became a hard error.-D warningsis now passed on the clippy command line instead, so the deny level applies only to the linted crates.dylint:
cargo-dylintinvokesdylint-linkas rustc's linker, found by name on PATH. Run throughcargo bin, cargo-run-bin prepends a shim directory whosedylint-linkshim re-runscargo bin dylint-link, which fails from the directories rustc links in (support/lints and each dependency's source dir, none of which declare[workspace.metadata.bin]). The dylint check now invokes thecargo-dylintbinary directly with the realdylint-linkon an absolute PATH, bypassing the shims. It builds only the two tools dylint needs rather thancargo bin --install, which also tries to buildcross(which doesn't compile on the pinned toolchain).caching: cargo-run-bin builds its tools into
.bin, which wasn't cached, so every lint check rebuilt its tools from source each run. A dedicatedactions/cachestep now caches.binper check, keyed onCargo.toml+rust-toolchain.toml(the tools depend on their pinned versions and the toolchain, not onCargo.lock) with restore-keys for graceful fallback when a version is bumped.🚨 Breaking Changes
None.