Environment Variables

Environment variables can be used during the build process. Cloud Native Build provides some default environment variables.

# Declaring Environment Variables

  1. Declare environment variables using env.
  2. Environment variables declared in the Pipeline are valid for the current Pipeline.
  3. Environment variables declared in the Job are valid for the current Job.
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

  1. Use imports to point to a private Git repository file to inject private tokens into environment variables.
  2. When there is a conflict between env and imports 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:

  1. They can only contain letters (both uppercase and lowercase), numbers, and underscores (_).
  2. The first character cannot be a number.

Variables that do not comply with the above rules will be ignored.

# Export Environment Variables

You can modify, add, or delete environment variables within a Job using the exports property, which has a lifecycle within the current Pipeline.

exports:
  from-key: to-key
  • exports is an object where the object's key is the key of the output object of this Job, and the value is the mapped environment variable name.
    • from-key specifies the original key to be transformed, supports environment variables, and supports deep value retrieval, referring to lodash.get.
    • to-key specifies the transformed key.

# Exporting Environment Variables from Jobs' Return Values

The script task allows you to define custom scripts and has the following properties:

  • code: Exit code

  • stdout: Standard output

  • stderr: Standard error

  • info: Mixed output of standard output and standard error in chronological order

    TIP

    Note: It is recommended to use printf "%s" "hello\nworld" to output variables to eliminate the trailing newline character in the standard output stream while preserving escape characters like \n.

When using conditional logic such as if, ifModify, ifNewBranch, you can set the following properties:

  • skip: If not skipped, it returns an empty string; if skipped, it returns the reason for skipping (if, ifModify, ifNewBranch).
- name: use if
  if: exit -1
  exports:
    skip: REASON
- name: tell last
  script: echo $REASON # The value of $REASON is the string "if"

# Modifying Environment Variables

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: tag
          type: xxx:xxxx
          exports:
            # Supports deep value retrieval
            nextRelease.gitTag: CUSTOM_ENV_GIT_TAG
        - 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

# Exporting Environment Variables from 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
        - name: echo env
          script:
            - echo $CUSTOM_ENV_VERSION
            - echo $CUSTOM_ENV_URL

# 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