触发事件精讲:push、pull_request、workflow_dispatch、schedule、repository_dispatch 及事件过滤

触发事件是 GitHub Actions 流水线的启动器。每次事件发生时,Runner 会检查工作流文件中配置的 on 区块是否匹配当前事件的类型、分支、路径或自定义载荷。本章深入剖析五个核心事件的定义、过滤机制与典型陷阱,帮助你精确控制流水线启动时机,避免冗余构建和无效运行。

3.1 push 事件 — 代码推送触发

当开发者向仓库推送 commit、tag 或删除分支时,push 事件被触发。这是 CI/CD 最常用的基础事件。

参数类型说明
branches数组包含或排除的分支名(支持通配符)
branches-ignore数组排除的分支,优先级高于 branches
tags数组包含或排除的标签名
tags-ignore数组排除的标签
paths数组文件路径 glob 匹配,改变的文件与任意一个匹配则触发
paths-ignore数组排除的文件路径(与 paths 互斥)
仅在主分支和 feature 分支推送时构建示例:
on:
  push:
    branches:
      - main
      - 'feature/**'
    paths-ignore:
      - 'docs/**'
      - '*.md'

3.2 pull_request 事件 — 合并请求触发

当 PR 被创建、同步提交、重新打开或关闭时触发。与 push 不同,pull_request 在合并后的目标分支上运行,因此可使用 github.head_ref 和 github.base_ref 获取分支信息。

活动类型触发时机
openedPR 刚被创建
synchronizePR 分支有新的 commit 推送
reopenedPR 被重新打开
closedPR 被合并或关闭(可结合 github.event.pull_request.merged 判断)

重要陷阱: 若同时配置 push 和 pull_request,同一 commit 推送可能导致流水线被触发两次。建议用 branches-ignore 在 PR 事件中排除目标分支避免重复。

避免双重构建:PR 事件中明确指定 types: [opened, synchronize] 并在 push 事件中限制分支范围。
on:
  pull_request:
    branches: [main]
    types: [opened, synchronize]

3.3 workflow_dispatch 事件 — 手动触发

允许用户在 GitHub Actions 界面或通过 gh CLI 手动启动工作流。可定义 inputs 让用户输入参数。

on:
  workflow_dispatch:
    inputs:
      environment:
        description: '部署环境(staging / production)'
        required: true
        default: 'staging'
      debug:
        description: '启用调试日志'
        type: boolean
        default: false

手动触发时传递的参数通过 ${{ github.event.inputs.environment }} 获取。

触发命令:

gh workflow run .github/workflows/deploy.yml \
  --ref main \
  -f environment=production \
  -f debug=true

3.4 schedule 事件 — 定时调度

使用 POSIX cron 语法定义定时任务,时区固定为 UTC。支持每 5 分钟、每小时、每天等多种周期。

on:
  schedule:
    - cron: '0 */6 * * *'   # 每 6 小时执行一次
    - cron: '30 4 * * 1'    # 每周一 4:30 UTC 执行
由于 GitHub Actions 的调度存在约 30 分钟以内的延迟,不适合对时间精确度要求极高的任务。

3.5 repository_dispatch 事件 — 外部 Webhook 触发

通过 GitHub API 发送自定义事件,传递 event_type 和 client_payload。适用于第三方系统(如 CI、部署平台)触发工作流。

配置工作流:

on:
  repository_dispatch:
    types: [deploy-staging, deploy-production]

触发 API 请求:

curl -X POST \
  -H "Authorization:  YOUR_GITHUB_" \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/OWNER/REPO/dispatches \
  -d '{"event_type":"deploy-staging","client_payload":{"version":"v1.3.2"}}'

3.6 事件过滤进阶

过滤规则支持 包含(branches / tags / paths)和 排除(branches-ignore / tags-ignore / paths-ignore)两类。当同时使用包含与排除时,排除规则优先级更高。

  • 路径过滤:使用 ** 匹配任意级子目录,* 匹配单级,? 匹配单个字符。注意路径过滤基于当前推送中 所有变更文件,只要有一个文件匹配 paths 就触发。
  • 分支/标签过滤:支持 glob 模式,如 release/**、v*。也可使用 !exclude 语法在同一个数组中做排除。
on:
  push:
    branches:
      - '!release/**'   # 先排除 release 分支
      - '**'            # 再包含所有分支
    paths:
      - 'src/**'
      - 'tests/**.py'

3.7 调试与常见错误

  1. 调度事件未触发:检查 cron 表达式是否在 UTC 时区,且仓库有 default 分支。调度事件不会在没有提交记录的仓库中运行。
  2. push 和 pull_request 双重构建:在 pull_request 中使用 branches-ignore: [target_branch] 或在 push 中限制非 PR 分支。
  3. paths-ignore 不生效:确保 paths-ignore 与 paths 互斥,且路径模式正确。若所有变更文件都匹配 paths-ignore,工作流不会被触发。
  4. workflow_dispatch 缺少输入:在 inputs 中 required: true 时,用户必须提供该输入才会显示“Run workflow”按钮。
  5. repository_dispatch 权限不足:需要具有仓库 contents: write 权限的 才能发送调度请求。
将所有触发概念整合为一张流程图:
GitHub Actions 事件触发与过滤流程 事件触发与过滤流程 push pull_request workflow_dispatch schedule repository_dispatch 分支/标签过滤 branches / tags / branches-ignore 路径过滤 paths / paths-ignore 活动类型/自定义输入 types / inputs / event_type 匹配规则成功? 否 启动工作流 jobs 开始执行 跳过 注意 调度事件无分支/路径过滤,可直接触发;repository_dispatch 需匹配 event_type 并验证 。 对于 push 和 pull_request,若所有变更文件均被 paths-ignore 排除,工作流不会被启动。