引言:为什么 CI/CD 对 Rust 项目很重要?
Rust 开发不仅仅是编写安全快速的代码,还要确保其长期稳定性。CI/CD(持续集成/持续部署)是一种自动化项目构建、测试和部署的实践。对于拥有严格编译器和类型系统的 Rust 来说,CI/CD 尤其有用:它可以在早期阶段捕获错误,检查依赖兼容性,并自动发布新版本。
GitHub Actions 是 GitHub 平台内置的 CI/CD 工具。它提供了 Rust 的现成模板、强大的测试矩阵以及与任何云服务集成的能力。在本文中,我们将介绍如何为 Rust 项目设置一个完整的流水线:从基本检查到发布到 crates.io。
1. 基础:为 Rust 创建第一个 workflow
GitHub Actions 中的 workflow 是一个 YAML 文件,描述了一系列步骤。对于 Rust 项目,最小的 workflow 应包括:安装 Rust、下载依赖、构建和运行测试。
在仓库根目录下创建文件 .github/workflows/ci.yml:
name: Rust CI
on: push: branches: [ main ] pull_request: branches: [ main ]
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4 - name: Setup Rust uses: actions-rs/toolchain@v1 with: toolchain: stable override: true components: clippy, rustfmt - name: Cache dependencies uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git 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这个 workflow 在每次推送到主分支或创建 pull request 时运行。依赖缓存(actions/cache)大大加快了后续运行速度。请注意 clippy 中的 -- -D warnings 标志——它将警告转化为错误,从而提高代码质量。
1.1. 矩阵测试:在多个 Rust 版本上检查
Rust 有三个主要发布通道:stable、beta 和 nightly。为了确保你的代码在所有版本上都能工作,请使用策略矩阵:
jobs: test: runs-on: ubuntu-latest strategy: matrix: rust: [stable, beta, nightly] steps: - uses: actions/checkout@v4 - name: Setup Rust ${{ matrix.rust }} uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} override: true - name: Build and test run: | cargo build cargo test还要添加对最低支持 Rust 版本(MSRV)的检查。这对于库尤其重要。例如,如果你的 Cargo.toml 指定了 rust-version = "1.60",请在矩阵中添加 rust: [1.60.0, stable]。
2. 进阶技巧:优化与安全
2.1. 按配置文件进行缓存
默认情况下,cargo build 使用 debug 配置文件。对于 release 构建,缓存会不同。为不同的配置文件分开缓存:
- name: Cache dependencies uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.rust }}-${{ matrix.profile }} env: CARGO_TERM_COLOR: always在矩阵中添加 profile: [debug, release]。