2. GitHub Actions 核心概念:Workflow、Job、Step、Runner、Event、Action

GitHub Actions 是一个事件驱动的自动化平台,其执行模型由六个核心概念构成:Workflow(工作流)、Job(作业)、Step(步骤)、Runner(运行器)、Event(事件)和 Action(动作)。理解这六个概念之间的关系,是编写 CI/CD 流水线的起点。

GitHub Actions 六核心概念关系图 GitHub Actions 六核心概念关系图 Event(事件) push / pull_request / schedule Workflow(工作流) .github/workflows/*.yml Job(作业) build(依赖:无) runs-on: ubuntu-latest Job(作业) test(依赖:build) needs: build Job(作业) deploy(依赖:test) needs: test Step(步骤)- test job 1. actions/checkout@v4 2. Run: npm ci 3. Run: npm test Runner(运行器) GitHub-hosted / self-hosted Action(动作) 可复用的步骤封装 触发关系:Event → Workflow → Job(可并行/串行)→ Step(顺序执行)→ 运行在 Runner 上,Step 可调用 Action 每个 Workflow 必须至少包含一个 Job,每个 Job 至少包含一个 Step

2.1 概念对比与职责划分

概念定义生命周期配置位置关键属性
Event触发工作流运行的事件瞬时(触发器)workflow 文件的 on: 字段push, pull_request, schedule, workflow_dispatch
Workflow一个完整的自动化流程定义从触发到所有 Job 完成.github/workflows/*.ymlname, on, jobs
Job工作流中的一组步骤,运行在同一 Runner与其 Step 同步jobs.<job_id>runs-on, needs, strategy
StepJob 内的单个任务,含命令或 Action顺序执行jobs.<job_id>.stepsname, run, uses
Runner执行 Job 的虚拟环境或机器Job 期间存活runs-on 指定标签ubuntu-latest, windows-latest, 自托管标签
Action可复用的自定义或社区步骤Step 调用时运行独立仓库或 Docker 镜像uses: owner/repo@version

2.2 配置结构与执行流程

一个典型的 Workflow 文件以 YAML 格式编写,GitHub 在推送到仓库后立即解析并排队。以下是后端测试场景中最基础的流水线配置:

name: Backend Test CI
on:
  push:
    branches: [ "main", "develop" ]
  pull_request:
    branches: [ "main" ]

jobs:
  unit-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        run: npm ci
      - name: Run unit tests
        run: npm run test:unit

  integration-test:
    needs: unit-test
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: testpass
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - name: Run integration tests
        run: npm run test:integration

执行顺序解析:

  1. Event 触发: 开发者推送代码到 main 分支 → Event 为 push,分支 main。
  2. Workflow 激活: 仓库发现 .github/workflows/ci.yml,匹配 on.push.branches,创建运行实例。
  3. Job 调度: unit-test 无 needs,立即在 ubuntu-latest Runner 上执行。
    integration-test 声明 needs: unit-test,等待 unit-test 成功后启动。
  4. Step 顺序执行: 在每个 Job 内部,Step 列表从上到下依次运行。如果某 Step 返回非零退出码,默认整个 Job 失败停止。
  5. Action 复用: actions/checkout@v4 是由 GitHub 官方维护的 Action,负责检出仓库代码。用户也可以将自己常用的 shell 命令封装为自定义 Action。

2.3 Runner 的隔离性与上下文

每个 Job 会分配到独立的 Runner 实例,Runner 环境之间完全隔离。下表总结了 GitHub 托管 Runner 和自托管 Runner 的关键差异:

特性GitHub 托管 Runner自托管 Runner
维护成本无(由 GitHub 管理)高(需自行更新 OS、工具链)
网络隔离可访问公网,无法访问内网资源可配置对内网访问,适合数据库/微服务测试
安全边界每次 Job 运行在全新 VM,无持久化需手动加固,避免工作流间数据泄露
计费按分钟计费(免费额度 2000 分钟/月)免费(仅需承担硬件和运维成本)
适用场景开源项目、标准构建测试企业内网部署、对GPU/专用硬件有依赖的场景

2.4 Action 的三种来源

在使用 uses: 关键字时,可以从以下三种位置引用 Action:

  • GitHub 官方 Action: 前缀为 actions/,如 actions/checkout@v4、actions/setup-node@v4。经过大量验证,推荐生产环境使用。
  • 社区/第三方 Action: 格式 author/repo@tag,例如 docker/login-action@v3。使用时建议固定到语义化标签或 commit SHA。
  • 本地 Action: 通过 ./path/to/action 引用仓库目录内的 Action 定义,适合团队内部测试工具复用。

生产部署建议: 在 CI/CD 流水线中固定 Action 版本时,优先使用完整 SHA-1 commit 哈希(如 uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45769f953675),而不是语义化标签。标签可以被覆盖,存在安全风险;SHA 不可变,保证重复构建的一致性。

2.5 Event 触发矩阵与常见陷阱

Workflow 可以响应多种事件,事件还可以组合过滤条件。下面列出后端测试中最常用的四个事件及其注意事项:

事件类型典型配置常见陷阱
pushbranches: [ main ]未添加 paths-ignore 过滤文档/README 变更,造成不必要运行
pull_requesttypes: [ opened, synchronize ]默认包含 labeled、unlabeled 等事件,可能导致 PR 操作时重复触发
schedulecron: '0 6 * * *'只会在默认分支(main)上运行,不会在其他分支触发定时任务
workflow_dispatch手动触发,可输入参数必须手工触发,不适合自动化流程;但适合调试和回滚

2.6 Job 依赖与矩阵策略

在复杂后管任务测试中,经常需要并行运行多版本测试。GitHub Actions 通过 strategy.matrix 实现测试矩阵,同时利用 needs 建立 Job 间依赖。

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run lint

  test:
    needs: lint
    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 ci
      - run: npm test

  deploy-staging:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - run: echo "Deploying to staging..."

依赖阻塞陷阱: 当 Job A(needs: [])和 Job B(needs: A)并行启动但 B 依赖 A 时,B 会等待 A 全部完成(包括矩阵中所有组合)后才开始。如果矩阵组合过多且平均完成时间差异大,整体流水线延迟会较长。建议对关键路径上的矩阵 Job 单独设置较短的超时时间:timeout-minutes: 30。

2.7 Step 的上下文与表达式

Step 可以通过 ${{ }} 表达式访问上下文信息,包括 github、env、secrets、steps 和 runner 等。以下示例展示如何在 Step 之间传递数据:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - id: step1
        name: Generate version
        run: echo "version=1.0.0-$(date +%s)" >> "$GITHUB_OUTPUT"
      - name: Use version from previous step
        run: |
          echo "Building version: ${{ steps.step1.outputs.version }}"
          # 实际构建命令使用该版本号

输出传递机制: 通过写入 $GITHUB_OUTPUT 环境文件(推荐方式,替代已弃用的 ::set-output 命令),下游 Step 可以通过 steps.<id>.outputs.<key> 获取。此机制在并行 Job 之间不可用,跨 Job 传递请使用 artifacts 或 workflow_dispatch 参数。

2.8 性能稳定性关键参数

在日常调试和优化中,以下参数直接影响 Workflow 的执行稳定性:

参数默认值推荐调整策略
timeout-minutes(Job 级)360日常 CI 设置为 30-60 分钟;长任务(如集成测试)设置为 120 分钟,避免幽灵占用 Runner 配额
continue-on-error(Step 级)false矩阵中允许特定组合失败但不阻塞其他组合时设置为 true;主流程步骤应保持 false
max-parallel(矩阵内)无限制免费账户建议主动设置为 5 以下,避免瞬间耗尽并发限制
concurrency(Workflow 级)无同一分支上只保留最新一次运行:concurrency: group: ${{ github.workflow }}-${{ github.ref }}

调试实用命令: 在 Step 中添加以下命令可实时查看 Runner 上下文变量,非常适合排查表达式引用错误:

jobs:
  debug-context:
    runs-on: ubuntu-latest
    steps:
      - name: Dump GitHub context
        env:
          GITHUB_CONTEXT: ${{ toJSON(github) }}
        run: echo "$GITHUB_CONTEXT"
      - name: Dump runner context
        env:
          RUNNER_CONTEXT: ${{ toJSON(runner) }}
        run: echo "$RUNNER_CONTEXT"

输出会以 JSON 格式打印在 Workflow 运行日志中,注意不要将 secrets 一起打印到日志(日志会自动将 secret 值遮蔽为 ***)。