fix(ci): make the cargo-audit gate fail on a report it cannot parse - #741
Conversation
#730 made the gate fail when jq is missing or cargo audit returns no report. One "could not look" path was left: the findings table still ended in `|| echo "(parse failed)"` and carried on to a pass. Parse the findings first and exit 2 if that fails, then print them, so `head` closing the pipe on a long list is not mistaken for a parse failure. The gate also now prints when the advisory database was last updated, and warns when it is over 7 days old. cargo audit fetches before each run, but --no-fetch or `fetch = false` answers from the copy on disk, and an old copy reports clean (the second thing that hid RUSTSEC-2026-0285). scripts/test-cargo-audit-check.sh plays canned reports through a fake cargo: clean, a vulnerability, warnings only, more findings than the display shows, jq missing, no report, non-JSON output, findings that do not parse, and a stale database. Against the previous script the last three cases fail. Runs in the workflows lint job and `just lint-workflows`, beside the other script tests. The other jq users in scripts/ were checked: issues-review.sh already requires jq up front, and check-action-pins.sh and doc-keeper-sweep.sh use gh's built-in --jq, not the jq binary. Closes #729. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SCNjpC4VgppHSFs7P6rkZg
|
Lint (workflows) is red, but not because of this PR's change. The "Check action pins" step fails on: Upstream moved its Proposed fix: bump all 5 pins of Generated by Claude Code |
Every job that needs Rust ran two steps: a bash one-liner pulling the
channel out of rust-toolchain.toml, then dtolnay/rust-toolchain to
install it. rustup ships on every GitHub-hosted runner and reads
rust-toolchain.toml itself, so one step does both:
rustup toolchain install --profile minimal --no-self-update
installs the pinned channel plus the file's components (rustfmt,
clippy), and every later cargo call in the checkout, src-tauri/
included, resolves to it. The release build adds
`rustup target add "$RUST_TARGET"` for its matrix target.
This drops a third-party action from the build path, which is also
what was turning Lint (workflows) red: upstream moved its v1 tag, so
the pin's version comment stopped matching (#741). With no pin there is
nothing to drift or to re-review on each upstream push. Quantco/pixi-pack
made the same change (Quantco/pixi-pack#340).
Given up: the action's new retry on release-server checksum failures.
That only bites while a Rust release is mid-publish.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SCNjpC4VgppHSFs7P6rkZg
(cherry picked from commit 4a6fb4f)
Every job that needs Rust ran two steps: a bash one-liner pulling the
channel out of rust-toolchain.toml, then dtolnay/rust-toolchain to
install it. rustup ships on every GitHub-hosted runner and reads
rust-toolchain.toml itself, so one step does both:
rustup toolchain install --profile minimal --no-self-update
installs the pinned channel plus the file's components (rustfmt,
clippy), and every later cargo call in the checkout, src-tauri/
included, resolves to it. The release build adds
`rustup target add "$RUST_TARGET"` for its matrix target.
This drops a third-party action from the build path, which is also
what was turning Lint (workflows) red: upstream moved its v1 tag, so
the pin's version comment stopped matching (#741). With no pin there is
nothing to drift or to re-review on each upstream push. Quantco/pixi-pack
made the same change (Quantco/pixi-pack#340).
Given up: the action's new retry on release-server checksum failures.
That only bites while a Rust release is mid-publish.
Claude-Session: https://claude.ai/code/session_01SCNjpC4VgppHSFs7P6rkZg
Co-authored-by: Claude <noreply@anthropic.com>
Closes #729.
#730 already made
scripts/cargo-audit-check.shexit 2 whenjqorcargo-auditis missing, or whencargo auditreturns no report. This PR closes the gaps that were left.Changes
|| echo "(parse failed)"and went on to pass. The findings are now parsed first, and the script exits 2 if that fails. Printing happens separately, sohead -50closing the pipe on a long list isn't mistaken for a parse failure (underpipefailit would have been).last-updatedfrom the JSON report and raises a::warning::when it's more than 7 days old.cargo auditfetches before every run, but--no-fetchorfetch = falseanswers from the copy on disk, and an old copy reports clean. That's the second thing the issue says hid RUSTSEC-2026-0285. This is a warning rather than a failure because the gate's verdict is still right for the data it read. BSDdatehas no-d, so macOS shows the timestamp without the age.scripts/test-cargo-audit-check.sh. It plays canned reports through a fakecargoon PATH and covers 10 cases: clean, a real vulnerability, warnings only, more findings than the display shows, jq missing, no report, non-JSON output, findings that don't parse, a stale DB, and the age being shown. It runs in theLint (workflows)job (which already triggers onscripts/**) and injust lint-workflows, next to the other script tests.issues-review.shalready requiresjqup front.check-action-pins.shanddoc-keeper-sweep.shusegh's built-in--jq, not thejqbinary, so none of them has this problem.Verification
scripts/test-cargo-audit-check.sh: 10/10 pass. Against the previous script, 3 fail: unparseable findings, the stale DB and the age display.src-tauriwithcargo-audit0.22.2 exits 0: "0 real vulnerabilities, 9 non-blocking advisory warning(s)", DB updated yesterday.dprint checkandcheck-documented-commands.sh: clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01SCNjpC4VgppHSFs7P6rkZg
Generated by Claude Code