Github Pipeline for Rust

GitHub Actions automate your Rust development workflow. This post covers essential workflows for maintaining code quality and catching issues early.

Code Formatting

Enforces consistent code style across your project. Fails if code isn't formatted according to rustfmt rules.

rustfmt:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Check format
      run: cargo fmt --check

Unused Dependencies

Identifies dependencies in Cargo.toml that your code doesn't actually use. Keeps your dependency tree lean and reduces build times.

unused-dependencies:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Install cargo-machete
      uses: taiki-e/install-action@v2
      with:
        tool: cargo-machete
    - name: Check for unused dependencies
      run: cargo machete

Security Audit

Scans your dependencies for known security vulnerabilities using the RustSec Advisory Database.

security-audit:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Install cargo-audit
      uses: taiki-e/install-action@v2
      with:
        tool: cargo-audit
    - name: Run security audit
      run: cargo audit

License and Dependency Policy

Validates that all dependencies meet your licensing requirements and aren't banned. Useful for ensuring compliance in commercial projects.

cargo-deny:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Install cargo-deny
      uses: taiki-e/install-action@v2
      with:
        tool: cargo-deny
    - name: Check licenses and advisories
      run: cargo deny check

Static Analysis

Runs Clippy lints to catch common mistakes and non-idiomatic code. The -D warnings flag treats warnings as errors, forcing you to address them.

clippy:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Setup Rust cache
      uses: Swatinem/rust-cache@v2
      with:
        cache-on-failure: true
    - name: Check for clippy warnings
      run: cargo clippy --all-targets --all-features --color always – -D warnings

Unit Tests

Runs tests defined alongside your code in lib files. Quick feedback on core logic.

unit-tests:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Setup Rust cache
      uses: Swatinem/rust-cache@v2
      with:
        cache-on-failure: true
    - name: Run unit tests
      run: cargo test --lib

Integration Tests

Runs tests from the tests/ directory that verify multiple components working together.

integration-tests:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Setup Rust cache
      uses: Swatinem/rust-cache@v2
      with:
        cache-on-failure: true
    - name: Run integration tests
      run: cargo test --test integration_test

Release Build

Verifies that your code compiles with optimizations enabled. Catches issues that only appear in release mode.

build:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
    - name: Setup Rust cache
      uses: Swatinem/rust-cache@v2
      with:
        cache-on-failure: true
    - name: Release build
      run: cargo build --release --verbose

Caching Strategy

The Swatinem/rust-cache action caches compilation artifacts between workflow runs. This includes:

  • Compiled dependencies in target/
  • Cargo registry and git checkouts
  • Incremental compilation data

The cache-on-failure: true option saves the cache even when the build fails. This is useful because:

  • Your code might fail tests, but dependencies still compiled successfully
  • Next run will be faster even if this one failed
  • Particularly helpful when fixing compilation errors incrementally

Without caching, each workflow run compiles all dependencies from scratch. With caching, only your changed code recompiles, cutting workflow time from minutes to seconds.

Putting It All Together

Check out the complete workflow configuration on GitHub.