部署与发布:分环境、加审批、能回滚
构建通过只是半程,发布是另一半。这篇讲怎么把发布这件事做得可控。
一、三套环境怎么定义
在仓库根目录加 .cnb/tag_deploy.yml,定义可选环境:
.cnb/tag_deploy.yml
environments:
- name: development
description: 开发环境
env:
name: development
tag_name: $CNB_BRANCH
- name: staging
description: 预发布
env:
name: staging
tag_name: $CNB_BRANCH
- name: production
description: 生产环境
env:
name: production
tag_name: $CNB_BRANCH
配好后,Tag 详情页的「部署」按钮会让用户选环境。
二、生产环境加权限
.cnb/tag_deploy.yml
environments:
- name: production
description: 生产环境
permissions:
roles:
- master
users:
- zhangsan
规则细节:
- 默认情况:有仓库写权限 + 能推 Tag 的人就能部署
- 配了
permissions:需要仓库写权限 且 命中permissions,此时不再检查推 Tag 权限
所以 permissions 是用来收紧的,不是放宽。
三、环境里再放自定义按钮
一个环境里想加"生成发布说明"这种辅助动作:
.cnb/tag_deploy.yml
environments:
- name: production
description: 生产环境
button:
- name: 生成发布说明
description: 自动生成 Release Notes
event: web_trigger_release_notes
env:
a: 1
b: 2
button 只支持触发 web_trigger 系列事件,事件本身要在 .cnb.yml 里定义。
多模块项目用 deploy 配多个部署按钮,靠 env 区分模块。
四、重新构建的限制(很容易踩)
部署事件(tag_deploy.*)触发的构建有特殊规则:
- 只有原触发人本人能重新构建
- 只有 24 小时内能重新构建
超时或换人怎么办?去 Tag 详情页重新发起一次部署,走完整的前置检查和审批流程。这是故意的——防止有人用"重新构建"绕过审批。
五、按分支做分级发布
再进一步,用分支区分发布等级:
.cnb.yml
"release/*":
push:
- stages:
- name: 部署到预发
script: echo "deploy to staging"
main:
tag_push:
- stages:
- name: 部署到生产
script: echo "deploy to production"
配套的分支策略通常是:feature/* 开发 → release/* 预发 → main 打 Tag 上生产。
六、部署流水线该长什么样
一条能用的部署流水线,至少要有四段:
.cnb.yml
$:
tag_push:
- stages:
# 1. 准备产物
- name: build
script: npm run build
# 2. 部署
- name: deploy
script: |
echo "部署到 $env"
# 3. 冒烟验证
- name: smoke test
script: curl -f https://example.com/health
# 4. 通知
- name: notify
script: echo "发布完成:$CNB_BRANCH"
failStages:
- name: 失败告警
script: echo "发布失败,请立即处理"
第 3 步最容易被省掉,也最重要——没有冒烟验证的部署不叫部署,叫"推一把试试"。
七、一条常被忽略的:制品要可追溯
部署时不要现场构建。正确顺序是:构建流水线产出镜像/包 → 部署流水线拉取那个确定的产物。
这样两个好处:
- 部署时不会因为依赖下载失败而失败
- 出了问题能明确回答"生产上跑的是哪个 commit"
对应做法:
.cnb.yml
$:
push:
- services:
- docker
stages:
- name: build and push
script: |
docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${CNB_COMMIT_SHORT} .
docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${CNB_COMMIT_SHORT}
tag_push:
- services:
- docker
stages:
- name: deploy
script: |
docker pull ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${CNB_COMMIT_SHORT}
用 commit short sha 当 tag,是版本可追溯最简单有效的做法。