我试着做一个非常基本的GitLab CI工作。
我要:
当我推动开发的时候,gitlab用标签" develop“来建立对接者形象。
当我按到main时,gitlab会检查当前提交是否有标记,并使用它构建映像,否则不会触发作业。
Build and publish docker image:
stage: build
rules:
- if:
($CI_COMMIT_BRANCH == "main" && $CI_COMMIT_TAG && $CI_PIPELINE_SOURCE == "push")
variables:
TAG: $CI_COMMIT_TAG
- if:
($CI_COMMIT_BRANCH == "develop" && $CI_PIPELINE_SOURCE == "push")
variables:
TAG: develop
script:
- echo $TAG
- ...<another commands>
但这不像预期的那样有效。$CI_COMMIT_TAG -是空的。尽管提交触发了作业(合并提交)有标记。
我发现我找到了无助于使用"if“语句来实现我的目标。
解决方案基于工作流建议在这里也没有帮助。
使用名为COMMIT_TAG的变量的直观方式,这似乎是一项相当普通的工作。
但这不起作用。一个善良的人能向我解释如何实现我的目标吗?
发布于 2021-09-16 19:53:49
Gitlab /CD有多个“管道源”,一些预定义变量只存在于某些源。
例如,如果您只需将推送到远程,那么CI_PIPELINE_SOURCE
的值将是push
。对于push
管道,许多预定义变量将不存在,例如CI_COMMIT_TAG
、CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
、CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_NAME
等。
但是,如果您在GitLab UI中或从git push --tags
命令中创建Git标记,它将创建一个标记管道,并且像CI_COMMIT_TAG
这样的变量将存在,但CI_COMMIT_BRANCH
不会。
无论是什么触发了管道,始终存在的一个变量是CI_COMMIT_REF_NAME
。对于将提交绑定到分支的推送源,此变量将保存分支名称。如果提交没有绑定到分支(即,曾经有一个分支用于该提交,但现在它已被删除),它将保存完整的提交SHA。或者,如果管道是用于标记的,它将保存标记名。
有关更多信息,请阅读不同的管道源(在CI_PIPELINE_SOURCE
变量的描述中)和上面链接的文档中的其他变量。
我要做的是把这个检查移到script
部分,这样我们就可以让它变得更复杂,或者立即运行exit 0
,这样作业就不会运行并且不会失败,或者运行脚本的其余部分。
Build and publish docker image:
stage: build
script:
- if [ $CI_PIPELINE_SOURCE != 'push' ]; then exit 0 fi
- if [ $CI_COMMIT_REF_NAME != 'develop' && $CI_COMMIT_TAG == '' ]; then exit 0 fi
- if [ $CI_COMMIT_TAG != '' ]; then git branch --contains $CI_COMMIT_TAG | grep main; TAG_ON_MAIN=$? fi
- if [ $TAG_ON_MAIN -ne 0 ]; then exit 0 fi
- echo $TAG
- ...<other commands>
这有点让人费解,所以这里是逐行的:
$CI_PIPELINE_SOURCE
变量不是“push”,我们就exit 0
。$CI_COMMIT_REF_NAME
(同样,提交SHA、标记名或分支名称)不是develop
且$CI_COMMIT_TAG
为空,则为exit 0
$CI_COMMIT_TAG
不是空的,我们运行一个命令来查看标记是否基于main
,git branch --contains <tag_name>
。这将返回这个标记是其一部分的所有分支(即创建它的分支,以及标记创建后存在的所有分支)。然后,我们通过grep
传递结果以查找main
。如果main
在结果列表中,退出代码是0
,我们可以使用特殊变量$?
(始终返回前面命令的退出代码)来获得它。然后,我们将此退出代码设置为要在下一个条件中使用的变量。grep
从步骤3.
的退出代码是否为非0(也就是说,如果main
不在分支列表中,<tag_name>
是其中的一部分),并进行exit 0
。在所有这些之后,我们可以确保管道源是push
,或者有一个标记,它在main
分支上,或者没有标记,管道是给develop
分支的。
https://stackoverflow.com/questions/69199614
复制相似问题