Rust Build with Cargo: Build Files, Scanners and CI
Cargo is Rust’s build tool, package manager, test runner, benchmark runner and documentation generator in one. Combined with rustup for toolchains and a small set of community subcommands (cargo-audit, cargo-deny, cargo-llvm-cov), it covers the whole build pipeline with very little glue.
~/.cargo/registry, ~/.cargo/git, target/ (via Swatinem/rust-cache) or sccache
How the build works
In CI, each stage of the generic build pipeline maps to a Cargo command, plugin or scanner. Press play, or step through it:
Source + Cargo.toml: A commit triggers CI. Cargo.toml declares dependencies, Cargo.lock pins them and rust-toolchain.toml pins the compiler.
Fetch crates: Cargo downloads crates from crates.io or a private registry; --locked fails on a stale Cargo.lock, and rust-cache caches ~/.cargo and target/.
Lint and format: cargo fmt --all --check fails on unformatted code, and cargo clippy -- -D warnings turns every lint into an error.
Compile: cargo build --release --locked compiles an optimised native binary.
Test and coverage: cargo nextest run (or cargo test) runs the tests, and cargo llvm-cov --fail-under-lines 80 enforces coverage.
Security scans in parallel: Semgrep checks our code, cargo audit checks the RustSec database, cargo deny checks advisories and licences, and Gitleaks scans for secrets.
Quality gate: Format, Clippy, tests, the coverage gate and the supply-chain checks must pass before release.
Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
Package the crate (pass): cargo publish --dry-run builds and validates the .crate package; the release binary is the other output.
SBOM and signing (pass): cargo cyclonedx --format json writes the SBOM, and the artifacts are signed with Sigstore cosign.
Publish (pass): cargo publish uploads the crate to crates.io or a private registry; binaries are kept as CI artifacts.
Profiles control optimisation: dev (fast compile, debug info) and release (opt-level = 3); tune lto and codegen-units for smaller, faster release binaries.
Features turn optional code and dependencies on or off; CI should build with the feature sets you ship (--all-features, --no-default-features).
build.rs runs before compiling the crate (code generation, linking native libraries); it executes arbitrary code at build time, so review it in dependencies.
--locked makes Cargo fail instead of updating Cargo.lock, which keeps CI reproducible.
Build files
File
Purpose
Commit?
Cargo.toml
Package metadata, dependencies, features, profiles, workspace members