Rust GitHub Actions
GitHub Actions 是 GitHub 提供的 CI/CD(持续集成/持续交付)平台,用于自动化 Rust 项目的构建、测试、发布和部署。它支持 YAML 配置的工作流(workflow),可以触发于 push、pull request 等事件。本教程基于官方文档和社区最佳实践,提供从基础到高级的完整指导,适用于 Rust 库或应用开发。教程假设你有基本的 YAML 和 Rust 知识。 当前日期为 2025 年 9 月 7 日,信息基于最新可用资源。
1. 介绍
GitHub Actions 允许你在仓库中定义 .github/workflows/ 目录下的 YAML 文件,这些文件描述自动化任务。Rust 项目常用 Actions 来:
- 构建(Build):运行
cargo build。 - 测试(Test):运行
cargo test,支持多工具链(如 stable、beta、nightly)。 - 代码检查(Lint):集成
clippy和rustfmt。 - 缓存(Cache):加速依赖和构建。
- 发布(Publish):上传到 crates.io 或 Docker Hub。
- 部署(Deploy):如使用 Shuttle 或其他平台。
优势:免费(公共仓库无限分钟,私有仓库有限制)、集成 GitHub、支持矩阵构建(多平台/工具链)。 入门:仓库 > Actions > New workflow > 搜索 "Rust" 模板。
2. 前置要求
- GitHub 仓库(公共或私有)。
- Rust 项目:包含
Cargo.toml和源代码。 - 安装 rustup 和 Cargo。
- 可选:crates.io 账户(发布用),GitHub Secrets(存储 token,如 CRATES_TOKEN)。
- 权限:仓库需启用 Actions(Settings > Actions > General > Allow all actions)。
验证:本地运行 cargo build 和 cargo test 确保项目正常。
3. 基本 CI 工作流:构建和测试
创建第一个工作流:.github/workflows/ci.yml。
步骤
- 在仓库根目录创建
.github/workflows/文件夹。 - 添加
ci.yml:name: Rust CI # 工作流名称 on: # 触发事件 push: branches: [ "main" ] pull_request: branches: [ "main" ] env: # 全局环境变量 CARGO_TERM_COLOR: always # 启用彩色输出 jobs: # 作业定义 build_and_test: name: Rust project # 作业名称 runs-on: ubuntu-latest # 运行器(GitHub 托管的 Ubuntu) steps: - name: Checkout code # 检出仓库 uses: actions/checkout@v4 # 使用官方 checkout action - name: Install Rust # 安装 Rust 工具链 uses: dtolnay/rust-toolchain@stable # 使用 dtolnay 的 action(推荐,自动安装 stable) with: components: rustfmt, clippy # 添加 rustfmt 和 clippy - name: Cache dependencies # 缓存 Cargo 依赖(可选,但推荐) uses: actions/cache@v4 with: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} path: | ~/.cargo/registry ~/.cargo/git target - name: Build # 构建项目 run: cargo build --verbose # --verbose 显示详细输出 - name: Run tests # 运行测试 run: cargo test --verbose - 提交并推送:
git add . && git commit -m "Add CI workflow" && git push。 - 查看:仓库 > Actions > 运行的工作流,检查日志。
解释
- on:触发于 push 或 PR 到 main 分支。
- jobs:单个作业
build_and_test,在 Ubuntu 上运行。 - steps:序列步骤,包括检出、安装 Rust、缓存、构建、测试。
- uses:调用复用 Actions(如 checkout、rust-toolchain)。
- run:执行 shell 命令(默认 bash)。
最佳实践:使用矩阵(matrix)测试多工具链:
strategy:
matrix:
toolchain: [stable, beta, nightly] # 测试多个版本
steps:
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.toolchain }}
这会并行运行三个作业,失败任何一职则整体失败。
4. 集成代码检查:Clippy 和 Rustfmt
添加 lint 步骤,确保代码质量。
更新 ci.yml:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- run: cargo fmt --all -- --check # 检查格式,不修改
- run: cargo clippy --all-targets --all-features -- -D warnings # 拒绝警告
cargo fmt --check:验证格式一致性。cargo clippy -D warnings:将警告视为错误。- 最佳实践:添加
continue-on-error: true到非关键步骤,避免阻塞。
5. 缓存优化
Rust 构建慢?使用缓存加速。
上述示例已包含 Cargo 缓存。高级:使用 sccache(编译缓存):
- name: Install sccache
uses: mozilla-actions/sccache-action@v0.0.7 # Mozilla 的 sccache action
env:
SCCACHE_GHA_ENABLED: true
RUSTC_WRAPPER: sccache # 包装 rustc
- 支持 S3 等后端,减少重复编译。
- 提示:缓存键基于
Cargo.lockhash,确保依赖变更时失效。
6. 多平台和交叉编译
测试多目标(如 x86_64、ARM):
jobs:
cross-compile:
runs-on: ubuntu-latest
strategy:
matrix:
target: [x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- run: cargo build --target ${{ matrix.target }} --release
- 安装目标:
rustup target add <triple>。 - 最佳实践:仅构建 release 模式,上传 artifacts:
- name: Upload binary uses: actions/upload-artifact@v4 with: name: binary-${{ matrix.target }} path: target/${{ matrix.target }}/release/myapp
7. 发布到 crates.io
自动化发布:仅在 main 分支 tag 时触发。
创建 .github/workflows/release.yml:
name: Release to crates.io
on:
push:
tags: [ "v*" ] # 触发于 v1.0.0 等 tag
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- run: cargo build --release
- name: Login to crates.io
run: cargo login ${{ secrets.CRATES_TOKEN }} # Secrets 中存储 token
- name: Publish
run: cargo publish
- 获取 token:crates.io > Account Settings > API access tokens > New token(full access)。
- 添加 Secret:仓库 > Settings > Secrets and variables > Actions > New repository secret (CRATES_TOKEN)。
- 最佳实践:使用
cargo publish --dry-run测试;添加变更日志。
8. 依赖管理:Dependabot
自动化依赖更新。
创建 .github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly" # 每周检查
ignore:
- dependency-name: "semver" # 忽略特定依赖
- dependency-name: "crates-io"
open-pull-requests-limit: 10 # 最多 10 个 PR
- Dependabot 会创建 PR 更新 Cargo.toml 和 Cargo.lock。
- 最佳实践:结合 CI 运行测试,确保更新安全。
9. 高级发布:使用 release-plz
自动化发布笔记和 crates.io 上传。
- 添加依赖:
cargo add release-plz --build。 - 创建工作流
.github/workflows/release-plz.yml:name: Release on: push: branches: [ "main" ] permissions: contents: write # 发布笔记 pull-requests: write jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # 获取历史 - uses: dtolnay/rust-toolchain@stable - uses: release-plz/release-plz-action@v0.5 with: version: semver sign: false # 如需签名,配置 GPG
- release-plz 生成 PR 包含发布笔记和版本变更,合并后自动发布。
- 最佳实践:用于库项目,集成 changelog。
10. Docker 集成:构建和推送镜像
对于应用,构建 Docker 镜像。
更新 ci.yml 添加 Docker 步骤:
- name: Build Docker image
run: docker build -t myapp:latest .
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push to Docker Hub
run: docker push myapp:latest
- Dockerfile 示例:
FROM rust:1.81 as builder WORKDIR /usr/src/app COPY . . RUN cargo build --release FROM debian:bookworm-slim COPY --from=builder /usr/src/app/target/release/myapp /usr/local/bin/ CMD ["myapp"] - 最佳实践:使用多阶段构建,缓存 Docker 层。
11. 优化和最佳实践
- 速度:使用 sccache 和缓存;并行作业(matrix);避免 verbose 在生产。
- 安全:使用 OIDC 认证(而非 token)登录 registry;扫描依赖(cargo-audit)。
- 成本:公共仓库免费;私有限 2000 分钟/月,使用 self-hosted runners。
- 多平台:测试 Windows/macOS:
runs-on: windows-latest或macos-latest。 - 通知:集成 Slack/Discord 使用 actions/slack-notify。
- 矩阵排除:
fail-fast: false允许部分失败继续。 - 环境:使用
environment保护部署步骤。 - 秘密管理:避免硬编码,使用 GitHub Secrets。
- 监控:查看 Actions > 运行日志;设置 badge 在 README:
。 - 常见错误:YAML 缩进;工具链版本不匹配;权限不足(添加
permissions: { contents: read })。
12. 故障排除
- 工作流失败:检查日志,常见:缺少组件(添加 clippy 到 rust-toolchain);缓存失效(清除 key)。
- 权限错误:添加
permissions到 workflow。 - 慢构建:启用缓存,升级到 GitHub-hosted larger runners。
- 测试失败:本地复现;使用
cargo nextest加速测试(cargo install cargo-nextest)。 - 发布失败:验证 token 权限;检查 Cargo.toml metadata(如 license)。