是否可以在用户自定义变量中使用预定义变量:
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.
我想使用分支名称作为标签为 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.