环境变量替换如何在 gitlab-ci.yml 中工作?

How does environment variable substitution work in gitlab-ci.yml?

假设我有以下定义,脚本 processValue 奇迹般地出现在路径上:

script:
    - processValue $CI_PROJECT_DIR
    - processValue ${CI_COMMIT_REF_NAME+nice}
    - processValue ${CI_COMMIT_REF_NAME/#release\//}

哪个进程评估变量?它会以某种方式被 gitlab 取代吗?或者 gitlab 只是将定义的变量设置为 env 变量并在给定 docker 图像的默认 shell 上保留替换? (意味着最后一次替换将仅在 bash 中有效)

用于执行script行的shell依赖于os,可以配置。对于 Linux 环境,默认的 shell 是 bash

但是说到扩展环境变量,事情就有点复杂了。在创建运行脚本的 shell 会话之前,GitLab 需要能够解析 ci 文件以评估触发器、确定构建环境等。因此,GitLab 迭代地解析环境变量, 每轮的规则与正常的 shell 会话有点不同,并且彼此之间也有一点不同。来自 docs:

There are three expansion mechanisms:

  • GitLab
  • GitLab Runner
  • Execution shell environment

在GitLab阶段,

The expanded part needs to be in a form of $variable, or ${variable} or %variable%. Each form is handled in the same way, no matter which OS/shell handles the job, because the expansion is done in GitLab before any runner gets the job.

GitLab Runner 然后再次尝试扩展运行时可用的额外变量集,例如CI_BUILDS_DIR.

再次来自文档:

GitLab Runner internal variable expansion mechanism

  • Supported: project/group variables, .gitlab-ci.yml variables, config.toml variables, and variables from triggers, pipeline schedules, and manual pipelines.
  • Not supported: variables defined inside of scripts (for example, export MY_VARIABLE="test").

The runner uses Go’s os.Expand() method for variable expansion. It means that it handles only variables defined as $variable and ${variable}. What’s also important, is that the expansion is done only once, so nested variables may or may not work, depending on the ordering of variables definitions, and whether nested variable expansion is enabled in GitLab.

最后,shell 执行了具有完整上下文的脚本行。

有关详细信息和配置选项,请参阅 the GitLab-ci runner docs and the GitLab runner environment variables docs