CI/CD for Rust Projects: GitHub Actions from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why is CI/CD critically important for Rust projects?

\n

Developing in Rust is not only about memory safety and high performance, but also about strict discipline. The Rust compiler catches many errors at the build stage, but this does not eliminate the need for quality testing, linting, and dependency compatibility checks. This is where CI/CD (Continuous Integration / Continuous Deployment) comes to the rescue.

\n

GitHub Actions is a built-in automation system that is ideal for Rust projects. It allows you to automatically run tests, format code, check for vulnerabilities, and even publish crates to the crates.io registry with every push to the repository. In this article, we will break down a complete pipeline: from basic cargo build to production deployment.

\n\n

1. Basics: Setting up a basic workflow for Rust

\n

Any CI/CD pipeline in GitHub Actions starts with creating a YAML file in the .github/workflows/ directory. Let's create a ci.yml file for basic Rust project checks.

\n\n

1.1. First workflow: Build and tests

\n

Let's start with a minimal set: cloning the repository, installing Rust, and running tests.

\n
name: Rust CI\n\non:\n  push:\n    branches: [ "main", "develop" ]\n  pull_request:\n    branches: [ "main" ]\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Install Rust\n      uses: dtolnay/rust-toolchain@stable\n    - name: Build\n      run: cargo build --verbose\n    - name: Run tests\n      run: cargo test --verbose
\n

What's happening here?

\n
    \n
  • actions/checkout@v4 — clones your code.
  • \n
  • dtolnay/rust-toolchain@stable — the official action for installing Rust (supports nightly, beta, and stable).
  • \n
  • cargo build and cargo test — the main commands for checking the project.
  • \n
\n

This workflow will run on every push to the main and develop branches, as well as when a Pull Request is created.

\n\n

1.2. Caching dependencies to speed up builds

\n

Rust projects often have many dependencies. To avoid downloading them every time, use caching. This will reduce build time from 5-10 minutes to 30-60 seconds.

\n
    - name: Cache Cargo registry\n      uses: actions/cache@v3\n      with:\n        path: |\n          ~/.cargo/registry\n          ~/.cargo/git\n          target/\n        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}\n        restore-keys: |\n          ${{ runner.os }}-cargo-
\n

Add this step before running cargo build. The hash from the Cargo.lock file ensures that the cache is updated only when dependencies change.

\n\n

2. Advanced code quality checks

\n

Tests alone are not enough to maintain high code quality. Let's add linting, formatting, and security checks.

\n\n

2.1. Formatting (rustfmt) and linting (clippy)

\n

Rust has built-in tools for maintaining a consistent code style. Let's add them in a separate job:

\n
  lint:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v4\n    - uses: dtolnay/rust-toolchain@stable\n      with:\n        components: clippy, rustfmt\n    - name: Check formatting\n      run: cargo fmt --check\n    - name: Run clippy\n      run: cargo clippy -- -D warnings
\n
    \n
  • cargo fmt --check — checks that the code is formatted according to the rustfmt standard.
  • \n
  • cargo clippy -- -D warnings — runs the linter and turns warnings into errors (the -D flag).
  • \n
\n

This will help avoid "dirty" code in the repository.

\n\n

2.2. Security check of dependencies (car

Blogs

Book Recommendations