---
url: /zh/build/deploy.md
---
云原生构建支持自定义部署流程，通过自定义部署环境、审批流程、部署流水线，实现自动化的部署流程。

操作示例：

![](/images/build/deploy-intro.zh.png)

## 自定义部署环境

在仓库根目录下添加 `.cnb/tag_deploy.yml` 文件用于配置部署环境。
如下示例中定义了 `development`、`staging`、`production` 三种环境，用户可在页面上选择需要部署的环境类型。

```yaml title=".cnb/tag_deploy.yml"
environments:
  # name: 环境名，点击该环境对应的部署按钮将触发 .cnb.yml 中的 tag_deploy.development 事件流水线
  - name: development
    description: Development environment
    # 环境变量（触发流水线时，会将环境变量传入流水线，包括部署流水线、web_trigger 流水线）
    env:
      name: development
      # CNB_BRANCH: 环境变量，部署事件中，为 tag 名
      tag_name: $CNB_BRANCH
    # 部署按钮权限控制
    # 不配置：有仓库写权限和 tag_push 权限的用户可点击部署按钮
    # 配置：有仓库写权限，且满足 roles 或 users 其中之一才有权限点击部署按钮
    permissions:
      # roles 和 users 配置其中之一或都配置均可，二者满足其一即可
      # 角色非向上包含关系。例如如下配置，表示仅 master 或 developer 角色才有权限，owner 即使仓库权限更高，但此处无权限
      roles:
        - master
        - developer
      users:
        - name1
        - name2
  - name: staging
    description: Staging environment
    # 自定义触发的部署流水线标题
    # title: 部署预发布环境
    env:
      name: staging
      # CNB_BRANCH: 环境变量，部署事件中，为 tag 名
      tag_name: $CNB_BRANCH

  - name: production
    description: Production environment
    # 环境变量（触发流水线时，会将环境变量传入流水线，包括部署流水线、web_trigger 流水线）
    env:
      name: production
      # CNB_BRANCH: 环境变量，部署事件中，为 tag 名
      tag_name: $CNB_BRANCH
    button:
      - name: 按钮名1
        # 如存在，则将作为流水线 title，否则流水线使用默认 title；可支持环境变量替换（仅支持替换一级，环境变量指的是当前配置的 env 和 inputs。仅支持 ${xxx} 写法。）
        description: 按钮描述
        # 触发的 CI 事件名，需要在 .cnb.yml 中配置
        event: web_trigger_one
        # 是否默认按钮
        isDefault: false
        # 权限控制，不配置则有仓库写权限的用户可触发构建
        # 如果配置，则需要有仓库写权限，并且满足 roles 或 users 其中之一才有权限触发构建
        # 注意：仅支持在页面检查 permissions 权限
        permissions:
          # roles 和 users 配置其中之一或都配置均可，二者满足其一即可
          # 角色非向上包含关系。例如如下配置，表示仅 master 或 developer 角色才有权限，owner 即使仓库权限更高，但此处无权限
          roles:
            - master
            - developer
          users:
            - name1
            - name2
        # 环境变量
        env:
          # 默认传入的环境变量，其中 key 值（a,b,c）为环境变量名，支持如下两种格式
          a: 1
          b: 2
          c:
            # 环境变量别名
            name: 变量c
            # 环境变量值
            value: 3
        # 可输入环境变量，可覆盖上述 env 的变量配置
        inputs:
          # 目前支持以下三种格式：输入框（input）、多行文本输入框（textarea）、下拉选择框（select 支持单选和多选），switch 开关（switch），radio 单选框（radio）
          # 其中 key 值（var1、var2、var3、var4、var5、var6）为环境变量名
          # inputs 也支持分组，见下方按钮二 inputs 配置
          var1:
            # 输入框
            name: 变量1
            description: 变量1描述
            placeholder: 请输入变量1
            required: true # 是否必填
            type: input
            default: 默认值1
          var2:
            # 输入框
            name: 变量2
            description: 变量2描述
            placeholder: 请输入变量2
            required: true
            type: textarea
            default: 默认值2
          var3:
            # 单选下拉选择框
            name: 变量3
            description: 变量3描述
            placeholder: 请选择变量3
            required: false
            type: select
            default: value1
            options:
              - name: 选项1
                value: value1
                description: 选项1描述
              - name: 选项2
                value: value2
                description: 选项2描述
          var4:
            # 多选下拉选择框
            name: 变量4
            description: 变量4描述
            placeholder: 请选择变量4
            required: false
            type: select
            # 是否支持多选，多选结果用分号分隔
            multiple: true
            default: value1,value2
            options:
              - name: 选项1
                value: value1
                description: 选项1描述
              - name: 选项2
                value: value2
                description: 选项2描述
              - name: 选项3
                value: value3
                description: 选项3描述
          var5:
            # switch 开关
            name: 变量5
            description: 变量5描述
            required: false
            type: switch
            default: value1
            options:
              - name: 选项1
                value: value1
                description: 选项1描述
              - name: 选项2
                value: value2
                description: 选项2描述
          var6:
            # radio 单选框
            name: 变量6
            description: 选择变量6
            required: false
            type: radio
            default: value1
            options:
              - name: 选项1
                value: value1
                description: 选项1描述
              - name: 选项2
                value: value2
                description: 选项2描述
      - name: 按钮名2
        description: 按钮描述
        event: web_trigger_two
        inputs:
          # inputs 支持分组，如下所示，用数组格式，每个数组元素代表一个分组。
          # 分组仅在页面显示上有区别，不影响实际的环境变量传入
          - name: 分组一
            inputs:
              # 目前支持以下三种格式：输入框（input）、多行文本输入框（textarea）、下拉选择框（select 支持单选和多选），switch 开关（switch），radio 单选框（radio）
              # 其中 key 值（var1、var2、var3、var4、var5、var6）为环境变量名
              var1:
                # 输入框
                name: 变量1
                description: 变量1描述
                placeholder: 请输入变量1
                required: true # 是否必填
                type: input
                default: 默认值1
              var2:
                # 输入框
                name: 变量2
                description: 变量2描述
                placeholder: 请输入变量2
                required: true
                type: textarea
                default: 默认值2
              var3:
                # 单选下拉选择框
                name: 变量3
                description: 变量3描述
                placeholder: 请选择变量3
                required: false
                type: select
                default: value1
                options:
                  - name: 选项1
                    value: value1
                    description: 选项1描述
                  - name: 选项2
                    value: value2
                    description: 选项2描述
          - name: 分组二
            inputs:
              var4:
                # 多选下拉选择框
                name: 变量4
                description: 变量4描述
                placeholder: 请选择变量4
                required: false
                type: select
                # 是否支持多选，多选结果用分号分隔
                multiple: true
                default: value1,value2
                options:
                  - name: 选项1
                    value: value1
                    description: 选项1描述
                  - name: 选项2
                    value: value2
                    description: 选项2描述
                  - name: 选项3
                    value: value3
                    description: 选项3描述
              var5:
                # switch 开关
                name: 变量5
                description: 变量5描述
                required: false
                type: switch
                default: value1
                options:
                  - name: 选项1
                    value: value1
                    description: 选项1描述
                  - name: 选项2
                    value: value2
                    description: 选项2描述
          - name: 分组三
            inputs:
              var6:
                # radio 单选框
                name: 变量6
                description: 选择变量6
                required: false
                type: radio
                default: value1
                options:
                  - name: 选项1
                    value: value1
                    description: 选项1描述
                  - name: 选项2
                    value: value2
                    description: 选项2描述

    # 部署前置条件检查（支持对环境、元数据、审批流程的检查），满足所有前置条件才可进行部署操作
    require:
      # 1 对部署环境是否满足要求的检查

      # 1.1 要求 development 环境部署成功
      - environmentName: development

      # 1.2 要求 staging 环境部署成功 30 分钟后
      - environmentName: staging
        after: 1800

      # 2 对元数据是否满足要求的检查

      # 2.1 键值 key1 对应的 value 不为空，即有值
      - annotation: key1

      # 2.2 键值 key1 对应的 value 值需等于 value1
      - annotation: key1
        expect:
          eq: value1

      # 2.3 键值 key2 对应的 value 值需大于 1 且小于 10
      - annotation: key2
        expect:
          and:
            gt: 1
            lt: 10
        # 自定义按钮，点击可触发执行 web_trigger_annotation 事件。
        # 可定义与 require 信息有关的按钮事件，当 require 满足条件后隐藏按钮
        button:
          - name: 生成元数据
            event: web_trigger_annotation
            # 如存在，则将作为流水线 title，否则流水线使用默认 title；可支持环境变量替换（仅支持替换一级，环境变量指的是当前配置的 env 和 inputs。仅支持 ${xxx} 写法。）
            description: 生成元数据流程
            # 权限控制，不配置则有仓库写权限的用户可触发构建
            # 如果配置，则需要有仓库写权限，并且满足 roles 或 users 其中之一才有权限触发构建
            # 注意：仅支持在页面检查 permissions 权限
            permissions:
              # roles 和 users 配置其中之一或都配置均可，二者满足其一即可
              # 角色非向上包含关系。例如如下配置，表示仅 master 或 developer 角色才有权限，owner 即使仓库权限更高，但此处无权限
              roles:
                - master
                - developer
              users:
                - name1
                - name2
            # 传给 web_trigger_annotation 事件流水线的环境变量
            # 可继承上一级别环境变量，优先级高于上一级别环境变量
            env:
              name1: value1
              name2: value2

      # 3 对审批流程是否满足要求的检查（可按以下方式自定义审批流程）
      # - 审批顺序：如下 1、2、3 审批流程需按顺序进行，即 1 审批通过，2 才能进行审批。1、2、3 审批流程全部通过才算通过审批
      # - 审批操作：包括 同意、拒绝。一人同意即算通过。如果拒绝，其他审批人无法再操作，直到拒绝的审批人再修改审批结果为同意

      # 3.1 按用户名审批，其中一人审批通过即可
      - approver:
          users:
            - user1
            - user2
            - user3
        # 可配置点击同意按钮触发的事件，以及传给事件流水线的环境变量
        # agreeEvent:
        #   # 描述信息，会作为流水线 title
        #   description: 同意审批
        #   # 点击同意按钮时触发的事件名，仅支持 web_trigger 事件
        #   event: web_trigger_agree
        #   # 传给事件流水线的环境变量，不支持继承上一级别的环境变量
        #   env:
        #     name1: value1
        #     name2: value2
        # 可配置点击拒绝按钮触发的事件，以及传给事件流水线的环境变量
        # rejectEvent:
        #   # 描述信息，会作为流水线 title
        #   description: 拒绝审批
        #   # 点击拒绝按钮时触发的事件名，仅支持 web_trigger 事件
        #   event: web_trigger_reject
        #   # 传给事件流水线的环境变量，不支持继承上一级别的环境变量
        #   env:
        #     name1: value1
        #     name2: value2
        title: 测试审批

      # 3.2 按角色审批，其中一人审批通过即可
      - approver:
          roles:
            - developer
            - master
        title: 开发审批

      # 3.3 按用户名或角色审批（审批人满足 users 或 roles 其一即可），其中一人审批通过才行
      - approver:
          users:
            - user4
            - user5
          roles:
            - master
            - owner
        title: 运维审批

    # 自定义部署按钮（缺省值：默认展示一个部署按钮）
    # 使用场景：有多个不同模块（例如仓库、CI、制品库等），需要分开独立部署时，可以配置多个不同的按钮
    # 注意：部署流水线中要区分是哪个模块，可以通过传入流水线的环境变量来区分
    deploy:
      - name: 部署按钮名1
        description: 部署按钮描述
        # 环境变量（触发部署流水线时，会将环境变量传入流水线），优先级高于上一级 env
        env:
          name1: value1
          name2: value2
      - name: 部署按钮名2
        description: 部署按钮描述
        # 环境变量（触发部署流水线时，会将环境变量传入流水线），优先级高于上一级 env
        env:
          name1: value1
          name2: value2
```

