内置任务
10622 字约 35 分钟
在每一阶段(Stage)操作中,除了使用自定义任务, CNB 还扩展了一些常用的内置任务,以供开发者使用。
总览
- docker:
- cache: 构建 Docker 镜像缓存,加速依赖安装
- cnb:
- await-resolve: 等待/通知机制,多流水线协作
- apply: 触发同仓库下的子流水线
- trigger: 触发指定仓库下的子流水线
- read-file: 导出文件内容为环境变量
- vscode:
- go: 控制远程开发环境可用时机
- git:
- reviewer: PR 自动添加评审人
- auto-merge: PR 自动合并
- issue-update: 更新 Issue 状态
- release: 仓库发布 Release
- pr-commit-message-preset: 预先设置 PR 的 提交信息
- pr-update: 更新 PR 的标题、标签
- testing:
- coverage: 单测覆盖率上报
- artifact
- remove-tag: 删除 CNB 制品标签
Docker
cache
docker:cache
Docker 缓存,构建一个 Docker 镜像作为缓存,在未来的构建中重复使用。
可以避免网络资源如 依赖包 重复下载。
适用事件
参数
dockerfile
- type:
String - required:
true
用于构建缓存镜像的 Dockerfile 路径。
为避免超长时间构建,Docker 镜像构建超时时间受 job.timeout 参数控制。
by
- type:
Array<String>|String - required:
false
用来声明缓存镜像构建过程中依赖的文件列表。
注意:未出现在 by 列表中的文件,除了 Dockerfile,其他在构建镜像过程中,都当不存在处理。
- 支持数组格式
- 支持字符串格式,多个文件用英文逗号分隔。
versionBy
- type:
Array<String>|String - required:
false
用来进行版本控制,未传入 versionBy,则默认取 by 的值进行版本控制。
versionBy 所指向的文件内容发生变化,我们就会认为是一个新的版本, 具体的计算逻辑见这个表达式:
sha1(Dockerfile + versionBy + buildArgs + target + arch)
- 支持数组格式。
- 支持字符串格式,多个文件用英文逗号分隔。
buildArgs
- type:
Object - required:
false
在 build 时插入额外的构建参数 (--build-arg $key=$value), value 值为 null 时只加入 key (--build-arg $key)。
target
- type:
String - required:
false
对应 docker build 中的 --target 参数,可以选择性地构建 Dockerfile 中的特定阶段,而不是构建整个 Dockerfile。
sync
- type:
Boolean - required:
false - default:
false
是否同步模式,true 则会等待缓存镜像 push 成功后才继续后续任务。
ignoreBuildArgsInVersion
- type:
Boolean - required:
false - default:
false
版本计算是否忽略 buildArgs。
参见 版本控制
输出结果
{
// 缓存对应的 docker image name
name;
}配置样例
main:
push:
- docker:
image: node:14
stages:
- name: build cache image
type: docker:cache
options:
dockerfile: cache.dockerfile
# by 支持以下两种形式:数组、字符串
by:
- package.json
- package-lock.json
# versionBy: package-lock.json
versionBy:
- package-lock.json
exports:
name: DOCKER_CACHE_IMAGE_NAME
- name: use cache
image: $DOCKER_CACHE_IMAGE_NAME
# 将 cache 中的文件拷贝过来使用
commands:
- cp -r "$NODE_PATH" ./node_modules
- name: build with cache
script:
- npm run build其中 cache.dockerfile 是一个用于构建缓存镜像的 Dockerfile,示例:
# 选择一个 Base 镜像
FROM node:14
# 设置工作目录
WORKDIR /space
# 将 by 中的文件列表 COPY 过来
COPY . .
# 根据 COPY 过来的文件进行依赖的安装
RUN npm ci
# 设置好需要的环境变量
ENV NODE_PATH=/space/node_modulescnb
await
resolve
await-resolve
cnb:awaitcnb:resolve
await 会等待 resolve 的执行,resolve 可以向 await 传递变量。
通过 await-resolve,可以让多个并发的 pipeline 相互配合,实现更灵活的顺序控制。
提示
await-resolve 同 apply、trigger 的区别:
前者指一个构建中某 pipeline 执行到 await 任务时等待对应 key 的其他 pipeline 的 resolve 通知才会继续进行。
后者指一个 pipeline 触发新 pipeline。可以异步调用,也可以同步等待。还可以跨仓库。
使用限制
- 只能对
同一个事件触发的 pipeline 进行 await 和 resolve 操作 - 一个
key仅能 resolve 一次,但可以 await 多次 - 通过
key对 await 和 resolve 进行分组 - await-resolve 任务只能运行在流水线的
stages中,不能运行在endStages和failStages中
死锁检测
await 和 resolve 相互配合可以完成灵活的流程控制,但也会引入更复杂的边界情况,比如:
- 死锁
- pipeline-1 和 pipeline-2 相互 await
- 多条 pipeline 间存在 await 环
- 无限等待
- await 一个不存在的 key,或者 key 没有关联 resolve
- resolve 所在 pipeline 执行失败
- 重复 resolve
- 多个 resolve 任务关联同一个 key
死锁检测 机制会自动检测以上异常,结束 await 的等待状态,抛出 dead lock found. 异常。
await 和 resolve 的在配置文件中顺序不影响运行结果,即最后 await 任务一定是会等待相应的 resolve 完成,这种情况不会被 死锁检测 机制终止。
适用事件
await 参数
key
- type: String
- required: true
配对 ID
resolve 参数
key
- type: String
- required: true
配对 ID
data
- type: object
- required: false
要传递的对象
key: value 格式,支持多级。示例:
- name: resolve a json
type: cnb:resolve
options:
key: demo
data:
a: 1
b:
c: 2await 任务的结果,是 resolve 声明的 data 对象。 可以通过 exports 访问这个对象,示例:
- name: await a json
type: cnb:await
options:
key: demo
exports:
a: VAR_A
b.c: VAR_B
- name: show var
script:
- echo ${VAR_A} # 1
- echo ${VAR_B} # 2当然,也可以不传送任务内容,仅仅表示一个等待动作:
- name: ready
type: cnb:resolve
options:
key: i-am-ready- name: ready
type: cnb:await
options:
key: i-am-ready输出结果
{
// resolve 返回的 data 内容
data;
}apply
cnb:apply
在当前仓库中,触发当前仓库的自定义事件流水线。
适用事件
pushcommit.addbranch.createpull_request.targetpull_request.mergeabletag_pushpull_request.mergedapi_triggerweb_triggercrontabtag_deploy
参数
config
- type:
String - required:
false
完整的 CI 配置文件内容。
configFrom
- type:
String - required:
false
指定一个本地文件作为配置文件。
event
- type:
String - required:
false - default:
api_trigger
要执行的自定义事件名,必须为 api_trigger 或以 api_trigger_ 开头。
sync
- type:
Boolean - required:
false - default:
false是否同步执行。
同步模式下会等待本次 apply 流水线执行成功,再执行下一个任务。
continueOnBuildError
- type:
Boolean - required:
false - default:
false
同步模式下,触发的流水线构建失败时,是否继续执行下个任务。
title
- type:
String - required:
false
自定义流水线标题
环境变量相关
传递给新的流水线当前 Job 可见的、业务定义的环境变量。
默认值中有如下环境变量,用户无法覆盖:
APPLY_TRIGGER_BUILD_ID,含义同 CI 默认环境变量中的CNB_BUILD_IDAPPLY_TRIGGER_PIPELINE_ID,含义同 CI 默认环境变量中的CNB_PIPELINE_IDAPPLY_TRIGGER_REPO_SLUG,含义同 CI 默认环境变量中的CNB_REPO_SLUGAPPLY_TRIGGER_REPO_ID,含义同 CI 默认环境变量中的CNB_REPO_IDAPPLY_TRIGGER_USER,含义同 CI 默认环境变量中的CNB_BUILD_USERAPPLY_TRIGGER_BRANCH,含义同 CI 默认环境变量中的CNB_BRANCHAPPLY_TRIGGER_COMMIT,含义同 CI 默认环境变量中的CNB_COMMITAPPLY_TRIGGER_COMMIT_SHORT,含义同 CI 默认环境变量中的CNB_COMMIT_SHORTAPPLY_TRIGGER_ORIGIN_EVENT,含义同 CI 默认环境变量中的CNB_EVENTCNB_PULL_REQUEST_ID,含义同 CI 默认环境变量中的CNB_PULL_REQUEST_IDCNB_PULL_REQUEST_IID,含义同 CI 默认环境变量中的CNB_PULL_REQUEST_IIDCNB_PULL_REQUEST_MERGE_SHA,含义同 CI 默认环境变量中的CNB_PULL_REQUEST_MERGE_SHA
Config 取值优先级
按以下顺序依次取值,取到为止:
configconfigFrom- 当前仓库
.cnb.yml - 若在
pull_request.merged事件中调用 apply 内置任务,取合并后的配置文件 - 若在
pull_request.target、pull_request.mergeable事件中调用apply内置任务,取目标分支的配置文件 - 其他情况取当前分支配置文件
configFrom 只支持本地文件如 ./test/.cnb.yml,远程文件可先自行下到本地。
输出结果
{
"sn": "cnb-i5o-1ht8e12hi", // 构建号
"buildLogUrl": "http://xxx/my-group/my-repo/-/build/logs/cnb-i5o-1ht8e12hi", // 构建日志链接
"message": "success",
"buildSuccess": true, // 触发的构建是否成功,此key仅在同步模式下存在
"lastJobExports": {} // 触发的流水线最后一个job导出的环境变量
}配置样例
main:
push:
- stages:
- name: trigger
type: cnb:apply
options:
configFrom: ./test/.cnb.yml
event: api_trigger_testmain:
push:
- stages:
- name: trigger
type: cnb:apply
options:
config: |
main:
api_trigger_test:
- stages:
- name: test
script: echo test
event: api_trigger_testmain:
push:
- stages:
- name: trigger
type: cnb:apply
options:
# 执行当前配置文件的其它事件
event: api_trigger_test
api_trigger_test:
- stages:
- name: test
script: echo testmain:
push:
- stages:
- name: trigger
type: cnb:apply
options:
configFrom: .xxx.yml
event: api_trigger_test
sync: truetrigger
cnb:trigger
在当前仓库中,触发指定仓库的自定义事件流水线(需要有触发对应仓库流水线的权限)。
适用事件
参数
token
- type:
String - default: 环境变量 CNB_TOKEN
个人访问令牌。
新流水线触发者为令牌对应用户,会判断有无触发目标仓库流水线权限。
slug
- type:
String - required:
true
目标仓库的完整路径,如:group/repo。
event
- type:
String - required:
true
触发的自定义事件名,必须是 api_trigger 或以 api_trigger_ 开头。
需要目标仓库配置了对应分支、对应事件的流水线,才可以触发。
branch
- type:
String - required:
false
触发分支,默认为目标仓库主分支。
sha
- type:
String - required:
false
触发分支中的 CommitId,默认取 branch 的最新提交记录。
env
- type: TriggerEnv
- required:
false
触发目标仓库流水线时指定传递过去的环境变量。
默认值中有如下环境变量,用户无法覆盖:
API_TRIGGER_BUILD_ID,含义同 CI 默认环境变量中的CNB_BUILD_IDAPI_TRIGGER_PIPELINE_ID,含义同 CI 默认环境变量中的CNB_PIPELINE_IDAPI_TRIGGER_REPO_SLUG,含义同 CI 默认环境变量中的CNB_REPO_SLUGAPI_TRIGGER_REPO_ID,含义同 CI 默认环境变量中的CNB_REPO_IDAPI_TRIGGER_USER,含义同 CI 默认环境变量中的CNB_BUILD_USERAPI_TRIGGER_BRANCH,含义同 CI 默认环境变量中的CNB_BRANCHAPI_TRIGGER_COMMIT,含义同 CI 默认环境变量中的CNB_COMMITAPI_TRIGGER_COMMIT_SHORT,含义同 CI 默认环境变量中的CNB_COMMIT_SHORT
sync
- type:
Boolean - required:
false - default:
false
是否同步执行,同步模式下会等待本次 trigger 流水线执行成功后,再执行下一个任务。
continueOnBuildError
- type:
Boolean - required:
false - default:
false
同步模式下,触发的流水线构建失败时,是否继续执行下个任务。
title
- type:
String - required:
false
自定义流水线标题
类型定义
TriggerEnv
{
[key: String]: String | Number | Boolean
}输出结果
{
"sn": "cnb-i5o-1ht8e12hi", // 构建号
"buildLogUrl": "http://xxx/my-group/my-repo/-/build/logs/cnb-i5o-1ht8e12hi", // 构建日志链接
"message": "success",
"buildSuccess": true, // 触发的构建是否成功,此key仅在同步模式下存在
"lastJobExports": {} // 触发的流水线最后一个job导出的环境变量
}配置样例
基本使用
在当前仓库触发指定仓库 main 分支下事件名为 api_trigger_test 的流水线。
该流水线配置文件使用仓库 main 分支的 .cnb.yml 文件。
使用访问令牌 $TOKEN 查询用户是否有触发目标仓库流水线权限。
main:
push:
- stages:
- name: trigger
type: cnb:trigger
imports: https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/envs.yml
options:
token: $TOKEN
slug: a/b
branch: main
event: api_trigger_testread-file
cnb:read-file
读取指定文件内容,可导出为环境变量供后续任务使用。
用 ##[set-output key=value] 指令输出变量更便捷,但会将内容输出到日志,不适用于敏感信息。
对于事先确定的敏感信息可以用 imports 导入,对于构建过程中生成的敏感信息,可写入文件,用该内置任务读取。
imports 只支持远端仓库存在的文件,该内置任务只支持读取本地存在的文件。
文件类型通过后缀判断,目前支持 .json、 .yml、.yaml、 纯文本(key=value 结构)。
适用事件
参数
filePath
- type: String
- required: true
本地文件路径。
输出结果
{
// 读到的对象
}配置样例
将一些后续任务需要的变量写入文件,用该内置任务读取文件导出为环境变量,供后续任务使用。
{
"myVar": "myVar",
"deep": {
"myVar": "myVar in deep"
},
"deepWithEnvKey": {
"myVar": "myVar in deepWithEnvKey"
}
}main:
push:
- env:
myKey: deepWithEnvKey
stages:
- name: write env file
script: echo "write env to myJson.json"
- name: export env
type: cnb:read-file
options:
filePath: myJson.json
exports:
myVar: ENV_MY_VAR
deep.myVar: ENV_DEEP_MY_VAR # 指定多级的key
$myKey.myVar: ENV_ENV_KEY_MY_VAR # 通过环境变量指定获取的key
- name: echo env
script:
- echo $ENV_MY_VAR
- echo $ENV_DEEP_MY_VAR
- echo $ENV_ENV_KEY_MY_VARvscode
go
vscode:go
远程开发中是否配置该内置任务的区别:
- 使用该任务: 启动云原生开发时,需等待该任务执行完,才出现 WebIDE 和 VSCode/Cursor 客户端入口。
- 不使用该任务: 流水线 prepare 阶段执行完(code-server 代码服务启动),stages 任务执行前,就会出现 WebIDE 和 VSCode/Cursor 客户端入口。
上述入口出现时机区别:仅指从 loading 等待页到跳转入口选择页出现的时机。 实际上无论是否使用该任务,在 code-server 代码服务启动后,远程开发已经是可用状态。
注意:使用该任务将增加等待时间。如果需要延迟开发者进入时机,在某些任务执行完才允许进入远程开发环境,可使用该任务。
适用事件
vscodebranch.createapi_triggerweb_trigger
输出结果
{
// webide url
"url": ""
}配置样例
$:
# vscode 事件:专供页面中启动远程开发用
vscode:
- docker:
# 使用自定义镜像作为开发环境,未传入此参数,将使用默认镜像 cnbcool/default-dev-env:latest
image: cnbcool/default-dev-env:latest
services:
- vscode
- docker
stages:
# 希望等该任务执行完再进入开发环境
- name: ls
script: ls -al
- name: vscode go
type: vscode:go
# 可以在进入开发环境后再执行的任务
- name: ls
script: ls -algit
auto-merge
git:auto-merge
自动合并 Pull Request,一般用于 PR 通过 pull_request 流水线检查 和 Code Review 后,在 pull_request.mergeable 流水线中自动合并 PR。无需人工点击合并按钮。
pull_request.mergeable 事件触发条件和时机参考事件。
适用事件
pull_request.mergeable
参数
mergeType
- type:
String - required:
false - default:
auto
合并策略,默认为 auto:如果多人提交走 merge ,否则走 squash 。
mergeCommitMessage
- type:
String - required:
false
合并点提交信息。
当合并策略为 rebase 的时候,该信息无效,无需填写。
当合并策略为 merge 时,默认为 chore: merge node(merged by CNB) ,会自动追加 PR 引用、评审人名单、PR 包含的提交人名单。举例说明:
chore: merge node(merged by CNB)
PR-URL: !916
Reviewed-By: tom
Reviewed-By: jerry
Co-authored-by: jack当合并策略为 squash 时,默认值为该 PR 的第一条 commit message。并会自动追加 PR 引用和 评审人名单、PR 包含的提交人名单。举例说明:
main:
pull_request.mergeable:
- stages:
- name: automerge
type: git:auto-merge
options:
mergeType: squash该配置会产生如下效果:
某个 PR (feat/model-a -> main) 中有两条提交记录:
- 提交记录 1:2023-10-1 日提交
feat(model-a): 给模块 A 增加一个新特性
由于某某原因,新增某某特性
close #10- 提交记录 2:修复了在 cr 时被指出的一些问题,2023-10-2 日提交
fix(model-a): 修复评审中指出的问题在自动合并后将会在 main 分支上产生一个这样的提交节点,即后续的提交记录(也就是提交记录 2)将会被抹掉
feat(model-a): 给模块 A 增加一个新特性
由于某某原因,新增某某特性
close #10
PR-URL: !3976
Reviewed-By: tom
Reviewed-By: jerry
Co-authored-by: jackmergeCommitFooter
- type:
String - required:
false
合并点需要设置的脚注,多个脚注用 \n 分隔,仅在 merge 和 squash 生效。
当合并策略为 rebase 的时候,该信息无效,无需填写。
当合并策略为 merge 或 squash 时,会将传入信息按行加入到脚注中,再追加 PR 引用、评审人名单、PR 包含的提交人名单。举例说明:
main:
pull_request.mergeable:
- stages:
- name: automerge
type: git:auto-merge
options:
mergeType: squash
mergeCommitMessage: "add feature for some jobs"
mergeCommitFooter: "--story=123\n--story=456"add feature for some jobs
--story=123
--story=456
PR-URL: !916
Reviewed-By: tom
Reviewed-By: jerry
Co-authored-by: jackremoveSourceBranch
- type:
Boolean - required:
false - default:
false
合并后是否删除源分支。
源分支与目标分支不同仓库时,该值无效。
ignoreAssignee
- type:
Boolean - required:
false - default:
false
是否忽略 assignee。
当该 PR 有指定 assignee (指派人)的时候,本任务不会执行自动合并的逻辑。 因为 assignee 的本意就是指派某人手动来处理。
当为 true 时,可忽略 assignee 强行合并。
输出结果
{
reviewedBy, // String,追加在提交信息后面的提交者信息
reviewers, // Array<String>, 走查者列表
}配置样例
单独使用
main:
pull_request.mergeable:
- stages:
- name: automerge
type: git:auto-merge
options:
mergeType: merge当分支 main 上 的 PR 触发了 pull_request.mergeable 事件,那么会将这个 PR 以 merge 的方式自动合并。
配合目标分支的 push 事件使用
main:
push:
- stages:
- name: build
script: npm run build
- name: publish
script: npm run publish
pull_request.mergeable:
- stages:
- name: automerge
type: git:auto-merge
options:
mergeType: merge当分支 main 上 的 PR 触发了 pull_request.mergeable 事件,那么会将这个 PR 以 merge 的方式自动合并。 在自动合并之后,会触发目标分支(main)上的 push 事件,继续执行声明的 build 和 publish 流程。
这里有一个谁应该对产生的 push 事件流程负责的问题,这里的设定是这样的:
- 如果提出 PR 者,是目标仓库的成员,那么提出 PR 的人对后续产生的
push事件流程负责。 - 如果提出 PR 者,不是目标仓库的成员(比如在开源项目中,从
Forked Repo提出 PR)。那么最后一个Code Review的Reviewer将对后续产生的push事件流程负责。
最佳实践
使用 squash 自动合并
使用 squash 合并,一次 PR 操作只在目标分支产生一个 Commit 节点,并且在有权限的情况下删除源分支。
main:
review:
- stages:
- name: automerge
type: git:auto-merge
options:
mergeType: squash
removeSourceBranch: true使用 auto 自动选择合并类型
如果多人提交走 merge ,否则走 squash。
main:
review:
- stages:
- name: automerge
type: git:auto-merge
options:
mergeType: auto建立专用的 CR 群交叉走查自动合并
- 走查通过后自动合并
- 记录走查者信息在提交信息中
main:
pull_request.mergeable:
- stages:
- name: CR 通过后自动合并
type: git:auto-merge
options:
mergeType: squash
mergeCommitMessage: $CNB_LATEST_COMMIT_MESSAGE
exports:
reviewedBy: REVIEWED_BY
- name: notify
image: tencentcom/wecom-message
settings:
robot: "155af237-6041-4125-9340-000000000000"
msgType: markdown
content: |
> CR 通过后自动合并 <@${CNB_BUILD_USER}>
>
> ${CNB_PULL_REQUEST_TITLE}
> [${CNB_EVENT_URL}](${CNB_EVENT_URL})
>
> ${REVIEWED_BY}
pull_request:
- stages:
# ...省略其它任务
- name: notify
image: tencentcom/wecom-message
options:
robot: "155af237-6041-4125-9340-000000000000"
msgType: markdown
content: |
> ${CURR_REVIEWER_FOR_AT}
>
> ${CNB_PULL_REQUEST_TITLE}
> [${CNB_EVENT_URL}](${CNB_EVENT_URL})
>
> from ${CNB_BUILD_USER}issue-update
git:issue-update
更新 Issue 状态,关闭或打开 Issue,修改 Issue 标签。
适用事件
工作机制
查找 Issue 是否存在 -> 检查是否符合 when 条件(可选) -> 检查是否符合 lint 条件(可选)-> 更新 issue 状态或标签
Issue 获取方式
- 如果传入了
fromText参数,则从fromText中获取。其中branch.delete必传fromText(分支已删除,无法从上下文中获取)。 - 如果没传入
fromText参数,则从上下文中获取。push事件:从本次推送的所有 的提交日志中获取。- Pull Request 类事件:从 PR 中的所有 Commit 的提交日志中获取。
- 其他事件:从最新的一个 Commit 的提交日志中获取。
获取方式:提取上述文本中如下两种格式
#IssueID:表示当前仓库的 Issue。例如 #123,表示当前仓库 id 为 123 的 Issue。groupName/repoName#IssueID:表示跨仓库(其他仓库)的 Issue。例如:test/test#123,表示 test/test 仓库中 id 为 123 的 Issue。
注意 #123 或 test/test#123 前需要有空格。
提交日志中如何带上 IssueID
提交代码时,可以在提交日志中加上关联的 IssueID, 可以在使用当前内置任务时可以自动提取到关联 Issue,用来更新 Issue 标签和状态
推荐在提交日志的 body 中带上 IssueID,命令行操作方式如下:
- 方法一:用
shift + enter换行,建议 title 和 body 之间加上一个空行
git commit -m "fix(云原生构建): 修复一个错误
cnb/feedback#123"- 方法二:
以下提交方式 title 和 body 之间会产生两个换行
git commit -m "fix(云原生构建): 修复一个错误" -m "cnb/feedback#123"参数
fromText
- type:
String - required:
false
从给定的文本中解析 IssueId。
不声明时,自动从上下文里的提交记录解析。
可以指定一个包含
IssueId引用的文本来声明操作对象,比如:${LATEST_CHANGE_LOG}。
state
- type: IssueStateMap
- required:
false
对应 state 属性,为 close 时,可关闭 Issue。
label
- type: UpdateLabel
- required:
false
对 label 的操作描述。
when
- type: IssueUpdateStatus
- required:
false
过滤条件,多个条件之间是 or 关系。为空时表示对所有 Issue 操作。
lint
- type: IssueUpdateStatus
- required:
false
检查 Issue 是否满足条件,不满足时抛出异常,多个条件之间是 or 关系,为空时表示不做检查。
defaultColor
- type:
String - required:
false
添加的标签的默认颜色,当有传入 label.add 参数时才有效。
类型定义
IssueStateMap
Enum<String>: open | close
UpdateLabel
- add
- type:
Array<String>|String - required:
false
- type:
要添加的标签列表,标签不存在时,会自动创建。
- remove
- type:
Array<String>|String - required:
false
- type:
要移除的标签列表
IssueUpdateStatus
- label
- type:
Array<String>|String - required:
false
- type:
标签,多个值之间是 or 关系
输出结果
{
issues // issue 列表
}权限检查
若需要更新的 Issue 属于流水线所属仓库, 且非 pull_request, pull_request.update, pull_request.approved, pull_request.changes_requested 事件, 则不会检查流水线触发者是否拥有修改 Issue 的权限。
配置样例
- 合并到 main 后,更新标签
main:
push:
- stages:
- name: update issue
type: git:issue-update
options:
# 移除 “开发中” 标签,添加 “预发布” 标签
label:
add: 预发布
remove: 开发中
# 当有 “feature” 或 “bug” 标签才进行上述标签操作
when:
label:
- feature
- bug- Tag push 时,关闭 Issue,更新标签
$:
tag_push:
- stages:
- name: 发布操作
script: echo "可用发布任务替代当前任务"
# 发布操作后执行 issue 更新操作
- name: update issue
type: git:issue-update
options:
# 关闭 issue
state: close
# 移除 “预发布” 标签,添加 “已发布” 标签
label:
add: 已发布
remove: 预发布
# 当有 “feature” 或 “bug” 标签才进行上述操作
when:
label:
- feature
- bug- 根据 changelog 添加标签
$:
tag_push:
- stages:
- name: changelog
image: cnbcool/changelog
exports:
latestChangeLog: LATEST_CHANGE_LOG
- name: update issue
type: git:issue-update
options:
fromText: ${LATEST_CHANGE_LOG}
label:
add: 需求已接收
when:
label: featurereviewer
git:reviewer
配置评审人或处理人给 PR 添加、删除评审人/处理人,可指定备选评审人/处理人范围。
适用事件
pull_requestpull_request.targetpull_request.update
pull_request 和 pull_request.update 事件下会检查触发者是否有权限操作评审人/处理人。pull_request.target 事件下则不会。 对于跨仓提交的 PR,可能存在触发者无权限的情况。此时推荐使用 pull_request.target 事件。
参数
type
- type: REVIEW_OPERATION_TYPE
- required:
false - default:
add-reviewer
操作类型:
add-reviewer: 添加评审人,会从reviewers参数中选择指定数量的评审人add-reviewer-from-repo-members: 从仓库直接成员里选一名,添加为评审人add-reviewer-from-group-members: 从仓库父组织(直接上级组织)里选一名,添加为评审人add-reviewer-from-outside-collaborator-members: 从仓库的外部协作者里选一名,添加为评审人remove-reviewer: 从已有的评审人中删除指定的成员add-assignee: 添加处理人,添加reviewers参数传入的成员remove-assignee: 从已有的处理人中删除指定的成员
reviewers
- type:
Array<String>|String - required:
false
要添加或删除的评审人用户名。多个使用 , 或 ; 分隔。
type 为 add-reviewer、remove-reviewer、add-assignee、remove-assignee 时有效。
若同时配置了 reviewers 、 reviewersConfig ,则会在两者中随机选指定数量的评审人或处理人
count
- type:
Number - required:
false
指定要添加的评审人或处理人数量,随机抽取指定数量的评审人或处理人。
- 当
type为add-reviewer或add-assignee时,count缺省值为reviewers的数量,即全部添加 - 当
type为add-reviewer-from-repo-members、add-reviewer-from-group-members或add-reviewer-from-outside-collaborator-members时:- 若目标分支为保护分支且设置了需要评审人批准,
count缺省值为需要批准的评审人数量 - 其他情况,
count缺省值为 1
- 若目标分支为保护分支且设置了需要评审人批准,
如果已有评审人或处理人的数量 < count ,那么补齐。
如果已有评审人或处理人的数量 >= count ,那么什么也不做。
exclude
- type:
Array<String>|String - required:
false
排除指定的用户。
reviewersConfig
- type: IReviewersConfig |
String - required:
false
文件评审人或处理人配置,如果配置中有配置当前变更文件的评审人或处理人,则会被添加为评审人或处理人。
type 为 add-reviewer 或 add-assignee 时有效。
支持两种格式:
- 字符串格式,传入配置文件相对路径(支持
json文件):
{
"reviewersConfig": "config.json"
}{
"./src": "name1,name2",
".cnb.yml": "name3"
}- 对象格式,传入文件评审人配置:
{
"reviewersConfig": {
"./src": "name1,name2",
".cnb.yml": "name3"
}
}其中,文件评审人或处理人配置的 key 为文件相对路径;value 为评审人或处理人英文名,用英文逗号分隔。
若同时配置了 reviewers 、reviewersConfig,则会在两者中随机选指定数量的评审人或处理人。
role
- type: ROLE_TYPE
- required:
false
评审人或处理人可以添加的角色可选包括:Developer、Master、Owner 如果选择 Developer,则可添加 Developer 及以上权限成员,包括 Developer、Master、Owner
skip_on_wip
- type:
Boolean - required:
false - default:
true
是否跳过 WIP 状态的 PR(PR 标题开头带有 [WIP] 标记),默认跳过 WIP 状态的 PR。
true: 当 PR 为WIP状态时,不会添加评审人或处理人。false: 当 PR 为WIP状态时,仍会添加评审人或处理人。
类型定义
REVIEW_OPERATION_TYPE
Enum<String>: add-reviewer | add-reviewer-from-repo-members | add-reviewer-from-group-members | add-reviewer-from-outside-collaborator-members | remove-reviewer | add-assignee | remove-assignee
IReviewersConfig
{
[key: String]: String
}ROLE_TYPE
Enum<String>: Developer | Master | Owner
输出结果
添加评审人的输出结果:
{
// 当前有效的评审人
"reviewers": [],
// reviewers 对应的 at 消息格式,方便发送通知
"reviewersForAt": []
}添加处理人的输出结果:
{
// 当前有效的处理人
"assignees": [],
// assignees 对应的 at 消息格式,方便发送通知
"assigneesForAt": []
}配置样例
- 添加评审人和处理人
main:
pull_request:
- stages:
- name: 添加评审人
type: git:reviewer
options:
type: add-reviewer
reviewers: aaa;bbb
- name: 添加处理人
type: git:reviewer
options:
type: add-assignee
reviewers: ccc;ddd- 删除指定成员的评审人和处理人
main:
pull_request:
- stages:
- name: 删除评审人
type: git:reviewer
options:
type: remove-reviewer
reviewers: aaa
- name: 删除处理人
type: git:reviewer
options:
type: remove-assignee
reviewers: aaa- 结合
ifModify,指定文件被修改时添加评审人和处理人
main:
pull_request:
- stages:
- name: 改配置?需要特别 review
ifModify:
- ".cnb.yml"
- "configs/**"
type: git:reviewer
options:
type: add-reviewer
reviewers: bbb
- name: 改配置?需要特别处理
ifModify:
- ".cnb.yml"
- "configs/**"
type: git:reviewer
options:
type: add-assignee
reviewers: ccc- 结合
if,在指定条件下将某些人添加为评审人或处理人
main:
pull_request:
- stages:
- name: 下班时间发版本?需指定人评审。
if: |
[ $(date +%H) -ge 18 ]
type: git:reviewer
options:
type: add-reviewer
reviewers: bbb
- name: 下班时间发版本?需指定人处理。
if: |
[ $(date +%H) -ge 18 ]
type: git:reviewer
options:
type: add-assignee
reviewers: ccc- 随机选择一名负责人走查代码
main:
pull_request:
- stages:
- name: random
image: tencentcom/random
settings:
from:
- aaa
- bbb
exports:
result: CURR_REVIEWER
- name: show CURR_REVIEWER
script: echo ${CURR_REVIEWER}
- name: add reviewer
type: git:reviewer
options:
type: add-reviewer
reviewers: ${CURR_REVIEWER}- 从当前仓库成员里选一名评审人进行评审
main:
pull_request:
- stages:
- name: add reviewer
type: git:reviewer
options:
type: add-reviewer-from-repo-members最佳实践
建立专用的 CR 群,交叉评审自动合并
- PR 随机选择 N 名评审者,通知到群
- 评审通过后自动合并
- 记录评审者信息在提交信息中
- Git 设置满足多人评审自动合并策略实现多人交叉评审
main:
review:
- stages:
- name: CR 通过后自动合并
type: git:auto-merge
options:
mergeType: squash
removeSourceBranch: true
mergeCommitMessage: $CNB_LATEST_COMMIT_MESSAGE
exports:
reviewedBy: REVIEWED_BY
# 将评审消息发送到企业微信机器人
- name: notify
image: tencentcom/wecom-message
settings:
msgType: markdown
robot: "155af237-6041-4125-9340-000000000000"
content: |
> CR 通过后自动合并 <@${CNB_BUILD_USER}>
>
> ${CNB_PULL_REQUEST_TITLE}
> [${CNB_EVENT_URL}](${CNB_EVENT_URL})
>
> ${REVIEWED_BY}
pull_request:
- stages:
# ...省略其它任务
# 发送到 CR 专用群
- name: add reviewer
type: git:reviewer
options:
reviewers: aaa,bbb,ccc,ddd
count: 2
exports:
reviewersForAt: CURR_REVIEWER_FOR_AT
- name: notify
image: tencentcom/wecom-message
settings:
msgType: markdown
robot: "155af237-6041-4125-9340-000000000000"
message: |
> ${CURR_REVIEWER_FOR_AT}
>
> ${CNB_PULL_REQUEST_TITLE}
> [${CNB_EVENT_URL}](${CNB_EVENT_URL})
>
> from ${CNB_BUILD_USER}release
git:release
仓库发布 Release
适用事件
pushcommit.addbranch.createtag_pushpull_request.mergedapi_triggerweb_triggertag_deploy
参数
提示
该内置任务不支持上传附件, 可使用 cnbcool/attachments 任务上传附件。
overlying
- type:
Boolean - required:
false - default:
false
叠加模式
true:叠加模式,即本次仅为编辑或更新 Release。false:非叠加模式,即先删除,再重新创建 Release。
注意
默认为 false,即,当 Release 版本已经存在时,会先删除这个版本,重新生成。
tag
- type:
String|Number - required:
false
release 对应的 Tag 名,非必填
tag_push 事件无需传入,直接取触发 tag_push 事件的 Tag 名。
非 tag_push 事件必填,用来作为 Releas 对应的 Tag 名。
title
- type:
String - required:
false - default:
tag名
Release 的标题
description
- type:
String - required:
false
Release 的描述
preRelease
- type:
Boolean - required:
false - default:
false
是否将 release 设置为 预发布
latest
- type: "true" | "false" | true | false
- required:
false - default:
false
是否将 Release 设置为最新版本
输出结果
无
配置样例
- 生成 changelog 并自动更新 Release 描述
$:
tag_push:
- stages:
- name: changelog
image: cnbcool/changelog
exports:
latestChangeLog: LATEST_CHANGE_LOG
- name: upload release
type: git:release
options:
title: release
description: ${LATEST_CHANGE_LOG}- 主分支 push 时发布 Release
main:
push:
- stages:
- name: git release
type: git:release
options:
tag: Nightly
description: descriptionpr-commit-message-preset
git:pr-commit-message-preset
预先设置 PR 的 提交信息。
当用户在 PR 界面中选择 Merge 或者 Squash 合并时,会自动将该 message 填入提交消息内。
适用事件
pull_requestpull_request.targetpull_request.updatepull_request.mergeablepull_request.approvedpull_request.changes_requested
参数
message
- type:
String - required:
true
预先设置的 PR 的 提交信息。
输出结果
无
配置样例
main:
pull_request:
- stages:
- name: prepare pull request commit message
type: git:pr-commit-message-preset
options:
message: Pull request commit message set by CI.pr-update
git:pr-update
更新 PR 的标签、标题。
适用事件
参数
fromText
- type:
String - required:
false
从给定的文本中解析 PR。
需要满足以下格式中的一个:
PR-URL: <your-repo-slug>#<number>PR-URL: #<number>
your-repo-slug 为仓库的路径,比如 cnbcool/cnb。 number 为 PR 的编号,为 PR 页面地址后的数字。
为了和 Issue 区分,需要在前面加上 PR-URL:。
若不传入 fromText,则会按照以下规则组装 fromText:
PR相关事件:以流水线所属仓库和 PR 编号组装为PR-URL: <current-repo-slug>#<number>,如PR-URL: cnbcool/cnb#123。环境变量
CNB_BEFORE_SHA有值且非0000000000000000000000000000000000000000: 获取 CNB_BEFORE_SHA(不包括) 到 CNB_COMMIT 提交历史里的提交信息。如:
commit2
PR-URL: #456
commit1
PR-URL: group1/repo1#123- 其他情况:获取 CNB_COMMIT的提交信息,如:
commit1
PR-URL: group1/repo1#123
PR-URL: #456label
- type: UpdateLabel
- required:
false
需要添加、删除的标签。
title
- type:
String - required:
false
PR 的标题。
defaultColor
- type:
String - required:
false
添加的标签的默认颜色,当有传入 label.add 参数时才有效。
输出结果
{
pullRequests // 修改的 pr 列表
}权限检查
若需要更新的 PR 属于流水线所属仓库, 且非 pull_request, pull_request.update, pull_request.approved, pull_request.changes_requested 事件, 则不会检查流水线触发者是否拥有修改 PR 的权限。
配置样例
如下流水线实现了以下功能:
pull_request流水线失败,增加标签待修改。pull_request流水线成功,增加标签待评审,删除标签待修改。pull_request.merged流水线,增加标签待发布,删除标签待评审。
main:
pull_request:
- stages:
- name: check
script: echo "do some check"
- name: 添加PR标签-待评审
type: git:pr-update
options:
label:
add:
- 待评审
remove:
- 待修改
failStages:
- name: 添加PR标签-待修改
type: git:pr-update
options:
label:
add:
- 待修改
pull_request.merged:
- stages:
- name: check
script: echo "do some check"
- name: 添加PR标签-待发布
type: git:pr-update
options:
label:
add:
- 待发布
remove:
- 待评审testing
coverage
testing:coverage
单测覆盖率,通过单测结果报告,计算单测覆盖率结果,并上报徽章数据。
可以在仓库的 洞察 页面以图表的形式按分支查看最近 100 个 Commit 的覆盖率徽章数据上报结果。
提示
Pull Request 相关事件(除了 pull_request.merged)触发的流水线上传的覆盖率数据,要查看单元测试洞察曲线,需要切换到合并请求视图。
适用事件
全量覆盖率
从本地覆盖率报告文件解析而来,目前可识别以下格式的报告:
json(js)(推荐使用)json-summarylcov(推荐使用)jacocogolang
增量覆盖率
参数
pattern
- type:
String - required:
false
Glob 格式,指定覆盖率报告文件位置,相对于当前工作目录。 缺省时,将尝试查找当前目录(包括子目录)下的以下文件:coverage.json、jacoco*.xml、lcov.info、*.lcov。
lines
- type:
Number - required:
false
指定全量覆盖率红线,判断如果全量覆盖率百分比小于该值,阻断工作流退出流水线。
diffLines
- type:
Number - required:
false
指定增量覆盖率红线,判断如果全量覆盖率百分比小于该值,阻断工作流退出流水线。 pull_request、pull_request.update、pull_request.target 事件支持计算增量覆盖率结果,其他事件只计算全量覆盖率。
allowExts
- type:
String - required:
false
参与覆盖率计算的代码文件类型白名单,逗号分隔, 如:.json, .ts, .js。 缺省时报告中的文件都会参与计算。
lang
- type:
String - required:
false
当覆盖率结果报告目标格式为 golang 时,请指定此参数 为 go,否则会出现计算误差。其他情况可忽略该参数。
breakIfNoCoverage
- type:
Boolean - required:
false
没有找到覆盖率报告文件时,是否抛出错误终止流程。
输出结果
{
// 代码行覆盖率,例如 100,计算出错时值为 NA
"lines": 100,
// 代码增量行覆盖率,例如 100,计算出错时值为 NA
"diff_pct": 100
}配置样例
main:
push:
- stages:
- name: coverage
type: testing:coverage
options:
breakIfNoCoverage: false
exports:
lines: LINES
- name: result
script: echo $LINESartifact
remove-tag
artifact:remove-tag
删除 CNB 制品标签,目前仅删除支持 CNB Docker 和 Helm 标签。需要有仓库写权限。
适用事件
pushcommit.addtag_pushtag_deploypull_request.mergedapi_triggerweb_triggercrontabbranch.create
参数
name
- type:
String - required:
true
制品包名
tags
- type:
Array<string> - required:
true
type
- type:
String - required:
false - default:
docker
制品类型,目前仅支持 Hocker 和 Helm
配置样例
main:
push:
- stages:
- name: remove tag
type: artifact:remove-tag
options:
# 包名
# 包名示例1,仓库同名制品:reponame
# 包名示例2,仓库非同名制品:reponame/name
name: reponame/name
tags:
- tag1
- tag2
type: docker