---
url: /zh/build/deploy.md
description: |
  介绍如何通过云原生构建配置自定义部署环境、审批流程和部署流水线， 实现自动化发布。
---
`云原生构建` 支持自定义部署流程，可配置部署环境、审批流程和部署流水线，实现自动化发布。

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

## 自定义部署环境

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

### 基础示例

最简配置，定义三个部署环境：

```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
  - name: production
    description: Production environment
    env:
      name: production
      tag_name: $CNB_BRANCH
```

### 权限控制

通过 `permissions` 限制部署操作的执行人：

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: production
    description: Production environment
    permissions:
      roles:
        - master
        - developer
      users:
        - name1
        - name2
```

### 自定义按钮（button）

在环境配置中添加 `button`，触发自定义的 `web_trigger` 事件：

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: production
    description: Production environment
    button:
      - name: 生成发布说明
        description: 自动生成 Release Notes
        event: web_trigger_release_notes
        env:
          a: 1
          b: 2
```

### 自定义部署按钮（deploy）

多模块场景下可通过 `deploy` 配置多个部署按钮，通过 `env` 区分不同模块：

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: production
    description: Production environment
    deploy:
      - name: 部署前端
        env:
          module: frontend
      - name: 部署后端
        env:
          module: backend
```

> `deploy` 按钮的环境变量仅支持通过 `env` 预先配置，不支持用户在页面上手动输入。
> 部署是较为严肃的操作，相关参数应纳入版本控制。

## 字段说明

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

* `description`：选填，环境描述。

* `title`：选填，自定义部署流水线标题。

* `env`：选填，传给部署流水线的环境变量。

* `permissions`：选填，部署权限控制。
  满足 `users` 或 `roles` 其一即有权限（还需仓库写权限）。
  不配置时，有仓库写权限和推送 Tag 权限即可触发。
  * `users`：选填，`Array<String>`，用户名数组。可定义多个。
  * `roles`：选填，`Array<String>`，仓库角色数组。仅支持具备仓库写权限的角色：
    `owner`（负责人）、`master`（管理员）、`developer`（开发者）。
    角色为向上包含。例如只声明 `master` 有权限，`owner` 权限更高，同样也有权限。

* `button`：选填，对象数组格式，自定义按钮。
  点击按钮可触发云原生构建流水线，执行 `event` 对应的事件。
  * `name`：必填，按钮名。
  * `description`：选填，按钮描述。如存在，将作为流水线 title；
    支持环境变量替换（仅支持替换一级，
    环境变量指当前配置的 env 和 inputs，仅支持 ${xxx} 写法）。
  * `event`：必填，自定义事件，仅支持 web\_trigger 事件。
  * `isDefault`：选填，`Boolean`，是否是默认按钮，仅支持设置一个（设置多个取第一个）。
  * `env`：选填，传给 web\_trigger 流水线的环境变量，可继承上一级别环境变量。
  * `permissions`：选填，权限控制，
    满足 `users` 或 `roles` 其中之一（还需具备该环境的部署权限）。
  * `inputs`：选填，可手动输入的环境变量，
    支持 `input`、`textarea`、`select`、`switch`、`radio` 五种类型，也支持分组。
    详细说明见 [手动触发流水线 - 自定义按钮配置](./web-trigger.md#自定义按钮配置)。

* `deploy`：选填，对象数组格式，自定义部署按钮。
  点击按钮可触发部署事件（`tag_deploy.*`）。
  * `name`：必填，按钮名。
  * `description`：选填，按钮描述。
  * `title`：选填，自定义触发的部署流水线标题。优先级高于上一级别 `title`
  * `env`：选填，传给部署流水线的环境变量，优先级高于上一级 env。

* `require`：选填，对象数组格式。部署前置条件，需满足所有条件后才可部署。
  支持以下三种类型：

  * **环境部署要求**
    * `environmentName`：必填，`String`，依赖的环境名，要求该环境已部署成功
    * `after`：选填，`Number`，依赖环境部署成功后还需等待的秒数
    * `button`：选填，自定义按钮。当前置条件不满足时显示，点击触发 `web_trigger` 事件以满足该条件
  * **元数据要求**
    * `annotation`：必填，`String`，元数据 key，要求值不为空
    * `expect`：选填，元数据值需满足的条件，支持 `eq`/`ne`/`gt`/`lt`/`gte`/`lte`/`and`/`or`/`reg`
    * `button`：选填，自定义按钮。当前置条件不满足时显示，点击触发 `web_trigger` 事件以满足该条件
  * **审批流程要求**
    * `approver`：必填，审批人，支持 `users` 和 `roles`
    * `title`：选填，`String`，审批标题
    * `agreeEvent`：选填，点同意按钮触发的自定义事件（仅支持 `web_trigger`）
    * `rejectEvent`：选填，点拒绝按钮触发的自定义事件（仅支持 `web_trigger`）

  详见下方 [自定义部署前置条件](#自定义部署前置条件) 章节的示例。

## 自定义部署前置条件

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

* 环境部署要求：要求指定环境已经部署成功，且满足 `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:
      - environmentName: development
  - name: production
    description: Production environment
    require:
      - environmentName: staging
        after: 1800 # 要求 staging 部署成功 30 分钟后
