自动化:自动合并、自动发版、Issue 自动流转
前面几篇讲的是"能跑"。这篇讲"跑完自己处理后续",把重复劳动交出去。
一、自动合并 PR
目标:检查通过 + 评审通过 → 自动合并,人不用点按钮。
关键事件是 pull_request.mergeable,它只在三个条件同时满足时触发:
- 目标分支是保护分支,且勾选了「需要评审人批准」和/或「需要通过状态检查」
- 无冲突且状态检查通过
- 评审通过
main:
pull_request.mergeable:
- stages:
- name: 自动合并
type: git:auto-merge
options:
mergeType: squash
mergeType 三选一:
| 值 | 行为 |
|---|---|
auto(默认) | 多人提交走 merge,否则走 squash |
merge | 生成合并点,保留所有提交 |
squash | 压成一个提交 |
:::warning mergeable 的两个坑
- 配置取自目标分支。你在源分支写这条流水线,不会生效
- 所以要先在目标分支(比如
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:
$:
tag_push:
- stages:
- name: 创建 Release
type: git:release
options:
title: $CNB_BRANCH
descriptionFromFile: ./CHANGELOG.md
参数要点:
| 参数 | 说明 |
|---|---|
overlying | 默认 false:先删后建。要保留原 Release 就设 true |
tag | Tag 名。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),流水线会自动关联。
$:
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 的趋势图,也能配增量覆盖率门禁——不达标直接失败。
五、一个完整的"成熟仓库"长什么样
把前面几篇的组合起来:
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 必须挂在明确分支名下,不能是 $——这是定时任务的硬要求。
六、别忘了
自动化越深,失败时的可观测性越重要。三个兜底:
failStages里发通知- 关键步骤用
exports把状态传出来打日志 - 定期看
云原生构建→历史事件,确认该触发都触发了