* `name`: 必填，环境名，需唯一。例如 `name: development`，点击该环境对应的部署按钮，将触发 `.cnb.yml` 中的 `tag_deploy.development` 事件流水线

* `description`: 选填，环境描述

* `title`: 选填，自定义触发的部署流水线标题

* `env`: 选填，传给部署流水线的环境变量。用户可根据需要传入需要的环境变量。

* `permissions`: 选填，部署权限控制，满足 `users` 或 `roles` 其中之一即有权限部署（还需要有仓库写权限）。如果未配置 `permissions`，则有仓库写权限和推送 Tag 权限即可触发构建
  * `users`: 选填，`Array<String>`，用户名数组。可定义多个。
  * `roles`: 选填，`Array<String>`，仓库角色数组。可定义多种仓库角色：
    `owner`(负责人)、`master`(管理员Administrator)、`developer`(开发者)、`reporter`(助手)、`guest`(访客)。角色非向上包含关系，例如仅声明了 `master` 有权限，`owner` 即使仓库权限更高，在此处也没有权限

* `button`: 选填，对象数组格式，自定义按钮。点击按钮可触发云原生构建流水线，执行参数 event 对应的事件。

  * `name`: 必填，按钮名。
  * `description`: 选填，按钮描述。如存在，则将作为流水线 title，否则流水线使用默认 title；可支持环境变量替换（仅支持替换一级，环境变量指的是当前配置的 env 和 inputs。仅支持 ${xxx} 写法。）。
  * `event`: 必填，自定义事件，仅支持 web\_trigger 事件。
  * `isDefault`: 选填，`Boolean`，是否是默认按钮，仅支持设置一个默认按钮（设置多个取第一个）。如果设置了默认按钮，点击按钮直接出现默认按钮触发构建弹框。未设置默认按钮，则点击按钮弹出包含所有自定义按钮的弹出层。
  * `env`: 选填，传给 web\_trigger 流水线的环境变量，可继承上一级别环境变量，优先级高于上一级别环境变量。
  * `permissions`: 选填，权限控制，满足 `users` 或 `roles` 其中之一即有权限触发构建（还需要有仓库写权限）。如果未配置 `permissions`，则有仓库写权限即可触发构建。注意：仅支持在页面检查 permissions 权限
    * `users`: 选填，`Array<String>`，用户名数组。可定义多个。
    * `roles`: 选填，`Array<String>`，仓库角色数组。可定义多种仓库角色：
      `owner`(负责人)、`master`(管理员Administrator)、`developer`(开发者)、`reporter`(助手)、`guest`(访客)。
      角色非向上包含关系，例如仅声明了 `master` 有权限，`owner` 即使仓库权限更高，在此处也没有权限
  * `inputs`: 选填，`Object<String, Input>`，可手动输入的环境变量，对象的键值为变量名，`Input` 类型定义如下：

    * `name`：`name`：必填，`String`，输入选项名称，非环境变量键值，仅用于页面展示
    * `description`：选填，`String`，描述信息
    * `placeholder`：选填，`String`，输入框内提示信息。仅当 type=`input` 或 `textarea` 或 `select` 时有效
    * `required`：选填，`Boolean`，是否必填
    * `type`：选填，`String`，输入框类型，可选 `input`、`textarea`、`select`、`switch`、`radio`，默认为 `input`
    * `default`: 选填，`String`，默认值
    * `multiple`: 选填，`Boolean`，是否支持多选，仅当 type=`select` 时有效，多选结果用分号分隔。单个选项的 `value` 中需避免出现逗号
    * `options`: 选填，`Array<Option>`，当 `type: select` 或 `type: switch` 时的选项。`Option` 类型定义如下：
      * `name`: 必填，`String`，选项名
      * `value`: 必填，`String`，选项值，作为环境变量值
      * `description`: 选填，`String`，选项描述信息

    `inputs` 也支持分组，`Array<Object>`，每个数组元素是一个对象，表示一个分组，类型定义如下：

    * `name`: 必填，`String`，分组名称，非环境变量键值，仅用于页面展示
    * `inputs`: 必填，`Object<String, Input>`，分组内环境变量定义，对象的键值为变量名，`Input` 类型定义同上方 `Input`类型定义。

