CI/CD for a Rust CLI with GitHub Actions
Format, lint, test, and publish cross-platform binaries for your Rust CLI.
A Rust CLI ships as compiled binaries per platform. This recipe runs the standard Rust checks, then builds release binaries on an OS matrix and attaches them to a GitHub Release on a tag.
What the pipeline does
- install Rust with rustfmt and clippy
- check fmt and clippy
- run tests
- build release binaries on an OS matrix on a tag
- attach binaries to a Release
The workflow
The release job runs across macOS, Linux, and Windows, builds an optimized binary, and uploads it to the release matching the tag using softprops/action-gh-release.
name: CI
on:
push:
branches: [main]
tags: ['v*']
pull_request:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
- run: cargo fmt --all --check
- run: cargo clippy --all-targets -- -D warnings
- run: cargo test --all
release:
needs: check
if: startsWith(github.ref, 'refs/tags/v')
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo build --release
- uses: softprops/action-gh-release@v2
with:
files: target/release/mycli*Caching and speed
Swatinem/rust-cache caches the registry and target directory on the check job. The matrix release job compiles in release mode on three OSes, which is CPU-heavy; cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) cut total release time and auto-retry transient crates.io fetches.
Deploying
The binaries land on the GitHub Release. For wider distribution, publish to crates.io with cargo publish, add a Homebrew formula, or build a musl static binary for a portable Linux artifact and a tiny container.
Key takeaways
- Run fmt, clippy -D warnings, and test before releasing.
- Build release binaries across an OS matrix.
- Also consider crates.io and a Homebrew formula.