GitHub Actions 自动化部署实战

CI/CD 是现代软件开发的基础设施。GitHub Actions 作为 GitHub 生态的原生 CI/CD 方案,上手简单、社区活跃,已经成为我所有项目的标配。本文分享我在实际项目中积累的配置经验和最佳实践。

基础概念

一个 GitHub Actions 工作流由以下概念构成:

  • Workflow:定义在 .github/workflows/ 目录下的 YAML 文件,一个仓库可以有多个工作流
  • Event:触发工作流的事件,如 push、pull_request、schedule(定时)、workflow_dispatch(手动)
  • Job:工作流中的一个执行单元,多个 Job 默认并行执行
  • Step:Job 中的一个执行步骤,可以运行命令或使用 Action
  • Runner:执行 Job 的虚拟环境(ubuntu-latest、macos-latest、windows-latest)

前端项目部署:静态站点到 GitHub Pages

这是最常见的场景——将静态网站自动部署到 GitHub Pages:

name: Deploy to GitHub Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

关键点说明:

  • permissions: contents: write 是必需的,否则 Action 无法推送部署分支
  • npm cinpm install 更快且更确定,适合 CI 环境
  • peaceiris/actions-gh-pages 是社区最常用的 GitHub Pages 部署 Action

Rust 项目:多平台构建与发布

对于我的开源库 MarkdownKit,每次打 tag 时需要自动构建多平台二进制文件并发布到 GitHub Release:

name: Release

on:
  push:
    tags: ['v*']

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - name: Setup Rust
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable

      - name: Build release binary
        run: cargo build --release

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: markdownkit-${{ matrix.os }}
          path: target/release/markdownkit*

  release:
    needs: build
    runs-on: ubuntu-latest

    steps:
      - uses: actions/download-artifact@v4
      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          files: markdownkit-*/markdownkit*
          generate_release_notes: true

这里使用了矩阵构建(matrix strategy),同一个 Job 会在三个操作系统上并行执行,最后在 release Job 中汇总产物。

缓存优化:加速 CI

缓存是 CI 性能优化的关键。不同语言的缓存策略:

# Node.js: 缓存 node_modules
- uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'npm'

# Rust: 缓存 target/ 目录和 cargo registry
- uses: actions/cache@v4
  with:
    path: |
      ~/.cargo/registry/cache/
      ~/.cargo/git/db/
      target/
    key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }}

最佳实践总结

  1. 使用 workflow_dispatch:除了自动触发外,总是加上手动触发选项,方便排查和重试
  2. 锁定 Action 版本:使用 @v4 而非 @main,避免上游改动破坏你的工作流
  3. 最小权限原则:通过 permissions: 字段显式声明所需权限,而非使用默认的读写全部权限
  4. 合并 CI 步骤:将测试、lint、构建合并到一个 Job 中(如果速度可以接受),减少 Job 之间的等待和 artifact 传递开销
  5. 善用 concurrency:使用 concurrency.group 确保同一分支的旧工作流在新 push 时自动取消
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

这套配置已经在我 4 个开源项目中稳定运行了一年多,希望对你有所帮助 🚀