Environment Variables
Environment variables can be used during the build process.
Cloud Native Build
provides some default environment variables.
# Declaring Environment Variables
- Declare environment variables using
env
. - Environment variables declared in the
Pipeline
are valid for the currentPipeline
. - Environment variables declared in the
Job
are valid for the currentJob
.
main:
push:
- env:
RELEASE_MSG: release message
stages:
- name: release
type: git:release
env:
RELEASE_NAME: release-1
options:
description: ${RELEASE_MSG}
name: ${RELEASE_NAME}
# Importing Environment Variables
- Use
imports
to point to aprivate
Git repository file to inject private tokens into environment variables. - When there is a conflict between
env
andimports
keys,env
takes priority.
main:
push:
- services:
- docker
imports: https://xxx/envs.yml
stages:
- name: docker info
script: docker info
- name: docker login
script: docker login ${imageDomain} -u $TEST_DOCKER_USER -p $TEST_DOCKER_PWD
Example content of https://xxx/envs.yml
:
TEST_DOCKER_USER: your_docker_username
TEST_DOCKER_PWD: your_docker_password
TEST_NPM_USER: your_npm_username
TEST_NPM_PWD: your_npm_password
whatever_key_you_want: whatever_value_you_want
# Variable Name Restrictions
In Shell, there are certain restrictions on naming environment variables. According to the POSIX standard, environment variable names should adhere to the following rules:
- They can only contain letters (both uppercase and lowercase), numbers, and underscores (_).
- The first character cannot be a number.
Variables that do not comply with the above rules will be ignored.
# Exporting Environment Variables
After the execution of a Job
, there is a result
object.
You can use exports to export the properties from the result
object to environment variables,
which will be available during the current Pipeline
lifecycle.
The syntax format is as follows:
exports:
from-key: to-key
from-key
is the property name from theJob result
object that you want to export. It supports environment variables and deep value retrieval, referring tolodash.get
.to-key
is the variable name to be mapped to the environment variable.
There are three ways to set the result:
Script task execution result
Custom variables from the parsed output
Result from built-in tasks
# Script Task Execution Result
After the execution of a custom script
task, the Job result
object has the following properties:
code
: Return codestdout
: Standard outputstderr
: Standard errorinfo
: Mixed output of standard output and standard error in chronological order
Note: You can use printf "%s" "hello\nworld"
to output variables, which eliminates the trailing newline character in the standard output stream while preserving escape characters like \n
.
main:
push:
- stages:
- name: set env
script: echo -n $(date "+%Y-%m-%d %H:%M")
exports:
code: CUSTOM_ENV_DATE_CODE
info: CUSTOM_ENV_DATE_INFO
- name: echo env
script:
- echo $CUSTOM_ENV_DATE_CODE
- echo $CUSTOM_ENV_DATE_INFO
When using conditional logic such as if
, ifModify
, ifNewBranch
, the following properties can be set:
skip
: If the task execution is skipped based on the above conditional logic, it returns the reason for skipping; otherwise, it is an empty string.
- name: use if
if: exit -1
exports:
skip: REASON
- name: tell last
# The value of $REASON is the string "if"
script: echo $REASON
# Parsing Custom Variables from Output
CI will recognize the content in the standard output stream in the format ##[set-output key=value]
and automatically place it into the result
object.
If the variable value contains newline characters \n
, you can encode the variable value using base64
or escape
.
If the variable value starts with base64,
,
the Cloud Native Build
will decode the content after base64,
using base64
decoding.
Otherwise, it will decode the variable value using unescape
.
Here is an example using Node.js
:
// test.js
const value = '测试字符串\ntest string';
// Output the base64 encoded variable value
console.log(`##[set-output redline_msg_base64=base64,${Buffer.from(value, 'utf-8').toString('base64')}]`);
// Output the escape encoded variable value
console.log(`##[set-output redline_msg_escape=${escape(value)}]`)
main:
push:
- docker:
image: node:20-alpine
stages:
- name: set output env
script: node test.js
# Export the variables output from test.js as environment variables
exports:
redline_msg_base64: BASE64_KEY
redline_msg_escape: ESCAPE_KEY
- name: echo env
script:
- echo "BASE64_KEY $BASE64_KEY"
- echo "ESCAPE_KEY $ESCAPE_KEY"
Here is an example using echo
:
main:
push:
- stages:
- name: set output env
script: echo "##[set-output redline_msg_base64=base64,$(echo -e "测试字符串\ntest string" | base64 -w 0)]"
exports:
redline_msg_base64: BASE64_KEY
- name: echo env
script:
- echo -e "BASE64_KEY $BASE64_KEY"
Note: In Unix-like systems, the base64
command by default adds a newline character after every 76 characters. You can use the -w 0
option to disable the newline character to ensure that the CI can parse the variable on a single line.
For variable values that do not contain \n
, you can directly output them:
echo "##[set-output redline_msg=some value]"
TIP
Due to the length limitation of system environment variables, very large variable values may not work.
CI will ignore variable values that are greater than or equal to 100KB
. You can write them to a file and parse them manually.
For sensitive information, it is recommended to use the built-in task read-file.
# Exporting Environment Variables in Built-in Tasks
Some built-in tasks have output results that can be exported as environment variables using exports
.
main:
push:
- stages:
- name: xxxx
type: xxx:xxx
options:
product: public
name: cnb
dist: release/
exports:
version: CUSTOM_ENV_VERSION
url: CUSTOM_ENV_URL
# Supports deep value retrieval
nextRelease.gitTag: CUSTOM_ENV_GIT_TAG
- name: echo env
script:
- echo $CUSTOM_ENV_VERSION
- echo $CUSTOM_ENV_URL
Please refer to the documentation of each built-in task for the content of the result
.
# Modifying Environment Variables
You can override existing environment variables by setting them to an empty string or null
to delete them.
main:
push:
- env:
CUSTOM_ENV_DATE_INFO: default
CUSTOM_ENV_FOR_DELETE: default
stages:
- name: set env
script: echo -n $(date "+%Y-%m-%d %H:%M")
exports:
# Add
code: CUSTOM_ENV_DATE_CODE
# Modify
info: CUSTOM_ENV_DATE_INFO
# Delete
CUSTOM_ENV_FOR_DELETE: null
# Delete
# CUSTOM_ENV_FOR_DELETE:
- name: echo env
script:
- echo $CUSTOM_ENV_DATE_CODE
- echo $CUSTOM_ENV_DATE_INFO
- echo $CUSTOM_ENV_DATE_STDOUT
- echo $CUSTOM_ENV_FOR_DELETE
- echo $CUSTOM_ENV_GIT_TAG
# Using Environment Variables
# Using in Script Tasks
When executing script tasks, the environment variables set in the pipeline are available as environment variables during task execution.
main:
push:
- stages:
- name: test internal env
# CNB_BRANCH is a built-in environment variable
script: echo $CNB_BRANCH
- name: test self defined env
env:
cat_name: tomcat
script: echo $cat_name
# Variable Substitution
Some property values in the configuration file undergo variable substitution.
If there is an environment variable env_name=env_value
,
then the property value $env_name
will be replaced with env_value
.
If env_name
has no value, it will be replaced with an empty string.
The following properties undergo variable substitution:
- Built-in tasks
The property values within the options of built-in tasks and optionsFrom undergo variable substitution.
# options.yml
name: Nightly
main:
push:
- env:
address: options.yml
description: publish for xx task
stages:
- name: git release
type: git:release
# $address will be replaced with "options.yml" from the env
optionsFrom: $address
# The name in options.yml will be merged into options
options:
# $description will be replaced with "publish for xx task" from the env
description: $description
The final content of options will be:
name: Nightly
description: publish for xx task
- Plugin Tasks
The property values within the settings of plugin tasks and settingsFrom undergo variable substitution.
# settings.yml
robot: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
main:
push:
- env:
address: settings.yml
message: pr check
stages:
- name: notify
image: tencentcom/wecom-message
# $address will be replaced with "settings.yml" from the env
settingsFrom: $address
# The robot in settings.yml will be merged into settings
settings:
# $message will be replaced with "pr check" from the env
content: $message
The final content of settings will be:
robot: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
message: pr check
Additionally, the settingsFrom
specified in the Dockerfile's LABEL
can also undergo variable substitution.
FROM node:20
LABEL cnb.cool/settings-from="$address"
- env
The property values declared under env can reference variables from the upper-level env for substitution.
# .cnb.yml
main:
push:
- env:
cat_name: tomcat
stages:
- name: echo env
env:
# Use the cat_name value declared in the upper-level env for substitution
name: "cat $cat_name"
# Output: cat tomcat
script: echo $name
- imports
The property values within imports and the declared property values in the imported files undergo variable substitution.
If imports is an array, the variables declared in the files before an array element are valid for the subsequent elements.
# env1.yml
address: env2.yml
platform: amd64
# env2.yml
# Read the platform property value from env1.yml for substitution
action: build for $platform
# .cnb.yml
main:
push:
- imports:
- env1.yml
# $address will be replaced with env2.yml from env1.yml
- $address
stages:
- name: echo action
# Read the action property value from env2.yml for substitution
script: echo $action
- pipeline.runner.tags
# Building images for different architectures
.build: &build
runner:
tags: cnb:arch:$CNB_PIPELINE_NAME
services:
- docker
stages:
- name: docker build
script: echo "docker build for $CNB_PIPELINE_NAME"
main:
push:
# "amd64" and "arm64:v8" will be declared as the values of the built-in environment variable CNB_PIPELINE_NAME
amd64: *build
"arm64:v8": *build
- pipeline.docker.volumes
.docker-volume: &docker-volume
docker:
image: node:22-alpine
volumes:
- $volume_path
main:
push:
install:
env:
volume_path: node_modules
<<: *docker-volume
stages:
- name: install
script: npm install axios
# Notify other pipelines to execute
- name: resolve
type: cnb:resolve
options:
key: install
build:
env:
volume_path: node_modules
<<: *docker-volume
stages:
# Wait for the install pipeline
- name: await
type: cnb:await
options:
key: install
- name: ls
script: ls node_modules
- ifModify
# Only compile the corresponding module if there are changes in the code
.build: &build
ifModify: $CNB_PIPELINE_NAME/*
stages:
- name: build $CNB_PIPELINE_NAME
script: echo "build $CNB_PIPELINE_NAME"
main:
push:
module-a: *build
module-b: *build
- name
The property values of pipeline.name and job.name undergo variable substitution.
Unlike other property values, the name property can only undergo variable substitution using built-in environment variables.
main:
push:
- name: build in $CNB_REPO_SLUG
env:
platform: amd64
imports:
- env1.yml
- env2.yml
stages:
- name: echo
script: echo "hello world"
- lock.key
# env.yml
build_key: build key
.build: &build
imports: env.yml
lock:
key: $build_key
stages:
- name: echo
script: echo "hello world"
main:
push:
# One of the following two pipelines will acquire the lock and execute successfully, while the other will fail to acquire the lock and not execute.
- *build
- *build
- allowFailure
main:
push:
- env:
allow_fail: true
stages:
- name: echo
allowFailure: $allow_fail
# The script execution will throw an error, but since allowFailure is true, the task will be considered successful
script: echo1 1
# Preventing Variable Substitution
If you don't want $env_name
to be replaced, you can use \$
to prevent substitution.
main:
push:
- stages:
- name: git release
type: git:release
options:
name: Development
# The property value is "some code update $description"
description: some code update \$description