CI/CD
Gate pull requests on what the change introduces, not on the backlog it inherited.
#The workflow Rust Doctor writes for you
The interactive report offers to add .github/workflows/rust-doctor.yml to the
workspace it just scanned. It is the only file the tool writes, it never
overwrites an existing one, and what it writes is the workflow below.
#GitHub Actions
name: Rust Doctor
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
inspect:
name: Inspect
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
# Baseline scope compares against the base ref, so the shallow default
# clone is not enough.
- uses: actions/checkout@v5
with:
fetch-depth: 0
# rust-doctor runs `cargo clippy` inside the scanned workspace.
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
# BASE_REF reaches the shell through the environment rather than through
# `${{ }}` interpolation: a branch name is attacker-controlled text on a
# fork pull request, and interpolating it into a run block is a command
# injection.
- name: Inspect the workspace
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
if [ -n "$BASE_REF" ]; then
npx -y rust-doctor@latest . --yes --verbose \
--scope baseline --base "origin/$BASE_REF" --blocking error
else
npx -y rust-doctor@latest . --yes --verbose --blocking error
fi#Why baseline scope on a pull request
A first scan of an existing codebase reports the backlog of every decision taken before today. Failing a contributor's pull request on it teaches everyone to ignore the job.
--scope baseline --base origin/<base> judges only the findings the change
introduces. The backlog stays visible on main, where it belongs, and the
gate stays credible.
Fingerprints are computed from normalized content, never from source positions, so inserting lines above an existing finding does not make it look new.
#What breaks the build
--blocking decides: none, error, or warning. The step exits with the
tool's own exit code, non-zero only when a diagnostic reaches that level.
Start at error and tighten once the score is where you want it.
#Any other CI
There is no special mode. Run the same command and read the exit code:
npx -y rust-doctor@latest . --yes --blocking errorFor a machine-readable trail, add --json and keep the report as an artifact.
Its paths are workspace-relative, so it carries nothing about the runner.