* `deploy`: 选填，对象数组格式，自定义部署按钮。点击按钮可触发云原生构建流水线，执行部署事件（`tag_deploy.*`）。

  * `name`: 必填，按钮名。
  * `description`: 选填，按钮描述。
  * `title`: 选填，自定义触发的部署流水线标题。优先级高于上一级别 `title`
  * `env`: 选填，传给部署流水线的环境变量，优先级高于上一级 env。

* `require`: 选填，对象数组格式。部署的前置条件，需满足了前置条件（部署环境要求、元数据要求、审批流程）才可进行部署操作。

  1、部署环境要求的参数包括

  * `environmentName`: 必填。环境名。
  * `after`: 选填。时间，单位 s(秒)。表示 `environmentName` 的环境部署成功后 after 时间后才算满足前置条件。
  * `description`: 选填。`require` 的描述信息，附注用户理解 `require` 要求的内容。
  * `button`: 选填。自定义按钮，点击可触发执行 event 传入的事件。可定义与 require 信息有关的按钮事件，注意：当 require 满足条件后隐藏按钮。

    * `name`: 必填，按钮名。
    * `event`: 必填，自定义事件，仅支持 `web_trigger_*` 事件。
    * `description`: 选填，按钮描述。如存在，则将作为流水线 title，否则流水线使用默认 title；可支持环境变量替换（仅支持替换一级，环境变量指的是当前配置的 env 和 inputs。仅支持 ${xxx} 写法。）。
    * `env`: 选填，传给 web\_trigger 流水线的环境变量，可继承上一级别环境变量，优先级高于上一级别环境变量。
    * `permissions`: 选填，权限控制，满足 `users` 或 `roles` 其中之一即有权限触发构建（还需要有仓库写权限）。如果未配置 `permissions`，则有仓库写权限即可触发构建
      * `users`: 选填，`Array<String>`，用户名数组。可定义多个。
      * `roles`: 选填，`Array<String>`，仓库角色数组。可定义多种仓库角色：
        `owner`(负责人)、`master`(管理员Administrator)、`developer`(开发者)、`reporter`(助手)、`guest`(访客)。
        角色非向上包含关系，例如仅声明了 `master` 有权限，`owner` 即使仓库权限更高，在此处也没有权限。

  2、元数据要求的参数包括

  * `annotation`: 必填。元数据的 `key` 值。
  * `expect`: 选填。对元数据的 `value` 值的要求。对象格式，支持 `eq`、`ne`、`gt`、`lt`、`gte`、`lte`、`and`、`or`、`reg` 操作符。
    * `eq`: 等于
    * `ne`: 不等于
    * `gt`: 大于
    * `lt`: 小于
    * `gte`: 大于等于
    * `lte`: 小于等于
    * `and`: 与
    * `or`: 或
    * `reg`: 能和正则表达式匹配
  * `description`: 选填。`require` 的描述信息，附注用户理解 `require` 要求的内容。
  * `button`: 选填。自定义按钮，点击可触发执行 event 传入的事件。可定义与 require 信息有关的按钮事件，注意：当 require 满足条件后隐藏按钮。

    * `name`: 必填，按钮名。
    * `description`: 选填，按钮描述。如存在，则将作为流水线 title，否则流水线使用默认 title；可支持环境变量替换（仅支持替换一级，环境变量指的是当前配置的 env 和 inputs。仅支持 ${xxx} 写法。）。
    * `event`: 必填，自定义事件，仅支持 web\_trigger 事件。
    * `env`: 选填，传给 web\_trigger 流水线的环境变量，可继承上一级别环境变量，优先级高于上一级别环境变量。
    * `permissions`: 选填，权限控制，满足 `users` 或 `roles` 其中之一即有权限触发构建（还需要有仓库写权限）。如果未配置 `permissions`，则有仓库写权限即可触发构建
      * `users`: 选填，`Array<String>`，用户名数组。可定义多个。
      * `roles`: 选填，`Array<String>`，仓库角色数组。可定义多种仓库角色：
        `owner`(负责人)、`master`(管理员Administrator)、`developer`(开发者)、`reporter`(助手)、`guest`(访客)。
        角色非向上包含关系，例如仅声明了 `master` 有权限，`owner` 即使仓库权限更高，在此处也没有权限

  3、审批流程要求的参数包括

  * `approver`: 必填，审批人定义，满足 `users` 或 `role` 的审批人中，一人审批通过即可。
    * `users`: 用户名数组。可定义多个审批人。
    * `roles`: 仓库角色数组。可定义多种仓库角色。
      `owner`(负责人)、`master`(管理员Administrator)、`developer`(开发者)、`reporter`(助手)、`guest`(访客)
  * `title`: 选填，审批标题，如 `测试审批`。
  * `agreeEvent`: 选填，点击同意审批按钮成功后触发的事件
    * `description`: 选填，描述信息，会作为流水线 title。
    * `event`: 必填，事件名，仅支持 `web_trigger` 事件。
    * `env`: 选填，传给流水线的环境变量，不支持继承上一级别的环境变量。
  * `rejectEvent`: 选填，点击拒绝审批按钮成功后触发的事件
    * `description`: 选填，描述信息，会作为流水线 title。
    * `event`: 必填，事件名，仅支持 `web_trigger` 事件。
    * `env`: 选填，传给流水线的环境变量，不支持继承上一级别的环境变量。