```

### 元数据前置条件

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: production
    description: Production environment
    require:
      - annotation: key1 # 值不为空
      - annotation: key2
        expect:
          eq: value2 # 值等于 value2
      - annotation: key3
        expect:
          and:
            gt: 1
            lt: 10 # 值大于 1 且小于 10
        button:
          - name: 生成元数据
            event: web_trigger_annotation
            description: 生成元数据流程
            env:
              name1: value1
```

### 审批流程前置条件

可自定义审批流程和指定审批人。
`approver` 支持 `users` 和 `roles`，二者满足其一即为有权限的审批人：
`users` 精确匹配用户名；`roles` 为向上包含，
例如配置 `developer`，则 `developer`、`master`、`owner` 均可审批。
有权限的审批人可审批（同意、拒绝）。
全部流程审批通过后即满足要求。

> 部署权限名单（`permissions`）中的 `roles` 同样是向上包含语义：
> 配置最低可操作角色即可，更高角色自动包含在内。

```yaml title=".cnb/tag_deploy.yml"
environments:
  - name: production
    description: Production environment
    require:
      - approver:
          users:
            - user1
            - user2
        title: 测试审批
      - approver:
          roles:
            - developer
            - master
        title: 开发审批
      - approver:
          users:
            - user4
          roles:
            - master
            - owner
        title: 运维审批
```

## 自定义部署流水线

如下示例定义了三种环境的部署事件流水线。当在页面中选择部署某个环境时，
将触发对应的 `tag_deploy.<环境名>` 事件，流水线基于当前 tag 对应的代码部署。

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

  tag_deploy.staging: # 部署 staging 环境
    - name: dev
      stages:
        - name: 部署环境名
          script: echo $name
        - name: tag 名
          script: echo $tag_name

  tag_deploy.production: # 部署 production 环境
    - name: dev
      stages:
        - name: 部署环境名
          script: echo $name
        - name: tag 名
          script: echo $tag_name
```

### 自定义按钮触发的 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 权限。

环境的自定义按钮（`button`，含前置条件 `require` 里的 `button`）触发 `web_trigger` 事件时，
需具备该环境的部署权限；若按钮自身配置了 `permissions`，还需是其中列出的 `users` / `roles`。

## 重新构建限制

为避免部署操作被他人越权重新构建，
部署事件（`tag_deploy.*`）触发的构建有以下重新构建限制：

* 仅原流水线触发人本人可重新构建，其他用户不可。
* 仅支持 24 小时内重新构建，超过 24 小时不再支持。

超过 24 小时或非本人需要重新部署时，
请在 Tag 详情页重新发起部署，以走完整的前置检查与审批流程。
