CI/CD for Rust Projects: Setting Up GitHub Actions

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 CI/CD is Important for Rust Projects



Developing in Rust is not only about memory safety and high performance. In the modern world, any serious project requires automation of build, testing, and deployment processes. CI/CD (Continuous Integration / Continuous Deployment) allows teams to release updates faster, reducing the risk of human errors and ensuring codebase stability.



GitHub Actions is a built-in GitHub tool for automating workflows. It is ideal for Rust projects as it provides ready-made actions for installing the compiler, caching dependencies, and publishing crates to crates.io. In this article, we will walk through setting up a full CI/CD pipeline for a Rust application from scratch.



1. GitHub Actions Basics for Rust



Before diving into the code, let's understand the basic structure of GitHub Actions. Each workflow is defined by a YAML file located in the .github/workflows/ directory. A workflow consists of one or more jobs that run sequentially or in parallel on virtual machines (runners).



For Rust projects, a minimal workflow includes the following steps:



  • Checkout — fetching the latest version of the code from the repository.
  • Install Rust — via the actions-rs/toolchain action or the official dtolnay/rust-toolchain.
  • Cache dependencies — speeding up builds by saving target/ and ~/.cargo/.
  • Build and test — running cargo build and cargo test.


Example of a basic workflow (file .github/workflows/ci.yml):



name: Rust CI

on: push: branches: [ main ] pull_request: branches: [ main ]

env: CARGO_TERM_COLOR: always

jobs: build: runs-on: ubuntu-latest

steps: - uses: actions/checkout@v3 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: components: clippy, rustfmt - name: Cache dependencies uses: actions/cache@v3 with: path: | ~/.cargo/ target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Build run: cargo build --verbose - name: Run tests run: cargo test --verbose - name: Lint with clippy run: cargo clippy -- -D warnings - name: Check formatting run: cargo fmt --check


This workflow runs on every push to the main branch and on every pull request. It checks that the code compiles, passes tests, has no linter errors, and conforms to formatting style.



2. Advanced Strategies: Matrix Build and Caching



Rust is a cross-platform language, and it is often necessary to verify the build on multiple operating systems or architectures. For this, a matrix build is used.



Let's add support for Windows and macOS to our workflow:



jobs:  build:    strategy:      matrix:        os: [ubuntu-latest, windows-latest, macos-latest]        rust: [stable, beta]        runs-on: ${{ matrix.os }}        steps:    - uses: actions/checkout@v3        - name: Install Rust      uses: dtolnay/rust-toolchain@master      with:        toolchain: ${{ matrix.rust }}        components: clippy        - name: Cache      uses: actions/cache@v3      with:        path: |          ~/.cargo/registry/          ~/.cargo/git/          target/        key: ${{ matrix.os }}-cargo-${{ matrix.rust }}-${{ hashFiles('**/Cargo.lock') }}        - name: Build      run: cargo build --                

Blogs

Book Recommendations