## 自定义部署前置条件

对于每个环境可定义部署前置条件，只有满足所有前置条件才可进行部署操作。可定义如下三种前置条件：

* 环境部署要求：要求指定环境已经部署成功，且满足 `after` 部署成功时间要求
* 元数据值要求：要求指定元数据对应的值是否满足要求
* 审批流程要求：可自定义审批流程指定审批人，并进行审批操作，当全部审批流程都审批通过后，才算满足要求

### 环境部署前置条件示例

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: development
    description: Development environment
    env:
      name: development
      tag_name: $CNB_BRANCH

  - name: staging
    description: Staging environment
    env:
      name: staging
      tag_name: $CNB_BRANCH
    require:
      # 要求 development 环境部署成功
      - environmentName: development

  - name: production
    description: Production environment
    require:
      # 要求 staging 环境部署成功 30 分钟后
      - environmentName: staging
        after: 1800
```

### 元数据前置条件示例

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: production
    description: Production environment
    require:
      # 对元数据是否满足要求的检查

      # 键值 key1 对应的 value 不为空，即有值
      - annotation: key1

      # 键值 key2 对应的 value 值需等于 value1
      - annotation: key2
        expect:
          eq: value2

      # 键值 key3 对应的 value 值需大于 1 且小于 10
      - annotation: key3
        expect:
          and:
            gt: 1
            lt: 10
        # 自定义按钮，点击可触发执行 web_trigger_annotation 事件。
        # 可定义与 require 信息有关的按钮事件，当 require 满足条件后隐藏按钮
        button:
          - name: 生成元数据
            event: web_trigger_annotation
            # 如存在，则将作为流水线 title，否则流水线使用默认 title；可支持环境变量替换（仅支持替换一级，环境变量指的是当前配置的 env 和 inputs。仅支持 ${xxx} 写法。）
            description: 生成元数据流程
            # 传给 web_trigger_annotation 事件流水线的环境变量
            # 可继承上一级别环境变量，优先级高于上一级别环境变量
            env:
              name1: value1
              name2: value2
```

