CI/CD for Rust
A solid Rust pipeline runs fmt, clippy, test, and build --release on every PR, caches target/ and registry index, and publishes binaries or containers on tags.
Search across all documentation pages
A solid Rust pipeline runs fmt, clippy, test, and build --release on every PR, caches target/ and registry index, and publishes binaries or containers on tags.
# .github/workflows/ci.yml
name: ci
on: [push, pull_request]
jobs:
rust:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.97.0
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
- run: cargo fmt --all -- --check
- run: cargo clippy --all-targets --all-features -- -D warnings
- run: cargo test --all-features
- run: cargo build --release --lockedWhen to reach for this:
strategy:
matrix:
target:
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
steps:
- run: rustup target add ${{ matrix.target }}
- run: cross build --release --target ${{ matrix.target }}# Local parity
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo testWhat this demonstrates:
rust-cache restores dependencies between runs| Layer | Tool |
|---|---|
Registry + target/ | Swatinem/rust-cache |
| sccache | Remote compiler cache for large orgs |
| Docker layer cache | Dependency-only Dockerfile step |
Tag v1.2.3 triggers:
cargo build --releasecargo auditable (optional)Use cargo-release or release-plz for crate versioning in libraries.
--locked in CI - lockfile drift ships broken deps. Fix: fail CI if lock outdated.-D warnings on main branch.services: postgres in Actions or sqlx offline mode.default plus all-features on nightly schedule.cargo test --lib fast job.| Alternative | Use When | Don't Use When |
|---|---|---|
| GitLab CI | Org on GitLab | Already on Actions |
| Buildkite | Custom agents | Simple OSS project |
cargo nextest | Faster test runner | Tiny test suites |
Pin 1.97.0 (or MSRV) in CI; document bump process in team guide.
Commit .sqlx/ directory; set SQLX_OFFLINE=true in CI env.
Use OIDC to cloud (no long-lived AWS keys); inject DATABASE_URL at deploy time only.
Optional miri or 2024 edition preview job; do not block PRs on nightly-only failures.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 16, 2026