第七章:GitHub Actions 实战:workflow 与 actions

如果说 Jenkins 是 CI/CD 界的"瑞士军刀",GitLab CI 是"一体化平台",那么 GitHub Actions 就是"云原生原生公民"------它天生与 GitHub 仓库融为一体,配置简单、生态丰富、免费配额充足。本章从零开始讲解 GitHub Actions 的核心概念:Workflow、Job、Step、Action、Runner,以及 .github/workflows/*.yml 的完整语法。通过一个完整的 Spring Boot 项目示例,你将学会如何用 YAML 文件在 20 行代码内搭建一条生产级的 CI 流水线。

一、GitHub Actions 核心概念

GitHub Actions 是一套内置于 GitHub 的自动化平台,它允许你在特定事件(如代码推送、PR 创建)发生时,自动执行构建、测试、部署等任务。

四个核心概念:

二、Workflow 文件结构

Workflow 文件使用 YAML 语法,存放在仓库的 .github/workflows/ 目录下。一个典型的 Workflow 包含以下顶层元素:

yaml 复制代码
# 1. 工作流名称(可选,建议加上)
name: CI/CD Pipeline

# 2. 触发事件(必填)
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

# 3. 环境变量(可选)
env:
  NODE_VERSION: "20"

# 4. 作业定义(必填)
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Run tests
        run: npm test

三、事件(Events):何时触发

on 字段定义 Workflow 的触发条件。

3.1 单事件触发

yaml 复制代码
on: push

3.2 多事件触发

yaml 复制代码
on: [push, pull_request]

3.3 带条件的事件

yaml 复制代码
on:
  push:
    branches:
      - main
      - develop
    paths:
      - 'src/**'
      - '!docs/**'        # 排除 docs 目录
  pull_request:
    branches:
      - main
    types:
      - opened
      - synchronize
      - reopened
  schedule:
    - cron: '0 2 * * *'   # 每天凌晨 2 点执行
  workflow_dispatch:       # 手动触发

3.4 常用事件类型

四、作业(Jobs)与步骤(Steps)

Job 是 Workflow 的核心执行单元。

4.1 基本 Job 定义

yaml 复制代码
jobs:
  build:
    runs-on: ubuntu-latest          # 指定 Runner 环境
    steps:
      - name: Checkout code
        uses: actions/checkout@v4   # 使用预置 Action
      - name: Run build
        run: npm run build          # 执行 Shell 命令

4.2 Job 依赖关系

默认情况下,所有 Job 并行执行。通过 needs 关键字可以控制执行顺序:

yaml 复制代码
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm test

  build:
    runs-on: ubuntu-latest
    needs: test          # 等 test 成功后执行
    steps:
      - run: npm run build

  deploy:
    runs-on: ubuntu-latest
    needs: [test, build] # 等 test 和 build 都成功后执行
    steps:
      - run: ./deploy.sh

4.3 矩阵策略(Matrix Strategy)

用一组并行配置同时运行多个 Job,适用于多版本测试或多平台构建:

yaml 复制代码
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
        os: [ubuntu-latest, windows-latest]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm test

这会生成 3 × 2 = 6 个并行 Job,分别测试不同 Node 版本和操作系统组合。

五、Runner:执行环境

Runner 是运行 Job 的服务器。

5.1 GitHub 托管 Runner

GitHub 提供三种托管 Runner:

yaml 复制代码
jobs:
  build:
    runs-on: ubuntu-latest

5.2 自托管 Runner(Self-hosted Runner)

当需要特殊硬件、内网访问或合规要求时,可以自托管 Runner。

注册步骤:

进入仓库 Settings → Actions → Runners

点击"New runner",选择操作系统

按照页面提示下载并运行配置脚本

在 Workflow 中使用:

yaml 复制代码
jobs:
  build:
    runs-on: self-hosted

六、Actions:可复用的功能模块

Action 是 GitHub Actions 生态的核心。GitHub Marketplace 提供了超过 20,000 个预置 Action。

6.1 最常用的官方 Actions

6.2 Action 版本锁定

最佳实践:始终使用语义化版本标签(如 @v4),而非 @main 分支。

yaml 复制代码
# ✅ 推荐:锁定到主要版本
- uses: actions/checkout@v4

# ⚠️ 不安全:使用 main 分支(可能引入破坏性变更)
- uses: actions/checkout@main

# 🔒 最安全:锁定到具体 commit SHA
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

6.3 Action 的输入与输出

yaml 复制代码
- name: Set up Node.js
  id: setup-node                    # 设置 ID 以便后续引用输出
  uses: actions/setup-node@v4
  with:                             # 输入参数[reference:33]
    node-version: 20
    cache: 'npm'

- name: Print Node version
  run: echo "Node version is ${{ steps.setup-node.outputs.node-version }}"  # 引用输出[reference:34]

七、上下文(Contexts)与表达式

GitHub Actions 提供了丰富的上下文变量,可在 ${{ }} 中引用。

7.1 常用上下文

7.2 条件执行

yaml 复制代码
steps:
  - name: Deploy to production
    if: github.ref == 'refs/heads/main' && success()  # 仅在 main 分支且前置步骤成功时执行
    run: ./deploy.sh

  - name: Notify on failure
    if: failure()   # 仅在失败时执行
    run: ./notify-failure.sh

八、环境变量与 Secrets

8.1 环境变量

可在 Workflow、Job 或 Step 级别定义环境变量:

yaml 复制代码
env:
  NODE_VERSION: "20"
  CI: true

jobs:
  build:
    env:
      BUILD_ENV: "production"
    steps:
      - name: Print env
        run: echo "Node version is $NODE_VERSION"

8.2 Secrets(加密密钥)

Secrets 用于存储敏感信息(密码、Token 等)。

配置方式:

进入仓库 Settings → Secrets and variables → Actions

点击"New repository secret"

使用方式:

yaml 复制代码
steps:
  - name: Login to Docker Registry
    run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

8.3 环境级别的 Secrets 与保护规则

GitHub 支持为不同环境(如 dev、staging、production)分别配置 Secrets 和保护规则:

required reviewers:部署到该环境需要指定人员审批

wait timer:部署前等待指定时间

九、小结

GitHub Actions 通过简洁的 YAML 语法,将 CI/CD 流水线定义与代码仓库融为一体。核心组件包括:

Workflow:存放在 .github/workflows/*.yml 中的自动化流程定义

Event:通过 on 定义触发条件

Job:在 Runner 上执行的独立任务单元

Step:Job 中的具体操作(命令或 Action)

Action:可从 Marketplace 复用的功能模块

与 Jenkins 和 GitLab CI 相比,GitHub Actions 的最大优势是与 GitHub 生态的无缝集成和丰富的 Marketplace 生态。