### 审批流程前置条件示例

可自定义审批流程和指定审批人。有权限的审批人可进行审批操作（同意、拒绝）。全部流程审批通过后，即算满足要求

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: production
    description: Production environment
    require:
      # 对审批流程是否满足要求的检查（可按以下方式自定义审批流程）
      # - 审批顺序：如下 1、2、3 审批流程需按顺序进行，即 1 审批通过，2 才能进行审批。1、2、3 审批流程全部通过才算通过审批
      # - 审批操作：包括 同意、拒绝。一人同意即算通过。如果拒绝，其他审批人无法再操作，直到拒绝的审批人再修改审批结果为同意

      # 按用户名审批，其中一人审批通过即可
      - approver:
          users:
            - user1
            - user2
            - user3
        # 可配置点击同意按钮触发的事件，以及传给事件流水线的环境变量
        # agreeEvent:
        #   # 描述信息，会作为流水线 title
        #   description: 同意审批
        #   # 点击同意按钮时触发的事件名，仅支持 web_trigger 事件
        #   event: web_trigger_agree
        #   # 传给事件流水线的环境变量，不支持继承上一级别的环境变量
        #   env:
        #     name1: value1
        #     name2: value2
        # 可配置点击拒绝按钮触发的事件，以及传给事件流水线的环境变量
        # rejectEvent:
        #   # 描述信息，会作为流水线 title
        #   description: 拒绝审批
        #   # 点击拒绝按钮时触发的事件名，仅支持 web_trigger 事件
        #   event: web_trigger_reject
        #   # 传给事件流水线的环境变量，不支持继承上一级别的环境变量
        #   env:
        #     name1: value1
        #     name2: value2
        title: 测试审批

      # 按角色审批，其中一人审批通过即可
      - approver:
          roles:
            - developer
            - master
        title: 开发审批

      # 按用户名或角色审批（审批人满足 users 或 roles 其一即可），其中一人审批通过才行
      - approver:
          users:
            - user4
            - user5
          roles:
            - master
            - owner
        title: 运维审批
