环境变量
在构建过程中可以使用环境变量,云原生构建 内置了一些默认环境变量。
声明环境变量
- 通过
env声明环境变量 - 在
Pipeline里声明的环境变量对当前Pipeline有效 - 在
Job里声明的环境变量对当前Job有效
1main:
2 push:
3 - env:
4 RELEASE_MSG: release message
5 stages:
6 - name: release
7 type: git:release
8 env:
9 RELEASE_NAME: release-1
10 options:
11 description: ${RELEASE_MSG}
12 name: ${RELEASE_NAME}
导入环境变量
- 通过
imports导入一个密钥仓库文件,可将敏感信息注入到环境变量,供后续任务使用。 - 当
env和imports的key冲突时,优先使用env
1main:
2 push:
3 - services:
4 - docker
5 # 导入密钥仓库文件为环境变量
6 imports: https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/envs.yml
7 stages:
8 - name: docker info
9 script: docker info
10 - name: docker login
11 # 其中 TEST_DOCKER_DOMAIN、TEST_DOCKER_USER、TEST_DOCKER_PWD 为密钥仓库文件中的变量
12 script: docker login $TEST_DOCKER_DOMAIN -u $TEST_DOCKER_USER -p $TEST_DOCKER_PWD
https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/envs.yml 内容示例
1# docker 镜像源域名
2TEST_DOCKER_DOMAIN: registry.example.com
3# docker 用户名
4TEST_DOCKER_USER: your_docker_username
5# docker 密码
6TEST_DOCKER_PWD: your_docker_password
变量名限制
在 Shell 中,环境变量名的命名规则有一些限制。根据 POSIX 标准,环境变量名应符合以下规则:
- 只能包含字母(大小写均可)、数字和下划线(_)字符。
- 第一个字符不能是数字。
不符合上述规则的变量会被忽略
导出环境变量
Job 执行结束后,有一个 result 对象,可通过 exports 将 result 中的属性导出到环境变量,生命周期为当前 Pipeline。
语法格式为:
1exports:
2 from-key: to-key
from-key要导出的Job result对象中的属性名,支持环境变量,支持深层取值,参考lodash.get。to-key映射到环境变量中的变量名。
有如下三种方式设置 result:
脚本任务执行结果
解析输出中的自定义变量
内置任务的 result
脚本任务执行结果
script 自定义脚本任务执行完,Job result的属性有:
code: 返回码stdout: 标准输出stderr: 标准错误info: 标准输出、标准错误,按时序的混合体
注意:可使用 printf "%s" "hello\nworld" 来输出变量,以消除标准输出流最后的换行符,同时保留 \n 等转义字符。
1main:
2 push:
3 - stages:
4 - name: set env
5 script: echo -n $(date "+%Y-%m-%d %H:%M")
6 exports:
7 code: CUSTOM_ENV_DATE_CODE
8 info: CUSTOM_ENV_DATE_INFO
9 - name: echo env
10 script:
11 - echo $CUSTOM_ENV_DATE_CODE
12 - echo $CUSTOM_ENV_DATE_INFO
包含 if、ifModify、ifNewBranch 等判断逻辑时,可设置的属性有:
skip: 如果执行上述判断逻辑后跳过任务执行则返回跳过原因,否则为空字符串。
1- name: use if
2 if: exit -1
3 exports:
4 skip: REASON
5- name: tell last
6 # $REASON 的值为 if 这个字符串
7 script: echo $REASON
解析输出中的自定义变量
CI 会从标准输出流里按行识别 ##[set-output key=value] 格式的内容,自动放入 result 对象中。
若变量值包含换行符 \n,可对变量值进行 base64 或 escape 编码。
变量值若以 base64, 开始,云原生构建 会对 base64, 后面的内容做 base64 解码,否则会对变量值做 unescape 解码。
使用 Node.js 示例代码如下:
1// test.js
2const value = "测试字符串\ntest string";
3// 输出 base64 编码的变量值
4console.log(
5 `##[set-output redline_msg_base64=base64,${Buffer.from(value, "utf-8").toString("base64")}]`,
6);
7
8// 输出 escape 编码的变量值
9console.log(`##[set-output redline_msg_escape=${escape(value)}]`);
1main:
2 push:
3 - docker:
4 image: node:20-alpine
5 stages:
6 - name: set output env
7 script: node test.js
8 # 将 test.js 输出的变量导出为环境变量
9 exports:
10 redline_msg_base64: BASE64_KEY
11 redline_msg_escape: ESCAPE_KEY
12 - name: echo env
13 script:
14 - echo "BASE64_KEY $BASE64_KEY"
15 - echo "ESCAPE_KEY $ESCAPE_KEY"
使用 echo 示例代码如下:
1main:
2 push:
3 - stages:
4 - name: set output env
5 script: echo "##[set-output redline_msg_base64=base64,$(echo -e "测试字符串\ntest string" | base64 -w 0)]"
6 exports:
7 redline_msg_base64: BASE64_KEY
8 - name: echo env
9 script:
10 - echo -e "BASE64_KEY $BASE64_KEY"
注意:在 Unix-like 系统中,base64 命令默认会在每76个字符后添加一个换行符,可使用 -w 0 选项来禁用换行避免 CI 未能按行解析出变量。
不包含 \n 的变量值可直接输出
1echo "##[set-output redline_msg=some value]"
:::tip 受限于系统环境变量值长度限制,过大的变量值无效。
CI 会忽略大于等于 100KB 的变量值。可写入文件中自行解析。
对于敏感信息,建议使用 read-file 内置任务。 :::
内置任务中导出环境变量
一些内置任务会有输出结果,可通过 exports 导出为环境变量。
1main:
2 push:
3 - stages:
4 - name: xxxx
5 type: xxx:xxx
6 options:
7 product: public
8 name: cnb
9 dist: release/
10 exports:
11 version: CUSTOM_ENV_VERSION
12 url: CUSTOM_ENV_URL
13 #支持对象深层取值
14 nextRelease.gitTag: CUSTOM_ENV_GIT_TAG
15 - name: echo env
16 script:
17 - echo $CUSTOM_ENV_VERSION
18 - echo $CUSTOM_ENV_URL
result 内容参考各内置任务文档。
增删改查环境变量
可以覆盖已有的环境变量,设为空字符串或 null 即为删除。
1main:
2 push:
3 - env:
4 CUSTOM_ENV_DATE_INFO: default
5 CUSTOM_ENV_FOR_DELETE: default
6 stages:
7 - name: set env
8 script: echo -n $(date "+%Y-%m-%d %H:%M")
9 exports:
10 # 新增
11 code: CUSTOM_ENV_DATE_CODE
12 # 修改
13 info: CUSTOM_ENV_DATE_INFO
14 # 删除
15 CUSTOM_ENV_FOR_DELETE: null
16 # 删除
17 # CUSTOM_ENV_FOR_DELETE:
18 - name: echo env
19 script:
20 - echo $CUSTOM_ENV_DATE_CODE
21 - echo $CUSTOM_ENV_DATE_INFO
22 - echo $CUSTOM_ENV_DATE_STDOUT
23 - echo $CUSTOM_ENV_FOR_DELETE
24 - echo $CUSTOM_ENV_GIT_TAG
使用环境变量
在 脚本任务 中使用
执行脚本任务时,流水线设置的环境变量作为任务执行时的环境变量
1main:
2 push:
3 - stages:
4 - name: test internal env
5 # CNB_BRANCH 为内置环境变量
6 script: echo $CNB_BRANCH
7 - name: test self defined env
8 env:
9 cat_name: tomcat
10 script: echo $cat_name
变量替换
配置文件中的一些属性值会进行变量替换。
如有环境变量 env_name=env_value,那么属性值中 $env_name 会被替换成 env_value,若 env_name 无值,则会替换成空字符串。
下面列出了会进行变量替换的属性:
- 内置任务
内置任务 options 内的属性值和 optionsFrom 会进行变量替换。
1# options.yml
2name: Nightly
1main:
2 push:
3 - env:
4 address: options.yml
5 description: publish for xx task
6 stages:
7 - name: git release
8 type: git:release
9 # $address 会被替换成 env 中的 "options.yml"
10 optionsFrom: $address
11 # options.yml 中的 name 会合并到 options 中
12 options:
13 # $description 会被替换成 env 中的 "publish for xx task"
14 description: $description
options 的最终内容为:
1name: Nightly
2description: publish for xx task
- 插件任务
插件任务 settings 内的属性值和 settingsFrom 会进行变量替换。
1# settings.yml
2robot: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
1main:
2 push:
3 - env:
4 address: settings.yml
5 message: pr check
6 stages:
7 - name: notify
8 image: tencentcom/wecom-message
9 # $address 会被替换成 env 中的 "settings.yml"
10 settingsFrom: $address
11 # settings.yml 中的 robot 会合并到 settings 中
12 settings:
13 # $message 会被替换成 env 中的 "pr check"
14 content: $message
settings 的最终内容为:
1robot: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
2message: pr check
另外写在 Dockerfile 中的 LABEL 指定的 settingsFrom 同样可以进行变量替换
1FROM node:20
2
3LABEL cnb.cool/settings-from="$address"
- env
env 下声明的属性值可以引用上层 env 中的变量进行替换
1# .cnb.yml
2main:
3 push:
4 - env:
5 cat_name: tomcat
6 stages:
7 - name: echo env
8 env:
9 # 使用上层 env 声明的 cat_name 值进行替换
10 name: "cat $cat_name"
11 # 输出 cat tomcat
12 script: echo $name
- imports
imports 的属性值以及所声明的文件中的属性值均会进行变量替换。
若 imports 为数组,数组前面文件中声明的变量对数组后面元素有效。
1# env1.yml
2address: env2.yml
3platform: amd64
1# env2.yml
2# 读取 env1.yml 中的 platform 属性值进行替换
3action: build for $platform
1# .cnb.yml
2main:
3 push:
4 - imports:
5 - env1.yml
6 # env1.yml 中声明了 address,$address 会被替换成 env2.yml
7 - $address
8 stages:
9 - name: echo action
10 # 读取 env2.yml 中的 action 属性值进行替换
11 script: echo $action
- pipeline.runner.tags
1# 构建不同架构下的镜像
2.build: &build
3 runner:
4 tags: cnb:arch:$CNB_PIPELINE_NAME
5 services:
6 - docker
7 stages:
8 - name: docker build
9 script: echo "docker build for $CNB_PIPELINE_NAME"
10main:
11 push:
12 # 下面 "amd64" 和 "arm64:v8" 会被声明为内置环境变量 CNB_PIPELINE_NAME 的值
13 amd64: *build
14 "arm64:v8": *build
- pipeline.docker.volumes
1.docker-volume: &docker-volume
2 docker:
3 image: node:22-alpine
4 volumes:
5 - $volume_path
6main:
7 push:
8 install:
9 env:
10 volume_path: node_modules
11 <<: *docker-volume
12 stages:
13 - name: install
14 script: npm install axios
15 # 通知其他流水线执行
16 - name: resolve
17 type: cnb:resolve
18 options:
19 key: install
20 build:
21 env:
22 volume_path: node_modules
23 <<: *docker-volume
24 stages:
25 # 等待 install 流水线
26 - name: await
27 type: cnb:await
28 options:
29 key: install
30 - name: ls
31 script: ls node_modules
- ifModify
1# 不同模块下代码有变更才进行对应模块的编译
2.build: &build
3 ifModify: $CNB_PIPELINE_NAME/*
4 stages:
5 - name: build $CNB_PIPELINE_NAME
6 script: echo "build $CNB_PIPELINE_NAME"
7main:
8 push:
9 module-a: *build
10 module-b: *build
- name
pipeline.name 、stage.name 和 job.name 的属性值会进行变量替换。
1main:
2 push:
3 - name: build in $CNB_REPO_SLUG
4 env:
5 platform: amd64
6 imports:
7 - env1.yml
8 - env2.yml
9 stages:
10 - name: stage_$SOME_ENV
11 script: echo "hello world"
- lock.key
1# env.yml
2build_key: build key
1.build: &build
2 imports: env.yml
3 lock:
4 key: $build_key
5 stages:
6 - name: echo
7 script: echo "hello world"
8main:
9 push:
10 # 以下两条流水线,一条占用了锁成功执行,另一条位占到锁执行失败
11 - *build
12 - *build
- allowFailure
1main:
2 push:
3 - env:
4 allow_fail: true
5 stages:
6 - name: echo
7 allowFailure: $allow_fail
8 # 脚本执行会报错,但 allowFailure 为 true,任务被认为是成功的
9 script: echo1 1
阻止变量替换
如果不希望 $env_name 被替换,可以通过 \$ 阻止替换
1main:
2 push:
3 - stages:
4 - name: git release
5 type: git:release
6 options:
7 name: Development
8 # 属性值是 "some code update $description"
9 description: some code update \$description
限制
环境变量名需由字母、数字或 _ 组成,不能以数字开头。
变量值的长度不能超过 100KiB。