规则中无法识别 GitLab CI 自定义变量
Posted
技术标签:
【中文标题】规则中无法识别 GitLab CI 自定义变量【英文标题】:GitLab CI custom variable not recognized in rules 【发布时间】:2021-05-18 11:46:52 【问题描述】:在使用预定义 CI 变量的 variables
块中定义变量时,不能在 rules
块中引用它。在这里,只有 job_1 被执行:
variables:
PRODUCTION_BRANCH: $CI_DEFAULT_BRANCH
stages:
- stage_1
job_1:
stage: stage_1
script:
- export
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
job_2:
stage: stage_1
script:
- export
rules:
- if: '$CI_COMMIT_BRANCH == $PRODUCTION_BRANCH'
但是当对PRODUCTION_BRANCH
的值进行硬编码时,它会按预期工作。在这里,两个作业都被执行:
variables:
PRODUCTION_BRANCH: "master"
stages:
- stage_1
job_1:
stage: stage_1
script:
- export
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
job_2:
stage: stage_1
script:
- export
rules:
- if: '$CI_COMMIT_BRANCH == $PRODUCTION_BRANCH'
查看作业的输出时(因为export
记录了环境变量),在这两种情况下,变量PRODUCTION_BRANCH
的值都正确为master
。
为什么会有这样的行为,是否有修复/解决方法?
【问题讨论】:
你用的是什么版本?从 13.6 开始,类似的问题似乎已得到解决:gitlab.com/gitlab-org/gitlab/-/issues/206929 & gitlab.com/gitlab-org/gitlab/-/issues/34272 和 13.7:gitlab.com/gitlab-org/gitlab/-/issues/209864。这个仍然开放:gitlab.com/gitlab-org/gitlab/-/issues/35315 @Arty-chan 我正在运行 13.5.3 版。似乎最后一个问题与我有关 user1452736 发布了一个 Answer 说“这可能是因为在您的 gitlab 实例上禁用了此功能 https://docs.gitlab.com/ee/ci/variables/where_variables_can_be_used.html#enabling-the-nested-variable-expansion-feature” 【参考方案1】:gitlab 在评估 yaml 并确定要运行的内容时,不会对 variables
部分进行变量扩展。不过,变量插值在跑步者中确实有效。
因此,如果在定义自定义变量时使用变量插值,则必须小心。它们是用于 gitlab 条件(不起作用)还是仅用于运行器(在 gitlab 决定运行作业之后......这有效)?
这令人困惑,我在文档中找不到任何关于这种高概率陷阱的警告/参考......但也许我错过了。
所以在你的if:
中你可以使用
$CI_*
变量
(except for a few ENVIRONMENT ones ...请参阅链接的可使用变量表中rules
的描述列。)
您已在全局或作业中定义的自定义变量
variables:
PRODUCTION_BRANCH: "main"
但是如果你的if:
依赖于自定义变量(即$PRODUCTION_BRANCH
),它们本身需要变量插值......
variables:
PRODUCTION_BRANCH: $CI_DEFAULT_BRANCH
...它不会工作。 $PRODUCTION_BRANCH
将在 RUNNER 中具有您期望的值(一旦作业开始),但 gitlab 在解析 yaml 并决定运行哪些作业时不会进行插值。
在您的情况下,最简单的方法就是直接在您的if:
中使用$CI_DEFAULT_BRANCH
变量。
示例.gitlab-ci.yml
演示此...
你可以把它放到一个新的空仓库中。只需更新 REPO_NAMESPACE
、REPO_NAME
和 ONLY_DEPLOY_BRANCH
以匹配当前的 repo/branch。
工作:
debug
- 运行并输出显示您期望的所有值的变量(在运行器上下文中)
deploy1
- 运行
deploy2
- 不运行
deploy3
- 运行(显示变量绝对没有在 gitlab 端插值)。
variables:
REPO_NAMESPACE: "my-group/my-subgroup"
REPO_NAME: "my-project"
ONLY_DEPLOY_BRANCH: "main"
ONLY_DEPLOY_FROM: "$REPO_NAMESPACE/$REPO_NAME"
ONLY_DEPLOY_FROM2: "my-group/my-subgroup/my-project"
stages:
- debug
- deploy
# this runs
# variables all have expected values (in runner scope) and you would expect both deploy* jobs to run
debug:
stage: debug
script:
- export
# this runs
deploy1:
stage: deploy
image: alpine:latest
rules:
- if: $CI_PROJECT_PATH == $ONLY_DEPLOY_FROM2 && $CI_COMMIT_REF_SLUG == $ONLY_DEPLOY_BRANCH
when: always
script:
- echo "Hello world!"
# this doesn't run.
# Only difference to deploy1 job is using $ONLY_DEPLOY_FROM instead of $ONLY_DEPLOY_FROM2
# conclusion... gitlab must not do variable expansion of the variables section when determining which jobs run.
deploy2:
stage: deploy
image: alpine:latest
rules:
- if: $CI_PROJECT_PATH == $ONLY_DEPLOY_FROM && $CI_COMMIT_REF_SLUG == $ONLY_DEPLOY_BRANCH
when: always
script:
- echo "Hello world!"
# this runs which confirms that $ONLY_DEPLOY_FROM has not had CI variables replaced.
deploy3:
stage: deploy
image: alpine:latest
rules:
- if: $ONLY_DEPLOY_FROM == "$REPO_NAMESPACE/$REPO_NAME" && $CI_COMMIT_REF_SLUG == $ONLY_DEPLOY_BRANCH
when: always
script:
- echo "Hello world!"
您可以使用 ci linter (https://gitlab.com/$CI_PROJECT_PATH/-/ci/lint
) 来玩这个。一般来说,它是一个很好的解决问题的工具,无需连续提交一千次到 .gitlab-ci.yml 并消耗共享运行时间。
未解决的问题
Gitlab 有大约 4 万个未解决的问题。不过这里是相关的门票......
Supporting variable expansion for runner(已解决)Supporting the gitlab side variable expansion -- 这个问题。仍然未解决的问题。
什么时候会修复(文档清晰或其他)......我不会屏住呼吸。
【讨论】:
这是一个很大的陷阱,并且极大地限制了针对仅自定义/除了作业配置的规则的使用。很好的答案!!!【参考方案2】:只需将值放在引号中:
variables:
PRODUCTION_BRANCH: "$CI_DEFAULT_BRANCH"
【讨论】:
以上是关于规则中无法识别 GitLab CI 自定义变量的主要内容,如果未能解决你的问题,请参考以下文章
由于禁止的秘密访问规则,无法在 gitlab-runner 中使用 helm upgrade
Gitlab - 无法对 CI 和 CD 构建的远程服务器进行身份验证
无法连接到 unix:///var/run/docker.sock 上的 Docker 守护程序。 docker 守护进程是不是正在运行?带有自托管运行器的 Gitlab Cloud CI/CD 错误