---
url: /zh/build/trigger-rule.md
description: |
  介绍云原生构建的触发机制，包括 Git 操作事件、页面操作事件、API 请求、定时任务、 Issue 事件和 NPC 事件等多种触发方式及其配置说明。
---
当 `云原生构建` 接收到各类事件时，自动从仓库对应分支获取 `.cnb.yml`，
解析该分支下对应事件的流水线配置，并分配 Runner 执行。

## 触发机制概述

`云原生构建` 支持多种事件触发方式，主要包括：

| 事件类型       | 说明                                       |
|----------------|--------------------------------------------|
| Git 操作事件   | 代码推送、分支创建、PR 操作等              |
| 页面操作事件   | 手动触发、按钮点击、AI 功能操作等          |
| API 请求事件   | 通过 OPENAPI 或内置任务触发                |
| 定时任务事件   | 按预定时间计划触发                         |
| Issue 事件     | Issue 操作、评论等                         |
| NPC 事件       | Issue、PR 的描述或评论中 `@npc` 时触发     |

### 触发流程示例

以 main 分支代码 `push` 事件为例，触发流程如下：

```mermaid
flowchart LR
    push(git push) --> config(读取main分支下 .cnb.yml) --> event(获取main分支下 push 配置)  --> checkout(checkout main分支代码) --> 流水线执行
```

代码示例：

```yaml title=".cnb.yml"
main:
  push:
    - stages: # 同一个任务内可定义多个 stage，按顺序串行执行
        - name: job 1
          script: echo "do some job"
        - name: job 2
          script: echo "do some job"
```

### Fork 仓库触发限制

**Fork 后的仓库在以下事件中默认不执行流水线**：

* Git 操作事件
* 定时任务事件
* Issue 事件

#### 启用 Fork 仓库自动触发

如需允许这些事件触发流水线，可在仓库页面依次进入
**`设置` → `云原生构建`**，勾选以下选项：

* **允许自动触发**：选中后，仓库按 .cnb.yml 配置自动触发云原生构建
* **Fork 的仓库默认允许自动触发**：选中后，由本仓 Fork 出来的仓库将按照 .cnb.yml 配置自动触发云原生构建

> **安全提示**：Fork 后的仓库在执行流水线时，
> 其默认环境变量 `CNB_TOKEN` 的权限范围仅限于 **当前仓库**，以确保安全性。

## 触发分支 {#trigger-branch}

触发分支指代码仓库中触发事件的分支，用于匹配对应的流水线配置。

::: warning 重要提示
在某分支下配置其他分支的流水线，其他分支的事件并不会按此配置执行。
实际执行取决于各分支自身 `.cnb.yml` 文件的配置。
:::

### 匹配模式

