入门 The Cargo Team 2026-09-13 15:48:21 · 0 阅读

第10章 持续集成实践

快速入门

一个基础的 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@v6
      - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
      - run: cargo build --verbose
      - run: cargo test --verbose
  

这将测试所有三个发布通道(注意,任何一个工具链版本上的失败都会导致整个任务失败)。你也可以在 GitHub 界面中点击 "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:
  - <你的仓库>
tasks:
  - setup: |
      rustup toolchain install nightly stable
      cd <你的项目>/
      rustup run stable cargo fetch
  - stable: |
      rustup default stable
      cd <你的项目>/
      cargo build --verbose
      cargo test --verbose
  - nightly: |
      rustup default nightly
      cd <你的项目>/
      cargo build --verbose ||:
      cargo test --verbose  ||:
  - docs: |
      cd <你的项目>/
      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:
      # 最新镜像标签请查看 https://circleci.com/developer/images/image/cimg/rust#image-tags
      - image: cimg/rust:1.77.2
    steps:
      - checkout
      - run: cargo test

如果想搭建更复杂的流水线,比如 flaky 测试检测、缓存和构建产物管理,请参阅 CircleCI Configuration Reference

验证最新依赖

Cargo.toml指定依赖时,通常匹配的是一个版本区间。穷举测试所有版本组合并不现实,但至少验证一下最新版本,就能覆盖到使用 cargo addcargo install 的用户场景。

测试最新版本时需要考虑以下因素:

  • 尽量减少影响本地开发或 CI 的外部因素
  • 新依赖的发布频率
  • 项目愿意承担的风险程度
  • CI 成本,包括间接成本,比如 CI 服务有并行任务数上限,达到上限后新任务只能排队串行执行。

一些可行的方案包括:

  • 未将 Cargo.lock 提交到版本控制
    • 取决于 PR 提交频率,许多依赖版本可能未经测试
    • 这代价是牺牲了构建的确定性
  • 配置一个 CI 任务验证最新依赖,但将其标记为“失败时继续”
    • 取决于 CI 服务,失败状态可能不易察觉
    • 取决于 PR 提交频率,可能会消耗比必要更多的资源
  • 配置定时 CI 任务验证最新依赖
    • 托管式 CI 服务可能会禁用那些许久未更新的仓库中的定时任务,从而被动地影响这些包
    • 取决于 CI 服务,失败通知可能无法送达能够处理该问题的人员
    • 若未与依赖发布频率相匹配,可能导致测试的版本覆盖不足,或产生冗余测试
  • 通过 PR 定期更新依赖,例如使用 DependabotRenovateBot
    • 可以将每个依赖更新隔离在独立的 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@v6
      - run: rustup update stable && rustup default stable
      - run: cargo update --verbose
      - run: cargo build --verbose
      - run: cargo test --verbose

注意事项:

对于出现平台特定或特定 Rust 版本失败风险较高的项目,可能需要测试更多的组合。

验证 rust-version

发布指定了 rust-version 的软件包时,必须校验该字段的正确性。

以下是可辅助完成此任务的第三方工具:

以下是使用 GitHub Actions 执行此检查的一种示例方法:

jobs:
  msrv:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v6
    - uses: taiki-e/install-action@cargo-hack
    - run: cargo hack check --rust-version --workspace --all-targets --ignore-private

此示例旨在平衡检查的完整性与执行耗时:

  • 仅使用单一平台进行测试,因为大多数项目与平台无关,且依赖平台特定库来验证其行为。
  • 使用 cargo check,因为贡献者最常遇到的问题涉及 API 可用性,而非运行时行为。
  • 跳过未发布的软件包,因为假定只有通过注册表消费该项目的用户才关心 rust-version

检查警告

通常,项目希望在官方分支上保持“无警告”状态,而在本地开发时则可以较为宽松。 可以使用 build.warnings = "deny" 在存在警告时使 CI 任务失败。

以下是使用 GitHub Actions 检查警告的 CI 任务示例:

jobs:
  warnings:
    runs-on: ubuntu-latest
    env:
      CARGO_BUILD_WARNINGS: deny
    steps:
      - uses: actions/checkout@v6
      - run: rustup update stable && rustup default stable
      - run: rustup component add clippy
      - run: cargo clippy --all-targets --all-features --keep-going

注意事项:

  • 由于围绕警告行为的兼容性保证有限,新的工具链版本可能导致 CI 失败。 建议通过一个自动创建 PR 的任务来固定工具链版本,以便在新版本发布时升级工具链。
  • 在选择不需要检查的平台、功能以及软件包/构建目标组合时,需权衡检查的彻底性与执行耗时。
  • 有些 CI 系统支持直接集成 lint 报告,例如在 GitHub 上使用 clippy-sarif
  • 评论 (0)