CI/CD for Rust projects: GitHub Actions — Part 2: Testing and Deployment
In the first part, we set up a basic build pipeline for a Rust project. Now, delving deeper into programming in Rust, we will look at automated testing, linting, and deployment. This is a mandatory stage of learning Rust for beginners who want to write professional code. Today you will learn how to make your CI/CD truly useful.
1. Running tests and checking coverage
Any serious Rust project requires automatic test execution. In GitHub Actions, this is done using the cargo test command. However, to get the maximum benefit, add code coverage checking using tarpaulin.
Setting up the test environment
Add a step to your workflow file (.github/workflows/ci.yml):
name: CI for Rust
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: Run tests
run: cargo test --verbose
- name: Generate coverage
run: |
cargo install cargo-tarpaulin
cargo tarpaulin --out Xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
This code shows how easy it is to integrate Rust with external services. cargo tarpaulin will create a report that can be uploaded to Codecov or Coveralls. For Rust for beginners, it is important to understand: tests are your first line of defense.
2. Linting and formatting
Quality code is not only working code but also readable code. In Rust, there are two powerful tools: clippy (linter) and rustfmt (formatter). Include them in the pipeline.
Adding Clippy and Rustfmt
Add a new job or extend the existing one:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: clippy, rustfmt
- name: Check formatting
run: cargo fmt -- --check
- name: Run Clippy
run: cargo clippy -- -D warnings
The -D warnings flag turns warnings into errors. This is strict but effective for learning: you will immediately find out about potential problems. Remember that in programming in Rust, strictness is an advantage.
3. Automatic deployment to GitHub Pages
When tests and linting have passed, you can automatically publish documentation. Rust generates documentation via cargo doc. Deploying to GitHub Pages is an excellent way to showcase the results.
Workflow for deployment
Create a separate file .github/workflows/deploy.yml:
name: Deploy Documentation
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Build documentation
run: cargo doc --no-deps --document-private-items
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./target/doc
This pipeline triggers only on pushes to main. It generates documentation and publishes it. For Rust for beginners, this is a great way to show your projects to the world.
4. Optimizing build time: caching
Building Rust projects can be time-consuming. GitHub Action