跳到主要内容

自动化:自动合并、自动发版、Issue 自动流转

前面几篇讲的是"能跑"。这篇讲"跑完自己处理后续",把重复劳动交出去。

一、自动合并 PR​

目标:检查通过 + 评审通过 → 自动合并,人不用点按钮。

关键事件是 pull_request.mergeable,它只在三个条件同时满足时触发:

  1. 目标分支是保护分支,且勾选了「需要评审人批准」和/或「需要通过状态检查」
  2. 无冲突且状态检查通过
  3. 评审通过
.cnb.yml
main:
pull_request.mergeable:
- stages:
- name: 自动合并
type: git:auto-merge
options:
mergeType: squash

mergeType 三选一:

值行为
auto(默认)多人提交走 merge,否则走 squash
merge生成合并点,保留所有提交
squash压成一个提交

:::warning mergeable 的两个坑

  1. 配置取自目标分支。你在源分支写这条流水线,不会生效
  2. 所以要先在目标分支(比如 main)的 .cnb.yml 里配好,再去开 PR :::

git:auto-merge 还会自动补提交信息,比如 squash 模式下会用 PR 第一条 commit message,并追加:

PR-URL: !916
Reviewed-By: tom
Reviewed-By: jerry
Co-authored-by: jack

这段信息在半年后回看时非常有用:谁审的、原始 PR 在哪。

二、自动发版​

推 Tag 就发 Release:

.cnb.yml
$:
tag_push:
- stages:
- name: 创建 Release
type: git:release
options:
title: $CNB_BRANCH
descriptionFromFile: ./CHANGELOG.md

参数要点:

参数说明
overlying默认 false:先删后建。要保留原 Release 就设 true
tagTag 名。tag_push 事件不用传
descriptionFromFile从文件读描述,内容长时必用

:::warning overlying 默认是 false 这意味着同名 Release 会被先删除再重建。如果你在页面上手动编辑过 Release 内容,重跑流水线会丢。要保留就设 overlying: true。 :::

变更日志想自动生成的话,可以在前面加一个 stage 先算出 changelog 写进文件,再用 descriptionFromFile 引用。

三、Issue 跟着代码走​

git:issue-update 会自动从提交记录里解析 Issue 编号,然后关 Issue、打标签。

默认的 Issue 定位规则:

事件从哪找 Issue
Issue 相关事件当前 Issue
PR 相关事件该 PR 所有 commit 的提交日志
commit.add新增 commit 的提交日志
非新建分支的 push本次推送的 commit 提交日志

所以提交信息里带上 Issue 编号就行(比如 fix: 修复登录问题 #123),流水线会自动关联。

.cnb.yml
$:
pull_request.merged:
- stages:
- name: 关闭关联 Issue
type: git:issue-update
options:
state: close
prefix:
- close
- fix

也可以完全不用提交记录——用 fromText 或 fromFile 从别的文本里解析,fromFile 优先。

四、其他几个值得配的自动化​

PR 自动打标签

- name: 标记待评审
type: git:pr-update
options:
labels: 待评审

提前销毁令牌

用不到 CNB_TOKEN 了就销毁,缩小暴露窗口:

- name: 用完即焚
type: cnb:destroy-token

覆盖率门禁

- name: 覆盖率
type: testing:coverage
options:
file: coverage/lcov.info

支持 json(js)、json-summary、lcov、jacoco、golang 五种报告格式。可以在仓库 洞察 页看最近 100 个 commit 的趋势图,也能配增量覆盖率门禁——不达标直接失败。

五、一个完整的"成熟仓库"长什么样​

把前面几篇的组合起来:

.cnb.yml
main:
# PR:检查 + 自动评审人
pull_request:
- stages:
- name: lint
script: npm run lint
- name: test
script: npm test
- name: 指派评审人
type: git:reviewer
options:
type: add-reviewer-from-repo-members
failStages:
- name: 失败通知
script: echo "PR 检查失败"

# 满足条件自动合并
pull_request.mergeable:
- stages:
- name: 自动合并
type: git:auto-merge
options:
mergeType: squash

# 合并后关 Issue
pull_request.merged:
- stages:
- name: 同步 Issue
type: git:issue-update

$:
# 推 Tag 发版
tag_push:
- stages:
- name: 创建 Release
type: git:release
options:
descriptionFromFile: ./CHANGELOG.md

# 夜里跑全量
"crontab: 0 3 * * *":
- stages:
- name: 夜间全量测试
script: npm run test:all

# 日常构建
push:
- docker:
image: node:22
volumes:
- /root/.npm:copy-on-write
stages:
- name: install
script: npm ci
- name: build
script: npm run build

注意最后一段的 crontab 必须挂在明确分支名下,不能是 $——这是定时任务的硬要求。

六、别忘了​

自动化越深,失败时的可观测性越重要。三个兜底:

  1. failStages 里发通知
  2. 关键步骤用 exports 把状态传出来打日志
  3. 定期看 云原生构建 → 历史事件,确认该触发都触发了