持续集成

开始使用

基本的 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 用户界面中点击 "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

这将在稳定版和 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 ||:

这将在稳定版和 nightly 版上测试和构建文档,但 nightly 版中的任何错误都不会导致您的整体构建失败。有关更多信息,请参阅 builds.sr.ht 文档

验证最新依赖项

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
    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