---
url: /zh/build/trigger-rule.md
---
当 `云原生构建` 接收到各类事件时，会自动从仓库对应分支获取 `.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: # 触发事件，对应一个构建，可以包含多条 Pipeline。即可以是数组，也可以是对象。
    - stages: # 流水线 1
        - echo "do some job"
    - stages: # 流水线 2
        - echo "do some job"
```

### Fork 仓库触发限制

公开仓库允许他人 Fork。出于安全考虑，**Fork 后的仓库在以下类型的事件中，默认不会执行对应的流水线**：

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

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

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

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

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

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

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

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

### 匹配模式

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

#### 常用匹配规则

```yaml title=".cnb.yml"
.push_pipeline: &push_pipeline
  stages:
    - name: do something
      script: echo "do something"

# 匹配以 dev/ 开头的所有分支
"dev/*":
  push:
    - *push_pipeline

# 匹配 main 或 dev 分支
"(main|dev)":
  push:
    - *push_pipeline

# 匹配除 main 和 dev 以外的所有分支
"**/!(main|dev)":
  push:
    - *push_pipeline

# 匹配所有分支
"**":
  push:
    - *push_pipeline

# 兜底，匹配没有 glob 匹配的分支
"$":
  push:
    - *push_pipeline
  tag_push:
    - *push_pipeline
```

### 匹配策略

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

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

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

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

### Git 操作事件

#### Branch 事件

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

| 事件名 | 触发时机 | 说明 |
|--------|---------|------|
| push | 分支推送时触发 | 最常用的触发事件 |
| commit.add | 分支推送包含新提交时触发 | 会额外提供环境变量 `CNB_NEW_COMMITS_COUNT`（新增的 Commits 数量），可结合 `git log -n` 查看新增的 Commits |
| branch.create | 分支创建时触发 | 同时会触发 `push` 事件，若存在新 commit 也会触发 `commit.add` 事件 |
| branch.delete | 分支删除时触发 | 流水线配置可挂靠在分支名或 `$` 上，流水线会使用**默认分支**的配置文件（因为运行时分支已删除） |

**branch.delete 示例**：

```yaml title=".cnb.yml"
dev/1:
  branch.delete:
    - stages:
        - name: echo
          # CNB_BRANCH 值为删除的分支
          script: echo $CNB_BRANCH
$:
  branch.delete:
    - stages:
        - name: echo
          # CNB_BRANCH 值为删除的分支
          script: echo $CNB_BRANCH
```

#### Pull Request 事件

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

| 事件名 | 触发时机 |
|--------|---------|
| pull\_request | PR 创建、重新打开、源分支 push |
| pull\_request.update | PR 创建、重新打开、源分支 push、PR 的 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 评论创建时触发 |

::: 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 的目标分支配置了该事件流水线，触发该事件时才会有对应流水线执行
  :::

::: 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 时触发 | 仅支持在仓库的 Tag 列表页面点击「自动生成 Tag」按钮触发 |
| tag\_deploy.\* | 在仓库 Tag/Release 页面通过「部署」按钮触发 | 详情参考[部署](./deploy.md) |

**tag\_push 示例**：

```yaml title=".cnb.yml"
# 对指定 tag 生效
v1.0.*:
  tag_push:
    - stages:
        - name: echo tag name
          script: echo  $CNB_BRANCH

# 对所有 tag 生效
$:
  tag_push:
    - stages:
        - name: echo tag name
          script: echo  $CNB_BRANCH
```

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

**触发方式**：仅支持在仓库的 Tag 列表页面，点击「自动生成 Tag」按钮触发。

**实现原理**：启动一个流水线，默认使用 [cnbcool/git-auto-tag](../../plugin/#public/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
          # 该环境变量在触发构建时传入，可查看打印内容看 release 规则
          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
    - 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) |
| cnb:trigger | 参考 [cnb:trigger](./internal-steps/#cnb-trigger) |
| OPENAPI | 参考 OPENAPI |

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

***

### 定时任务事件

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

***

### Issue 事件

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

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

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

***

### NPC 事件

在以下场景中于描述或评论中提及 `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、pull\_request.update、pull\_request.approved、pull\_request.changes\_requested、pull\_request.comment | 预合并后的 Commit |
| pull\_request.merged | 合并后的 Commit |
| pull\_request.target、pull\_request.mergeable | 合并前目标分支最新 Commit |
| api\_trigger | 可指定版本；[cnb:apply](./internal-steps/#cnb-apply) 限制为当前构建的 Commit |
| web\_trigger | 从对应分支、Tag 读取配置文件，参考具体应用场景 |
| 定时任务 | 指定分支的最新 Commit |
| 重新构建 | 当前构建的 Commit |

## 不可信事件 {#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.comment`：Issue 评论
* `issue.comment@npc`：Issue 的描述或评论中 `@npc` 时触发

### 风险场景

**PR 类事件**：

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

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

**评论类事件**：

触发者为评论者，可能非仓库成员或管理员：

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

**NPC 事件**：

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

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

### 安全措施

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

| 安全措施 | 说明 |
|---------|------|
| CNB\_TOKEN 权限限制 | 流水线环境变量中内置的 [CNB\_TOKEN](./build-in-env.md#cnb_token) 权限受到严格限制，防止越权访问 |
| 文件引用显式声明 | 不可信事件的流水线引用外部文件时，被引用文件必须通过 `allow_events` 显式声明允许被哪些事件引用，避免敏感文件被意外引用 |

### 使用建议

::: tip 安全建议

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