是否可以在用户自定义变量中使用预定义变量:

Is it possible to use predefined variables in user-defined variables:

我想使用分支名称作为标签为 docker 图像名称定义变量,如文档 https://docs.gitlab.com/ce/ci/docker/using_docker_build.html 中所定义:

variables:
 CONTAINER_NAME: myimage:$CI_COMMIT_REF_NAME
 CONTAINER_PUSH_NAME: myrepo:5000/$CONTAINER_NAME

然而,当我输出 CONTAINER_PUSH_NAME 时,我得到:

myrepo:5000/myimage:$CI_COMMIT_REF_NAME

这意味着,我自己的变量被扩展了,但预定义的变量没有,尽管它们在脚本执行时可用,因为当我echo $CI_COMMIT_REF_NAME,我得到了分支名称,正如预期的那样。

是否可以使用预定义变量作为我定义变量的一部分,或者文档有误导性?

回答你的问题:不,你"cascade"(嵌套)一个替代到另一个的方式......

...但是有干净的解决方法(我应该说解决方案)

考虑以下因素:

.gitlab-ci.yml

image: ubuntu

variables:
  # Original
  CONTAINER_NAME: myimage:$CI_COMMIT_REF_NAME
  CONTAINER_PUSH_NAME: myrepo:5000/$CONTAINER_NAME
  #
  # Added to look for a workaround
  CONTAINER_NAME_PREFIX: 'myimage:'
  CONTAINER_PUSH_PREFIX: myrepo:5000/
  CONTAINER_PUSH_NAME_V2: $CONTAINER_PUSH_PREFIX$CONTAINER_NAME_PREFIX$CI_COMMIT_REF_NAME
  #
  # Suggested workaround
  MY_IMAGE: myimage
  MY_REPO: myrepo:5000
  SUGGESTED_CONTAINER_NAME: $MY_IMAGE:$CI_COMMIT_REF_NAME
  SUGGESTED_CONTAINER_PUSH_NAME: $MY_REPO/$MY_IMAGE:$CI_COMMIT_REF_NAME

test:
  script:
  # Just the relevant variables:
  - echo '*** Just the variables:'
  - echo $CI_COMMIT_REF_NAME
  - echo $CONTAINER_NAME
  - echo $CONTAINER_PUSH_NAME
  - echo $CONTAINER_PUSH_NAME_V2
  # Combinations of text and variables
  - echo '*** Combinations of text and variables:'
  - echo myrepo:5000/$CONTAINER_NAME
  - echo 'myrepo:5000/$CONTAINER_NAME'
  - echo "myrepo:5000/$CONTAINER_NAME"
  - echo $CONTAINER_PUSH_PREFIX$CONTAINER_NAME_PREFIX$CI_COMMIT_REF_NAME
  # Suggested workarounds:
  - echo '*** Suggested workarounds:'
  - echo $SUGGESTED_CONTAINER_NAME
  - echo $SUGGESTED_CONTAINER_PUSH_NAME

产生这个输出:

Running with gitlab-ci-multi-runner 9.1.0 (0118d89)
  on docker-auto-scale (e11ae361)
Using Docker executor with image ubuntu ...
Using docker image sha256:a9db1f09b71a10fe42d8ac456c24d961dccd06968e72d2f476df20a12cb41f3d for predefined container...
Pulling docker image ubuntu ...
Using docker image ubuntu ID=sha256:ebcd9d4fca80e9e8afc525d8a38e7c56825dfb4a220ed77156f9fb13b14d4ab7 for build container...
Running on runner-e11ae361-project-3324498-concurrent-0 via runner-e11ae361-machine-1495045360-f78e2b0f-digital-ocean-2gb...
Cloning repository...
Cloning into '/builds/elingerojo/CI-sandbox'...
Checking out 09b782b9 as master...
Skipping Git submodules setup
$ echo '*** Just the variables:'
*** Just the variables:
$ echo $CI_COMMIT_REF_NAME
master
$ echo $CONTAINER_NAME
myimage:master
$ echo $CONTAINER_PUSH_NAME
myrepo:5000/myimage:$CI_COMMIT_REF_NAME
$ echo $CONTAINER_PUSH_NAME_V2
myrepo:5000/myimage:master
$ echo '*** Combinations of text and variables:'
*** Combinations of text and variables:
$ echo myrepo:5000/$CONTAINER_NAME
myrepo:5000/myimage:master
$ echo 'myrepo:5000/$CONTAINER_NAME'
myrepo:5000/$CONTAINER_NAME
$ echo "myrepo:5000/$CONTAINER_NAME"
myrepo:5000/myimage:master
$ echo $CONTAINER_PUSH_PREFIX$CONTAINER_NAME_PREFIX$CI_COMMIT_REF_NAME
myrepo:5000/myimage:master
$ echo '*** Suggested workarounds:'
*** Suggested workarounds:
$ echo $SUGGESTED_CONTAINER_NAME
myimage:master
$ echo $SUGGESTED_CONTAINER_PUSH_NAME
myrepo:5000/myimage:master
Job succeeded

有5个正确的输出。选择适合您风格的一款:)


旁注:

"original" 问题在于为每个符号分配多个替换文本 level(符号是赋值的左侧,例如 CONTAINER_NAME) .意思是,你不能像 CONTAINER_PUSH_NAME 那样有 "nested" 替换 "depends" 通过符号 CONTAINER_NAME.[=21 在 $CI_COMMIT_REF_NAME 的更深层次(嵌套)替换=]

只要不嵌套,可以同时使用多个替换


选项 1

image: ubuntu

variables:
  # Just two lines, all info at top of the script
  CONTAINER_NAME_PREFIX: myimage
  CONTAINER_PUSH_PREFIX: myrepo:5000
  # Two auxiliary vars
  CONTAINER_NAME: $CONTAINER_NAME_PREFIX:$CI_COMMIT_REF_NAME
  CONTAINER_PUSH_NAME: $CONTAINER_PUSH_PREFIX/$CONTAINER_NAME_PREFIX:$CI_COMMIT_REF_NAME

test:
  script:
  - echo $CONTAINER_NAME
  - echo $CONTAINER_PUSH_NAME

输出:

$ echo $CONTAINER_NAME
myimage:master
$ echo $CONTAINER_PUSH_NAME
myrepo:5000/myimage:master

选项 2

image: ubuntu

variables:
  CONTAINER_NAME: myimage:$CI_COMMIT_REF_NAME
  CONTAINER_PUSH_PREFIX: myrepo:5000

test:
  script:
  # As bash value with double quotes
  # (could be assigned to an environment variable)
  - echo "myrepo:5000/$CONTAINER_NAME"
  # Or used directly in any command without quotes
  - echo $CONTAINER_PUSH_PREFIX/$CONTAINER_NAME

输出:

$ echo "myrepo:5000/$CONTAINER_NAME"
myrepo:5000/myimage:master
$ echo $CONTAINER_PUSH_PREFIX/$CONTAINER_NAME
myrepo:5000/myimage:master

检查 GitLab 13.10(2021 年 3 月,4 年后)是否对您的情况有所帮助:

Nested variable expansion

Sometimes you need to define a variable in the .gitlab-ci.yml file and use it in another variable definition.

We are introducing the new nested variables expansion feature.

When enabled, GitLab sorts and expands job variables recursively before sending the final output to the runner for job execution.
This specific sorting allows variables to be sent from GitLab CI/CD to the runner in a sequence that resolves correctly.

Now, you can easily use variables inside other variables in your .gitlab-ci.yml file.

See Documentation and Issue.