Art*_*kov 7 deployment docker gitlab-ci gitlab-ci-runner devops
我尝试做一个非常基本的 GitLab CI 工作。
我想要:
当我推送到开发时,gitlab 会使用标签“develop”构建 docker 镜像
当我推送到 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>
Run Code Online (Sandbox Code Playgroud)
但它并没有按预期工作。$CI_COMMIT_TAG - 为空。尽管触发作业(合并提交)的提交有标签。
我发现我发现的解释并不能帮助使用“if”语句实现我的目标。基于此处建议的工作流程的
解决方案也没有帮助。
使用名为 COMMIT_TAG 的变量的直观方式似乎很常见。
但它就是行不通。请好心人向我解释如何实现我的目标吗?
Ada*_*all 14
Gitlab CI/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
image: alpine:latest
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>
Run Code Online (Sandbox Code Playgroud)
这有点令人困惑,所以这里逐行说明:
$CI_PIPELINE_SOURCE变量不是“推”,我们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我们可以通过特殊变量获得的$?(始终返回上一个命令的退出代码)。然后,我们将此退出代码设置为一个变量,以便在下一个条件中使用。grepfrom 步骤的3.退出代码是否为非 0(即,如果main不在分支列表中),并且我们.<tag_name>exit 0在完成所有这些之后,我们可以确定 Pipeline Source 是push,或者有标签并且它位于main分支上,或者没有标签并且管道用于分支develop。
| 归档时间: |
|
| 查看次数: |
12657 次 |
| 最近记录: |