Help us learn about your current experience with the documentation. Take the survey.

在作业脚本中使用 CI/CD 变量

  • 版本:Free, Premium, Ultimate
  • 产品形态:GitLab.com, GitLab Self-Managed, GitLab Dedicated

所有 CI/CD 变量都会在作业的环境中设置为环境变量。 您可以在作业脚本中使用变量,格式遵循对应环境 Shell 的标准语法。

要访问环境变量,请使用您的 Runner 执行器的 Shell 所要求的语法。

在 Bash、sh 及类似 Shell 中

要在 Bash、sh 及类似 Shell 中访问环境变量,请在 CI/CD 变量前加上 ($):

job_name:
  script:
    - echo "$CI_JOB_ID"

在 PowerShell 中

要在 Windows PowerShell 环境中访问变量(包括系统设置的环境变量),请在变量名前加上 $env:$

job_name:
  script:
    - echo $env:CI_JOB_ID
    - echo $CI_JOB_ID
    - echo $env:PATH

某些情况下,环境变量必须用引号括起来才能正确展开:

job_name:
  script:
    - D:\qislsf\apache-ant-1.10.5\bin\ant.bat "-DsosposDailyUsr=$env:SOSPOS_DAILY_USR" portal_test

在 Windows 批处理中

要在 Windows 批处理中访问 CI/CD 变量,请用 % 将变量括起来:

job_name:
  script:
    - echo %CI_JOB_ID%

您也可以用 ! 将变量括起来以实现延迟扩展。 对于包含空格或换行符的变量,可能需要使用延迟扩展:

job_name:
  script:
    - echo !ERROR_MESSAGE!

在服务容器中

服务容器可以使用 CI/CD 变量,但默认情况下,它们只能访问保存在 .gitlab-ci.yml 文件中的变量。 在 GitLab 用户界面 (UI) 中添加的变量对服务容器不可用,因为服务容器默认不受信任。

要使在 UI 中定义的变量在服务容器中可用,您可以在 .gitlab-ci.yml 文件中将其重新赋值给另一个变量:

variables:
  SA_PASSWORD_YAML_FILE: $SA_PASSWORD_UI

重新赋值的变量不能与原始变量同名,否则它将无法被展开。

将环境变量传递给另一个作业

您可以在一个作业中创建新的环境变量,并将其传递给后续阶段的另一个作业。 这些变量不能用作 CI/CD 变量来配置流水线(例如,使用 rules 关键字),但可以在作业脚本中使用。

要将作业创建的环境变量传递给其他作业:

  1. 在作业脚本中,将该变量保存为 .env 文件。
    • 文件格式必须是每行一个变量定义。
    • 每行的格式必须为:VARIABLE_NAME=ANY VALUE HERE
    • 值可以用引号括起来,但不能包含换行符。
  2. .env 文件保存为 artifacts:reports:dotenv 产物。
  3. 之后,后续阶段的作业便可以在脚本中使用该变量,除非作业被配置为不接收 dotenv 变量

例如:

build-job:
  stage: build
  script:
    - echo "BUILD_VARIABLE=value_from_build_job" >> build.env
  artifacts:
    reports:
      dotenv: build.env

test-job:
  stage: test
  script:
    - echo "$BUILD_VARIABLE"  # 输出为:'value_from_build_job'

来自 dotenv 报告的变量优先级高于某些类型的新变量定义,例如作业中定义的变量。

您也可以dotenv 变量传递给下游流水线

控制哪些作业接收 dotenv 变量

您可以使用 dependenciesneeds 关键字来控制哪些作业接收 dotenv 产物。

要使作业不接收来自 dotenv 产物的任何环境变量:

  • 传递一个空的 dependenciesneeds 数组。
  • needs:artifacts 设置为 false
  • 设置 needs,使其仅列出没有 dotenv 产物的作业。

例如:

build-job1:
  stage: build
  script:
    - echo "BUILD_VERSION=v1.0.0" >> build.env
  artifacts:
    reports:
      dotenv: build.env

build-job2:
  stage: build
  needs: []
  script:
    - echo "此作业没有 dotenv 产物"

test-job1:
  stage: test
  script:
    - echo "$BUILD_VERSION"  # 输出为:'v1.0.0'
  dependencies:
    - build-job1

test-job2:
  stage: test
  script:
    - echo "$BUILD_VERSION"  # 输出为 ''
  dependencies: []

test-job3:
  stage: test
  script:
    - echo "$BUILD_VERSION"  # 输出为:'v1.0.0'
  needs:
    - build-job1

test-job4:
  stage: test
  script:
    - echo "$BUILD_VERSION"  # 输出为:'v1.0.0'
  needs:
    - job: build-job1
      artifacts: true

test-job5:
  stage: deploy
  script:
    - echo "$BUILD_VERSION"  # 输出为 ''
  needs:
    - job: build-job1
      artifacts: false

test-job6:
  stage: deploy
  script:
    - echo "$BUILD_VERSION"  # 输出为 ''
  needs:
    - build-job2

将环境变量从 script 部分传递到 artifacts 或 cache

使用 $GITLAB_ENV 来在 artifactscache 关键字中使用 script 部分中定义的环境变量。例如:

build-job:
  stage: build
  script:
    - echo "ARCH=$(arch)" >> $GITLAB_ENV
    - touch some-file-$(arch)
  artifacts:
    paths:
      - some-file-$ARCH

在一个变量中存储多个值

您不能创建一个值为数组的 CI/CD 变量,但可以使用 Shell 脚本技术来实现类似的行为。

例如,您可以将多个用空格分隔的值存储在一个变量中,然后通过脚本循环遍历这些值:

job1:
  variables:
    FOLDERS: src test docs
  script:
    - |
      for FOLDER in $FOLDERS
        do
          echo "The path is root/${FOLDER}"
        done

在其他变量中使用 CI/CD 变量

您可以在其他变量内部使用变量:

job:
  variables:
    FLAGS: '-al'
    LS_CMD: 'ls "$FLAGS"'
  script:
    - 'eval "$LS_CMD"'  # 执行 'ls -al'

作为字符串的一部分

您可以将变量用作字符串的一部分。您可以用大括号 ({}) 将变量括起来,以帮助区分变量名和周围的文本。如果不使用大括号,相邻的文本将被解释为变量名的一部分。例如:

job:
  variables:
    FLAGS: '-al'
    DIR: 'path/to/directory'
    LS_CMD: 'ls "$FLAGS"'
    CD_CMD: 'cd "${DIR}_files"'
  script:
    - 'eval "$LS_CMD"'  # 执行 'ls -al'
    - 'eval "$CD_CMD"'  # 执行 'cd path/to/directory_files'

在 CI/CD 变量中使用 $ 字符

如果您不希望 $ 字符被解释为另一个变量的开头,请改用 $$

job:
  variables:
    FLAGS: '-al'
    LS_CMD: 'ls "$FLAGS" $$TMP_DIR'
  script:
    - 'eval "$LS_CMD"'  # 执行 'ls -al $TMP_DIR'

将 CI/CD 变量传递给下游流水线时,此方法无效。