All checks were successful
PR Check — Rust / rust (pull_request) Successful in 9m23s
The removal trigger #312 was written for had already fired — I filed the issue without checking whether a newer plist existed. plist 1.10.0 ships quick-xml 0.41.0, which carries the fix, within tauri's existing bound: cargo update -p plist -> plist 1.8.0 -> 1.10.0 quick-xml 0.38.4 -> 0.41.0 So RUSTSEC-2026-0194 and -0195 are resolved rather than accepted, and leave .cargo/audit.toml the day they entered it. rsa is now the only entry, and the guard loops on that crate alone; its rationale comment is re-pointed accordingly, since it was written entirely around quick-xml/plist. Also bumps the two yanked crates (#313). tauri-plugin-deep-link 2.4.8 -> 2.4.9: upstream's 2.4.9 is a single commit, "Fix broken iOS custom URL schemes", so the defect behind the yank is iOS-only and never reached this desktop app — v0.14.0 shipping 2.4.8 was not a user-facing problem, which is why neither Security nor Fixed applies to it in the changelog. spin 0.9.8 -> 0.9.9; every 0.9.x up to 0.9.8 is yanked, which reads as a bulk yank rather than a defect. The #310 changelog bullet is amended rather than contradicted: it sits in the same unreleased section and would otherwise ship two opposing claims in the same release notes. Two of its statements were wrong. It said three advisories remained (now one), and it said tar sits on "real code paths in the shipped app" — tar is compiled, but its vulnerable extraction path is only reached by the AppImage and macOS installers this project does not bundle. The rustls-webpki half stands: TLS runs on every update check. ADR 0018's decision is untouched; an amendment header marks the passages that are now historical, including the "override is impossible" alternative, which plist 1.10.0 made false the same day. cargo audit from the repo root: 0 vulnerabilities, warnings 23 -> 21 (the two yanked ones). From src-tauri/ it reports 1 — that is the cwd sensitivity of .cargo/audit.toml, not a regression. Guard: 2 checks + canary, exit 0. cargo check + cargo test green (106 tests). Lock diff: 4 packages, 666 before and after. Resolves #312 Resolves #313 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
153 lines
6.9 KiB
YAML
153 lines
6.9 KiB
YAML
name: PR Check — Rust
|
|
|
|
# Rust half of the former check.yml (split in #232).
|
|
#
|
|
# Only runs when Rust actually changes. On this repo roughly 1 PR in 40 touches
|
|
# src-tauri/, and the runner has capacity 1 — jobs queue instead of running in
|
|
# parallel, so every minute spent here is a minute the next PR waits.
|
|
#
|
|
# No `branches:` filter on purpose. `branches: [main]` never matched a PR
|
|
# stacked on top of another feature branch, which is what /autopilot produces:
|
|
# 4 of the 5 PRs in the feature-gating milestone ran no CI at all.
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- 'src-tauri/**'
|
|
- '.forgejo/workflows/check-rust.yml'
|
|
# Whole directory, not just audit.toml: a later .cargo/config.toml
|
|
# (rustflags, linker, target dir) would change the Rust build, and an
|
|
# exact-path entry would let it skip Rust CI unnoticed.
|
|
- '.cargo/**'
|
|
|
|
# Cancel obsolete runs (e.g. on force-push) so only the latest commit runs.
|
|
# Distinct from the frontend group: a shared group would make the two
|
|
# workflows cancel each other on a PR that touches both.
|
|
concurrency:
|
|
group: ci-rust-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
rust:
|
|
runs-on: ubuntu
|
|
container: ubuntu:22.04
|
|
env:
|
|
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
CARGO_TERM_COLOR: always
|
|
# Nothing persists between runs (see the caching note below), so
|
|
# incremental artifacts get written and never reused — pure overhead.
|
|
# Test debug info is dead weight here for the same reason.
|
|
CARGO_INCREMENTAL: 0
|
|
CARGO_PROFILE_TEST_DEBUG: 0
|
|
steps:
|
|
- name: Install system dependencies, Node.js and Rust
|
|
run: |
|
|
apt-get update
|
|
apt-get install -y --no-install-recommends \
|
|
curl wget git ca-certificates build-essential pkg-config \
|
|
libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libssl-dev \
|
|
libdbus-1-dev
|
|
# Node.js is required by actions/checkout and taiki-e/install-action
|
|
# (they are JavaScript actions and need `node` in the container PATH).
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
|
apt-get install -y nodejs
|
|
# Rust toolchain
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
|
|
node --version
|
|
rustc --version
|
|
cargo --version
|
|
|
|
- name: Checkout
|
|
uses: https://github.com/actions/checkout@v4
|
|
|
|
# No actions/cache step here, deliberately. The job container cannot
|
|
# reach the runner's cache server (#234): the restore times out into a
|
|
# miss AND the save times out, so the cache cost ~7 min per run and
|
|
# returned nothing. Bring caching back through Swatinem/rust-cache once
|
|
# #234 is fixed — not before, it shares the same backend.
|
|
|
|
- name: cargo check
|
|
run: cargo check --manifest-path src-tauri/Cargo.toml --all-targets
|
|
|
|
# Anti-rot guard for the suppressions in .cargo/audit.toml (#310). Each
|
|
# entry there is justified by its crate being absent from every shipped
|
|
# target's graph — a property of today's resolved graph, not a permanent
|
|
# one. rsa is currently reachable from nothing: its only parent in the
|
|
# lockfile is sqlx-mysql, which this SQLite project never compiles. If a
|
|
# dependency change ever pulls it into a shipped target, the suppression
|
|
# would silently hide a live advisory and the daily audit would stay
|
|
# green: the inverse of the permanent red #310 exists to kill.
|
|
#
|
|
# Such a change would itself touch src-tauri, which is exactly what
|
|
# triggers this workflow. Runs after cargo check so the registry index is
|
|
# already warm, and --locked so cargo tree cannot rewrite the lockfile the
|
|
# audit was taken against.
|
|
#
|
|
# CRATES must mirror the crates named in .cargo/audit.toml. Adding an
|
|
# entry there without adding its crate here leaves it unguarded.
|
|
#
|
|
# Every check echoes its result, including the passing ones. A guard that
|
|
# is silent on success cannot be told apart in the log from a guard that
|
|
# never ran — which is the same silent-skip failure mode this step exists
|
|
# to catch, one level up.
|
|
- name: Verify suppressed advisories are still unreachable
|
|
run: |
|
|
set -u
|
|
CRATES="rsa"
|
|
TARGETS="x86_64-unknown-linux-gnu x86_64-pc-windows-msvc"
|
|
rc=0
|
|
checks=0
|
|
for crate in $CRATES; do
|
|
for target in $TARGETS; do
|
|
# An absent crate exits 0 with empty stdout ("nothing to print"
|
|
# goes to stderr). A non-zero exit means cargo tree itself failed
|
|
# — treat that as a failure rather than as proof of absence.
|
|
out=$(cargo tree --manifest-path src-tauri/Cargo.toml --locked \
|
|
-i "$crate" --target "$target" 2>/dev/null) || {
|
|
echo "cargo tree failed for $crate / $target — cannot verify the suppression"
|
|
rc=1
|
|
continue
|
|
}
|
|
if [ -n "$out" ]; then
|
|
echo "FAIL: $crate is now compiled for $target — its .cargo/audit.toml suppression is no longer justified (see #310)."
|
|
rc=1
|
|
else
|
|
echo "ok: $crate absent from $target"
|
|
fi
|
|
checks=$((checks + 1))
|
|
done
|
|
done
|
|
# Canary: a crate known to be present. If this stops being found, the
|
|
# loop above is broken and its silence means nothing.
|
|
canary=$(cargo tree --manifest-path src-tauri/Cargo.toml --locked \
|
|
-i tar --target x86_64-unknown-linux-gnu 2>/dev/null) || true
|
|
if [ -z "$canary" ]; then
|
|
echo "FAIL: canary 'tar' was not found although it is a known dependency. The guard is not proving anything."
|
|
rc=1
|
|
else
|
|
echo "ok: canary 'tar' found for x86_64-unknown-linux-gnu"
|
|
fi
|
|
echo "Suppression guard: $checks checks, exit $rc"
|
|
exit $rc
|
|
|
|
- name: cargo test
|
|
run: cargo test --manifest-path src-tauri/Cargo.toml --all-targets
|
|
|
|
# Prebuilt binary. `cargo install --locked cargo-audit` recompiled the
|
|
# tool from source on every single run (~4m40s). No continue-on-error:
|
|
# a tooling failure should fail the job rather than be swallowed.
|
|
- name: Install cargo-audit
|
|
uses: https://github.com/taiki-e/install-action@v2
|
|
with:
|
|
tool: cargo-audit
|
|
|
|
# Advisories are informational — they can land on unrelated crates and
|
|
# would otherwise stall unrelated work — so the step is non-blocking.
|
|
# It no longer hides real failures behind `|| true` though. Daily
|
|
# RustSec coverage outside Rust PRs lives in audit.yml.
|
|
- name: cargo audit
|
|
continue-on-error: true
|
|
run: cargo audit --file src-tauri/Cargo.lock
|