分支名称支持 `glob` 模式匹配（[了解 glob 匹配](https://globster.xyz/)）。

::: tip glob 匹配规则

* `*` 匹配任意字符，但**不匹配** `/`。
  例如 `dev/*` 可匹配 `dev/feature` 但不能匹配 `dev/team/feature`。
* `**` 匹配任意字符，**包括** `/`。
  例如 `dev/**` 可匹配 `dev/feature` 和 `dev/team/feature`。

如果分支名包含多级 `/`，请使用 `**`。
:::

#### 常用匹配规则

以下分别展示四种常用匹配模式，各模式可组合在同一 `.cnb.yml` 中：

**匹配以 `dev/` 开头的分支：**

```yaml title=".cnb.yml"
"dev/*":
  push:
    - stages:
        - name: do something
          script: echo "dev branch"
```

**匹配 `main` 或 `dev` 分支：**

```yaml title=".cnb.yml"
"(main|dev)":
  push:
    - stages:
        - name: do something
          script: echo "main or dev"
```

**排除 `main` 和 `dev`：**

```yaml title=".cnb.yml"
"**/!(main|dev)":
  push:
    - stages:
        - name: do something
          script: echo "not main or dev"
```

**匹配所有分支（含兜底 `$`）：**

```yaml title=".cnb.yml"
"**":
  push:
    - stages:
        - name: do something
          script: echo "all branches"
$:
  push:
    - stages:
        - name: do something
          script: echo "fallback"
```

| 模式                | 匹配范围                             |
|---------------------|--------------------------------------|
| `dev/*`             | 以 `dev/` 开头的分支（不含多级 `/`） |
| `(main\|dev)`       | `main` 或 `dev` 分支                 |
| `**/!(main\|dev)`   | 除 `main` 和 `dev` 外的所有分支      |
| `**`                | 所有分支                             |
| `$`                 | 兜底匹配，不被 glob 匹配的分支       |

### 匹配策略

系统分阶段按优先级进行分支匹配，只有前一阶段未匹配时才会进入下一阶段：

| 优先级 | 匹配阶段      | 说明                                  |
|--------|---------------|---------------------------------------|
| 1      | glob 模式匹配 | 尝试用所有 glob 规则匹配分支名        |
| 2      | 兜底匹配      | 使用 `$` 规则匹配未被 glob 匹配的分支 |

> **并行执行**：多个 glob 规则同时匹配时，所有匹配规则的流水线将**并行执行**。

## 触发事件 {#trigger-event}

### Git 操作事件

#### Branch 事件

由远端代码分支变动触发的事件。

| 事件名           | 触发时机             | 说明                                                     |
|------------------|----------------------|----------------------------------------------------------|
| push             | 分支推送时触发       | 最常用的触发事件                                         |
| commit.add       | 分支推送包含新提交时 | 额外提供 `CNB_NEW_COMMITS_COUNT`                         |
| branch.create    | 分支创建时触发       | 同时触发 `push`；有新 commit 时也触发 `commit.add`       |
| branch.delete    | 分支删除时触发       | 使用**默认分支**的最新代码和配置                         |

**branch 事件补充说明**：

* **commit.add**：提供 `CNB_NEW_COMMITS_COUNT`（新增 Commit 数），可结合 `git log -n` 查看新增 Commit
* **branch.create**：创建分支时会同时触发 `push` 事件；
  若推送包含新 commit，也会触发 `commit.add` 事件
* **branch.delete**：流水线使用**默认分支**的最新代码版本和配置文件
  （因为运行时分支已被删除）

**branch.delete 与 tag\_push 匹配规则一致**：均支持精确名称、glob 模式和 `$` 兜底匹配。
`branch.delete` 的示例如下，Tag 事件（`tag_push`）的示例见下文 [Tag 事件](#tag-事件)。

```yaml title=".cnb.yml"
# 精确匹配
main:
  branch.delete:
    - stages:
        - name: echo
          script: echo $CNB_BRANCH
# 兜底匹配
$:
  branch.delete:
    - stages:
        - name: echo
          script: echo $CNB_BRANCH
```

#### Pull Request 事件

由 Pull Request（以下简称 PR）相关操作触发的事件。

| 事件名                            | 触发时机                                                  |
|-----------------------------------|-----------------------------------------------------------|
| pull\_request                      | PR 创建、重新打开、源分支 push                            |
| pull\_request.update               | PR 创建、重新打开、源分支 push、title 或 description 修改 |
| pull\_request.target               | PR 创建、重新打开、源分支 push                            |
| pull\_request.mergeable            | 开启中的 PR 满足特定条件时触发                            |
| pull\_request.merged               | PR 合并完成时触发                                         |
| pull\_request.approved             | 用户评审 PR「允许合并」时触发                             |
| pull\_request.changes\_requested    | 用户评审 PR「需要改进」时触发                             |
| pull\_request.comment              | PR 评论创建时触发                                         |

**pull\_request.update 补充说明**：在 `pull_request` 的基础上，
PR 的 title 或 description 修改也会触发该事件。

::: tip pull\_request 与 pull\_request.update 的区别
`pull_request` 是 `pull_request.update` 的子集：

* PR 的 title、description 修改 → 触发 `pull_request.update`，但不触发 `pull_request`
* PR 创建、重新打开、源分支 push → 同时触发 `pull_request` 和 `pull_request.update`
  :::

::: tip pull\_request 与 pull\_request.target 的区别
详细区别请参考 [代码版本选择](#代码版本选择)。
:::

#### pull\_request.mergeable 触发条件

开启中的 PR 同时满足以下条件时触发：

1. 目标分支为 **保护分支**，并勾选以下规则：
   * 需要评审人批准
   * 需要通过状态检查（可选）

2. 可合并：
   * 无代码冲突
   * 状态检查通过（如勾选需要通过状态检查，且有状态检查）

3. 评审通过

::: warning pull\_request.mergeable 注意事项

* 配置文件取自目标分支，参考 [代码版本选择](#代码版本选择)
* PR 的目标分支配置了该事件流水线，触发该事件时才会有对应流水线执行
* CI 文件解析失败时，若目标分支是保护分支且开启了状态检查，会自动上报失败状态阻止合并；非保护分支不上报
  :::

::: warning pull\_request.merged 注意事项
a 分支合并到 b 分支，会触发 b 分支下的 `pull_request.merged`、`push` 事件。
:::

::: warning pull\_request.approved 注意事项
保护分支可能设置了多个评审人批准的要求，仅有一位用户通过评审不代表 PR 已处于评审通过状态。
:::

#### Tag 事件

由远端代码和页面 Tag 相关操作触发的事件。

| 事件名          | 触发时机               | 说明                                |
|-----------------|------------------------|-------------------------------------|
| tag\_push        | Tag push 时触发        | 用于 Tag 推送后的自动化处理         |
| auto\_tag        | 自动生成 Tag 时触发    | 见下方「auto\_tag 自动生成 Tag」说明 |
| tag\_deploy.\*    | 通过「部署」按钮触发   | 详情参考 [部署](./deploy.md)         |

**tag\_push**：Tag 推送时触发，支持精确 Tag 名、glob 模式和 `$` 兜底匹配。配置结构如下：

```yaml title=".cnb.yml"
# 精确匹配
v1.0.0:
  tag_push:
    - stages:
        - name: echo
          script: echo $CNB_BRANCH
# glob 模式匹配
v*:
  tag_push:
    - stages:
        - name: echo
          script: echo $CNB_BRANCH
# 兜底匹配
$:
  tag_push:
    - stages:
        - name: echo
          script: echo $CNB_BRANCH
```

#### auto\_tag 自动生成 Tag {#auto\_tag}

**触发方式**：仅支持在仓库的 Tag 列表页面，点击「自动生成 Tag」按钮触发。
按钮会以 `tag.auto_tag.branch` 指定的分支（默认仓库默认分支）启动流水线，
该分支可通过 [Tag 自动生成配置](../repo/settings-tag.md)
在 `.cnb/settings.yml` 中配置。

**实现原理**：启动一个流水线，
默认使用 [cnbcool/git-auto-tag](https://cnb.cool/cnb/plugins/cnbcool/git-auto-tag)
插件实现自动生成 Tag。

**Tag 格式说明**：

* 默认格式为 `3.8.11` 类型
* 如果最新一个 Tag 以 `v` 开头，则自动生成的 Tag 也会带上 `v`，如 `v4.1.9`

**自定义配置**：

```yaml title=".cnb.yml"
main:
  auto_tag:
    - stages:
        - name: release rules
          script: echo -e "$RELEASE_RULES"
        - name: auto tag
          image: cnbcool/git-auto-tag:latest
          settings:
            tagFormat: 'v\${version}'
            branch: $CNB_BRANCH
            repoUrlHttps: $CNB_REPO_URL_HTTPS
            releaseRules: $RELEASE_RULES
          exports:
            tag: NEW_TAG
        # exports 的生命周期为当前 Pipeline，需在同一 Pipeline 的后续 stage 中使用
        - name: show tag
          script: echo $NEW_TAG
```

::: warning 配置覆盖规则
默认配置会与 .cnb.yml 合并，同一分支名下，后出现的配置会覆盖前面的配置。
如果 `.cnb.yml` 中 `auto_tag` 配置在 `$` 下而不是默认分支名下，
两边的 `auto_tag` 配置都会保留，但
`$` 下的配置会被忽略。参考 [include 合并规则](./configuration.md#合并规则)。
:::

***

### 页面操作事件

#### web\_trigger 自定义事件 {#web\_trigger}

**事件名格式**：`web_trigger` 或 `web_trigger_` 开头，如 `web_trigger_test`。

**触发方式**：仅支持在页面触发事件。

**使用场景**：

| 场景         | 说明                                              |
|--------------|---------------------------------------------------|
| 部署能力     | 结合 [部署](./deploy.md)能力使用                   |
| 自定义按钮   | 页面中的 [自定义按钮](./web-trigger.md)            |
| 手动触发构建 | 支持输入环境变量（仅支持触发 `web_trigger` 事件） |

#### 云原生开发事件 {#vscode}

在页面点击「云原生开发」按钮触发的事件。详情参考 [云原生开发](../workspaces/intro.md)。

***

### API 请求事件

#### api\_trigger 自定义事件 {#api\_trigger}

**事件名格式**：`api_trigger` 或以 `api_trigger_` 开头，如 `api_trigger_test`。

**触发方式**：

| 触发来源        | 说明                                                    |
|-----------------|---------------------------------------------------------|
| cnb:apply       | 参考 [cnb:apply](./internal-steps/cnb/apply.md)           |
| cnb:trigger     | 参考 [cnb:trigger](./internal-steps/cnb/trigger.md)       |
| OPENAPI         | 参考 [OPENAPI](https://api.cnbprod.alpha.qq.com/#/operations/StartBuild) |

::: tip 提示
方式 1 和 2 是对方式 3 的封装。
:::

***

### 定时任务事件

由定时任务触发的事件。详情参考 [定时任务](./crontab.md)。

***

### Issue 事件

由 Issue 的相关操作触发的事件。

::: warning 配置要求
Issue 事件流水线配置需挂靠在 `$` 下。
:::

| 事件名                          | 触发时机                               |
|---------------------------------|----------------------------------------|
| issue.open                      | Issue 创建时                           |
| issue.close                     | Issue 关闭时                           |
| issue.reopen                    | Issue 重新打开时                       |
| issue.update                    | 名称、描述、处理人、标签、优先级变更时 |
| issue.update.assignee\_change    | Issue 处理人变更时                     |
| issue.update.priority\_change    | Issue 优先级变更时                     |
| issue.update.label\_change       | Issue 标签变更时                       |
| issue.comment                   | Issue 评论时                           |

以下示例将 `issue.open`、`issue.comment` 流水线挂靠在 `$` 下，
分别在 Issue 创建、评论时执行任务：

```yaml title=".cnb.yml"
$:
  issue.open:
    - stages:
        - name: notice issue
          script: echo "$CNB_ISSUE_TITLE" opened
  issue.comment:
    - stages:
        - name: notice issue
          script: echo "$CNB_ISSUE_TITLE" commented
```

其余事件（如 `issue.close`、`issue.update` 等）写法相同，仅需替换事件名。
更完整的通知示例（如 Issue 变更时推送企业微信群）参考 [Issue 通知示例](./showcase/issue-notice-group.md)。

:::: warning 评论数限制
当 Issue 或 PR 的评论数超过 100 条时，对应的 `issue.comment` /
`pull_request.comment` 及 `@npc` 事件均不再触发流水线。
::::

***

### NPC 事件 {#trigger-npc-scenes}

在以下场景中于描述或评论中提及 `NPC` 角色（如 `@npc`），将触发 `NPC` 事件：

| 场景              | 触发事件                       |
|-------------------|--------------------------------|
| 创建 Issue 的描述 | `issue.comment@npc`            |
| Issue 评论        | `issue.comment@npc`            |
| 创建 PR 的描述    | `pull_request.comment@npc`     |
| PR 评审           | `pull_request.comment@npc`     |
| PR 评论           | `pull_request.comment@npc`     |
| PR 评审评论       | `pull_request.comment@npc`     |

更多信息参考 [NPC 文档](./npc.md)

## 代码版本选择

事件触发时需要确定对应的代码版本，
获取、解析对应的 `.cnb.yml`，checkout 代码执行流水线。

### 版本选择策略

| 事件类型                                       | 代码版本选择                          |
|------------------------------------------------|---------------------------------------|
| push、commit.add、branch.create、vscode        | 当前分支最新 Commit                   |
| auto\_tag、branch.delete、issue.\*               | 默认分支最新 Commit                   |
| tag\_push、tag\_deploy.\*                         | 当前 Tag                              |
| pull\_request                                   | 预合并后的 Commit                     |
| pull\_request.update                            | 预合并后的 Commit                     |
| pull\_request.approved                          | 预合并后的 Commit                     |
| pull\_request.changes\_requested                 | 预合并后的 Commit                     |
| pull\_request.comment                           | 预合并后的 Commit（见说明 3）         |
| pull\_request.comment@npc                       | 目标分支最新 Commit（见说明 4）       |
| issue.comment@npc                              | 默认分支最新 Commit                   |
| pull\_request.merged                            | 合并后的 Commit                       |
| pull\_request.target、pull\_request.mergeable    | 合并前目标分支最新 Commit             |
| api\_trigger                                    | 可指定版本（见说明 1）                |
| web\_trigger                                    | 从对应分支或 Tag 读取配置（见说明 2） |
| 定时任务                                       | 指定分支的最新 Commit                 |
| 重新构建                                       | 当前构建的 Commit                     |

**补充说明**：

1. **api\_trigger**：可指定版本；`cnb:apply` 限制为当前构建的 Commit
2. **web\_trigger**：从对应分支、Tag 读取配置文件，参考具体应用场景
3. **pull\_request.comment**：PR 已合并时使用合并后的 Commit（源分支可能已删除，不做预合并）
4. **pull\_request.comment@npc**：
   * 跨仓 Fork PR 且触发者为 PR 提交者：使用源仓库源分支代码
   * PR 已合并：使用合并后的 Commit（源分支可能已删除），
     可配合 `git cherry-pick` 把提交同步到其他分支

## 不可信事件 {#untrusted-events}

不可信事件是指代码来源或触发者不可控的事件类型。

### 事件列表

以下事件为不可信事件：

**Pull Request 相关事件**：

* `pull_request`：PR 创建或源分支 push
* `pull_request.update`：PR 内容更新（含 title、description 修改）
* `pull_request.approved`：PR 审批通过
* `pull_request.changes_requested`：PR 审批被拒绝
* `pull_request.comment`：PR 评论
* `pull_request.comment@npc`：PR 的描述或评论中 `@npc` 时触发

**Issue 相关事件**：

* `issue.open`：Issue 创建
* `issue.reopen`：Issue 重新打开
* `issue.close`：Issue 关闭
* `issue.update`：Issue 内容更新（含 title、description 修改）
* `issue.update.assignee_change`：Issue 处理人变更
* `issue.update.priority_change`：Issue 优先级变更
* `issue.update.label_change`：Issue 标签变更
* `issue.comment`：Issue 评论
* `issue.comment@npc`：Issue 的描述或评论中 `@npc` 时触发

### 风险场景

**PR 类事件**：

流水线配置源自源分支，可能被未授权用户修改，存在以下风险：

* 恶意代码注入或敏感内容泄漏
* 构建产物（如镜像、二进制文件）被篡改
* 引用密钥仓库文件导致密钥或凭证泄漏

**Issue、评论类事件**：

Issue 的创建、关闭/重新打开、编辑与评论均无需仓库写权限，触发者可能非仓库成员或管理员：

* 访问触发者资源导致数据泄漏
* 篡改触发者资源造成破坏

**NPC 事件**：

流水线可由 `NPC` 所属仓库提供，且触发者为评论者，风险叠加：

* `NPC` 配置来源不可控，可能被恶意篡改
* 评论者资源泄漏和篡改风险同时存在

### 安全措施

为降低上述风险，系统对不可信事件采取以下防护措施：

* **CNB\_TOKEN 权限限制**：流水线环境变量中内置的 [CNB\_TOKEN](./build-in-env.md#cnb_token) 权限受到严格限制，防止越权访问
* **CNB\_TOKEN 角色封顶**：非 NPC 的不可信事件下，[CNB\_TOKEN](./build-in-env.md#cnb_token) 的最大角色固定为 `Reporter`（助手），
  触发者角色更高时同样按助手计算
* **文件引用显式声明**：不可信事件的流水线引用外部文件时，被引用文件必须通过 `allow_events` 显式声明允许被哪些事件引用，
  避免敏感文件被意外引用

### 使用建议

::: tip 安全建议

* **选择可信 `NPC`**：评论时优先选择可信仓库提供的 `NPC` 角色
* **敏感任务隔离**：涉及密钥操作、敏感数据处理等重要内容的任务，
  建议在 push、pull\_request.target、tag\_push 等可信事件中执行
  :::
