Cargo 持续集成指南

Cargo 持续集成指南

Cargo 持续集成指南,原创技术示意封面

入门

基本的 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:
  - <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 服务可能限制并行 runner 数量,达到上限后新作业只能排队串行执行。

可能的解决方案包括:

  • 不将 Cargo.lock 提交到版本控制。随着 PR 处理速度的不同,可能有许多版本没有被测试;同时会牺牲确定性。
  • 让 CI 作业验证最新依赖,但设置为失败后继续。根据 CI 服务的不同,失败可能不够明显;根据 PR 处理速度的不同,可能消耗超过必要数量的资源。
  • 安排定时 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@v6
      - 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 的软件包时,验证这个字段的准确性很重要。

一些第三方工具可以帮助完成这项工作,包括 cargo-msrv 和 cargo-hack。

下面是用 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。

原文:Continuous Integration — The Cargo Book。本文为中文翻译,全部7个配置示例按抓取时原文保留,未运行 CI。原文中 CircleCI 的 Rust 1.77.2 是示例固定版本,不表示最新版本;GitHub Actions 示例使用 actions/checkout@v6,仍需按项目政策评估第三方 action 与固定版本方式。文档为滚动版本。

Cargo 项目许可为 MIT 或 Apache-2.0,见 LICENSE-MIT 与 LICENSE-APACHE。本译文采用 MIT 许可,其条件如下:

免费授予任何获得本软件及相关文档文件(“软件”)副本的人不受限制地处理软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许软件接收者如此行事,条件是:上述版权声明和本许可声明须包含在软件的所有副本或实质性部分中。软件按原样提供,不作任何明示或默示保证,包括但不限于适销性、特定用途适用性和不侵权保证。无论依据合同、侵权或其他法律理论,作者或版权持有人均不对因软件、软件使用或其他软件交易而产生、引起或相关的任何索赔、损害或其他责任负责。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容