持续集成

入门

一个基本的 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 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@v4
      - 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@v4
    - uses: taiki-e/install-action@cargo-hack
    - run: cargo hack check --rust-version --workspace --all-targets --ignore-private

这试图平衡彻底性和周转时间

  • 使用单个平台,因为大多数项目都是平台无关的,相信特定于平台的依赖项会验证其行为。
  • 使用 cargo check,因为贡献者将遇到的大多数问题是 API 可用性而不是行为。
  • 未发布的软件包将被跳过,因为这假设只有经过验证的项目的消费者(通过注册表)才会关心 rust-version