持续集成
入门
一个基本的 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
文件。请务必将 <你的仓库>
和 <你的项目>
更改为要克隆的仓库和克隆的目录。
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
。