```

## 自定义部署流水线

如下示例定义了三种环境的部署事件流水线，
当在页面中选择部署 `development` 环境时，则触发 `tag_deploy.development` 事件。
流水线基于当前 tag 对应的代码进行部署操作。

```yaml title=".cnb.yml"
$:
  tag_deploy.development:
    - name: dev
      stages:
        - name: 部署环境名
          script: echo $name
        - name: tag 名
          script: echo $tag_name
  tag_deploy.staging:
    - name: staging
      stages:
        - name: 部署环境名
          script: echo $name
        - name: tag 名
          script: echo $tag_name
  tag_deploy.production:
    - name: production
      stages:
        - name: 部署环境名
          script: echo $name
        - name: tag 名
          script: echo $tag_name
```

示例中的流水线事件名和部署环境类型对应关系如下：

* `tag_deploy.development`：`development`
* `tag_deploy.staging`：`staging`
* `tag_deploy.production`：`production`

### 自定义按钮触发的 web\_trigger 事件

`tag_deploy.yml` 中的自定义按钮，仅支持触发 [web\_trigger事件](./trigger-rule.md#web_trigger) 事件。
如下流水线配置中，`web_trigger_annotation` 事件执行时，会进行上传[元数据](../repo/annotations.md)操作。

```yaml title=".cnb.yml"
$:
  # 自定义按钮可触发的事件
  web_trigger_annotation:
    - stages:
        - name: 上传元数据
          image: cnbcool/annotations:latest
          settings:
            data: |
              key1=value1
              key2=value2
```

## 部署权限说明

默认需有 `仓库写权限` 且有 `推送 Tag` 权限的用户才能进行部署操作。

如果环境有配置 `permissions` 字段，则 `有仓库写权限`，且满足 permissions 字段中定义的权限的用户才能进行部署操作，此时不检查 `推送 Tag` 权限。
