第2章:工作流文件结构详解——核心字段配置与顺序

本章深入解析 GitHub Actions 工作流文件的骨架结构。理解 name、on、jobs、steps、uses、run、env 等核心字段的语义、配置语法与书写顺序,是编写可维护、可复用的 CI/CD 流水线的基础。这些字段共同定义了一个工作流的触发条件、执行环境和具体任务。

核心原则:YAML 的缩进代表层级,字段顺序不影响执行逻辑,但遵循社区惯例(从上到下:描述→触发→环境→工作→步骤)能提升可读性。

2.1 字段层级结构与书写顺序

一个完整的工作流文件遵循以下固定层级(缩进使用两个空格):

name: <工作流名称>
run-name: <动态运行名称>   # 可选,支持表达式
on:                         # 触发事件
  push:
    branches: [main]
  pull_request:
    branches: [main]
env:                        # 全局环境变量
  GLOBAL_VAR: value
defaults:                   # 默认行为(可选)
  run:
    shell: bash
    working-directory: ./
jobs:                       # 作业定义
  <job_id>:                 # 唯一标识
    name: <作业显示名>
    runs-on: ubuntu-latest
    env:                    # 作业级环境变量
      JOB_VAR: value
    steps:                  # 步骤列表(顺序执行)
      - name: <步骤名称>
        if: <条件表达式>    # 可选
        uses: <action>@v1  # 或
        run: <shell命令>
        env:               # 步骤级环境变量
          STEP_VAR: value
        continue-on-error: false
        timeout-minutes: 5
关键顺序:on 在 jobs 之前;env 可以在文件级、作业级、步骤级定义,作用域递减;steps 内每个 step 是一个列表项,按顺序执行。

2.2 核心字段详解

字段 位置 用途 必填 典型取值
name 根 工作流显示名称,出现在 Actions Tab 推荐 测试构建与部署
run-name 根 运行时名称,支持表达式动态生成 否 ${{ github.workflow }} - ${{ github.event_name }}
on 根 触发工作流的事件列表 是 push, pull_request, schedule
env 根 / 作业 / 步骤 设置环境变量 否 NODE_ENV: production
jobs 根 定义一组作业,作业之间可并行或依赖 是 至少一个 job
runs-on 作业 指定运行器类型(操作系统) 是 ubuntu-latest, windows-latest
steps 作业 有序步骤列表,每个步骤执行一个 Action 或命令 是 至少一个 step
uses 步骤 引用一个外部 Action 仓库 互斥 actions/checkout@v4
run 步骤 执行内联 shell 命令 互斥 echo "Hello"

注意:uses 和 run 在同一个 step 中只能出现其一,不能同时使用。如果既要运行命令又要引用 Action,必须分两步。

2.3 触发事件 on 的配置模式

on 支持单事件(字符串)、多事件(列表)以及带分支/路径过滤的复杂配置:

on:
  push:                                # 单事件
  pull_request:                        # 多事件,可以组合
    branches: [main, dev]
  schedule:                            # 定时触发
    - cron: '0 */6 * * *'
  workflow_dispatch:                   # 手动触发
    inputs:
      environment:
        description: '部署环境'
        required: true
        default: 'staging'
  repository_dispatch:                 # API 触发
    types: [test-completed]
常见错误:on 后面直接写 push 字符串会导致 YAML 解析为 push 等同于 null,应使用列表或映射。例如 on: push 会被视为无效,正确写法为 on: [push] 或 on: push: 后跟空映射(不推荐)。

2.4 uses 与 run 的互斥与协作

字段 语法 典型场景 版本锁定
uses organization/repo@ref 复用社区 Action(如 checkout、setup-node) 推荐使用 @v4(语义版本)或 @sha(不可变)
run shell 命令字符串 执行自定义脚本、编译、测试命令 无版本概念,在命令中控制工具版本
steps:
  - name: Check out repository
    uses: actions/checkout@v4          # 使用预编译 Action
  - name: Run build script
    run: |
      npm ci
      npm run build
    shell: bash                        # 指定 shell 类型(可选)

2.5 环境变量作用域与优先级

env 可以在三个层级定义,低层级覆盖高层级同名变量:

env:
  LEVEL: global

jobs:
  build:
    env:
      LEVEL: job
    steps:
      - name: Override at step
        env:
          LEVEL: step
        run: echo $LEVEL   # 输出 step
实用技巧:使用 ${{ secrets.MY_SECRET }} 引用密钥,避免明文暴露。全局 env 适合设置通用标志,步骤级 env 适合临时覆盖。

2.6 工作流文件结构流程图

下图展示了工作流文件中各字段的配置顺序与层级关系:

工作流文件字段结构层级图 name on (触发事件) env (全局) defaults (可选) jobs job: build runs-on: ubuntu-latest env (作业级) steps (列表) uses 互斥 run 从上到下书写,缩进表示层级

2.7 常见配置错误及调试方法

  1. 缩进不一致:YAML 要求严格的两个空格缩进,Tab 或混合空格会导致解析失败。建议在本地编辑器安装 YAML 插件。
  2. 缺少 jobs:工作流必须至少包含一个作业。如果漏写 jobs 字段,Actions 会报错:Required property is missing: jobs。
  3. uses 与 run 共存于同一步:运行时会被忽略 run 或抛出歧义错误。应将不同的任务分开:先用 Action,再执行命令。
  4. 事件触发拼写错误:例如将 pull_request 写成 pullrequest。参考 官方事件列表。
  5. 环境变量作用域误解:步骤级变量不会自动传递给后续步骤,除非显式通过 $GITHUB_ENV 或 outputs。
调试技巧:在 Actions 界面点击失败的工作流运行,查看展开的步骤日志;本地可使用 act 工具模拟运行工作流(act -j job_id)。

2.8 性能与稳定性优化建议

  • 固定 Action 版本:使用 @v4 而非 @main,避免上游破坏性更新。
  • 使用 concurrency:防止同一分支多个 push 并发冲突。
  • 减少无用触发:在 on 中使用 paths-ignore 忽略文档或图片修改。
  • 适当拆分 jobs:利用矩阵策略并行化,缩短总运行时间。
  • 缓存依赖:使用 actions/cache 缓存 node_modules、~/.m2 等,减少重复下载。
# 示例:带缓存的 Node.js 构建步骤
- name: Cache Node modules
  uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

- name: Install dependencies
  run: npm ci