持续集成
入门
一个基本的 CI 将构建并测试你的项目
GitHub Actions
要在 GitHub Actions 上测试你的包,这是一个示例 .github/workflows/ci.yml 文件
name: Cargo Build & Test
on:
push:
pull_request:
env:
CARGO_TERM_COLOR: always
jobs:
build_and_test:
name: Rust project - latest
runs-on: ubuntu-latest
strategy:
matrix:
toolchain:
- stable
- beta
- nightly
steps:
- uses: actions/checkout@v4
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- run: cargo build --verbose
- run: cargo test --verbose
这将测试所有三个发布通道(注意:任何工具链版本失败都会导致整个作业失败)。你也可以在 GitHub UI 中点击 "Actions" > "new workflow" 并选择 Rust 来将默认配置添加到你的仓库。有关更多信息,请参阅GitHub Actions 文档。
GitLab CI
要在 GitLab CI 上测试你的包,这是一个示例 .gitlab-ci.yml 文件
stages:
- build
rust-latest:
stage: build
image: rust:latest
script:
- cargo build --verbose
- cargo test --verbose
rust-nightly:
stage: build
image: rustlang/rust:nightly
script:
- cargo build --verbose
- cargo test --verbose
allow_failure: true
这将在 stable 通道和 nightly 通道上进行测试,但 nightly 中的任何中断都不会导致你的整体构建失败。有关更多信息,请参阅GitLab CI 文档。
builds.sr.ht
要在 sr.ht 上测试你的包,这是一个示例 .build.yml 文件。请务必将 <your repo> 和 <your project> 更改为要克隆的仓库和克隆目录。
image: archlinux
packages:
- rustup
sources:
- <your repo>
tasks:
- setup: |
rustup toolchain install nightly stable
cd <your project>/
rustup run stable cargo fetch
- stable: |
rustup default stable
cd <your project>/
cargo build --verbose
cargo test --verbose
- nightly: |
rustup default nightly
cd <your project>/
cargo build --verbose ||:
cargo test --verbose ||:
- docs: |
cd <your project>/
rustup run stable cargo doc --no-deps
rustup run nightly cargo doc --no-deps ||:
这将在 stable 通道和 nightly 通道上测试并构建文档,但 nightly 中的任何中断都不会导致你的整体构建失败。有关更多信息,请参阅builds.sr.ht 文档。
CircleCI
要在 CircleCI 上测试你的包,这是一个示例 .circleci/config.yml 文件
version: 2.1
jobs:
build:
docker:
# check https://circleci.com/developer/images/image/cimg/rust#image-tags for latest
- image: cimg/rust:1.77.2
steps:
- checkout
- run: cargo test
要运行更复杂的流水线,包括不稳定测试检测、缓存和制品管理,请参阅CircleCI 配置参考。
验证最新依赖项
在 Cargo.toml 中指定依赖项时,它们通常匹配一系列版本。详尽测试所有版本组合将变得笨拙。验证最新版本至少可以为运行 cargo add 或 cargo install 的用户提供测试。
测试最新版本时的一些注意事项有
- 最小化影响本地开发或 CI 的外部因素
- 新依赖项发布的频率
- 项目愿意接受的风险水平
- CI 成本,包括间接成本,例如 CI 服务对并行运行器设置了最大值,导致达到最大值时新作业被串行化。
一些潜在的解决方案包括
- 不将
Cargo.lock检入- 取决于 PR 的速度,许多版本可能未经测试
- 这会牺牲确定性
- 设置一个 CI 作业来验证最新依赖项,但将其标记为“失败时继续”
- 取决于 CI 服务,失败可能不明显
- 取决于 PR 的速度,可能会使用比所需更多的资源
- 设置一个计划的 CI 作业来验证最新依赖项
- 托管的 CI 服务可能会禁用长时间未更改仓库的计划作业,影响被动维护的包
- 取决于 CI 服务,通知可能无法路由到能够处理失败的人
- 如果未与依赖项发布速率平衡,可能测试的版本不够多,或可能进行冗余测试
- 通过 PR 定期更新依赖项,例如使用 Dependabot 或 RenovateBot
- 可以将依赖项隔离到自己的 PR 中,或将它们合并到一个 PR 中
- 仅使用必要的资源
- 可以配置频率以平衡 CI 资源和依赖项版本的覆盖范围
使用 GitHub Actions 验证最新依赖项的示例 CI 作业
jobs:
latest_deps:
name: Latest Dependencies
runs-on: ubuntu-latest
continue-on-error: true
env:
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: allow
steps:
- uses: actions/checkout@v4
- run: rustup update stable && rustup default stable
- run: cargo update --verbose
- run: cargo build --verbose
- run: cargo test --verbose
注意事项
- 设置了
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS,以确保解析器不会因为项目的Rust 版本而限制所选依赖项。
对于每平台或每 Rust 版本失败风险较高的项目,可能需要测试更多组合。
验证 rust-version
发布指定rust-version的包时,验证该字段的正确性非常重要。
一些可以帮助解决此问题的第三方工具包括
使用 GitHub Actions 实现此目的的一种示例方法
jobs:
msrv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@cargo-hack
- run: cargo hack check --rust-version --workspace --all-targets --ignore-private
这试图平衡彻底性和周转时间
- 使用单个平台,因为大多数项目都是平台无关的,信任特定于平台的依赖项来验证其行为。
- 使用
cargo check,因为贡献者遇到的大多数问题都是 API 可用性问题,而不是行为问题。 - 跳过未发布的包,因为这假设只有通过注册表使用验证项目的消费者才会关心
rust-version。