Continuous integration 如何让Gitlab CI管道始终运行某些作业,而仅在合并请求时运行其他作业?
TL/DR: 我的目标是拥有一个Gitlab(CE-12.4.2)管道,它只在合并请求上执行一些作业,而总是在其他作业上执行(在合并请求和所有正常推送上)。Continuous integration 如何让Gitlab CI管道始终运行某些作业,而仅在合并请求时运行其他作业?,continuous-integration,gitlab,merge-request,Continuous Integration,Gitlab,Merge Request,TL/DR: 我的目标是拥有一个Gitlab(CE-12.4.2)管道,它只在合并请求上执行一些作业,而总是在其他作业上执行(在合并请求和所有正常推送上)。.gitlab ci.yml如何才能做到这一点 我的用例: 我有一个庞大的管道,运行着大量的工作(测试、验证、dep、构建、文档等等)。现在,我添加了一个登台环境(使用kubernetes),并让管道构建一个新映像并将其部署到登台环境中。这使我能够立即打开已更改的(web)应用程序,查看更改的行为和外观,而无需在本地进行检查。现在,构建一个映
.gitlab ci.yml
如何才能做到这一点
我的用例:
我有一个庞大的管道,运行着大量的工作(测试、验证、dep、构建、文档等等)。现在,我添加了一个登台环境(使用kubernetes),并让管道构建一个新映像并将其部署到登台环境中。这使我能够立即打开已更改的(web)应用程序,查看更改的行为和外观,而无需在本地进行检查。现在,构建一个映像并将其部署到staging对于每次推送来说都是太多的资源,所以我只希望在有人创建合并请求供我查看时将其部署到staging
一个非常简单的例子:
install:
script: ...
test:
script: ...
build-image:
script: ...
only: [merge_requests]
deploy-staging:
script: ...
only: [merge_requests]
对于所有正常推送,应执行作业install
和test
对于合并请求,应执行作业安装
、测试
、生成映像
和部署暂存
我尝试过的:Gitlab有一个功能,可以在作业上定义仅:[合并请求]
,这会导致只有在为合并请求执行管道时才执行该作业。听起来正是我要找的,但有一个很大的陷阱。将该属性应用于管道中的一个作业后,在合并请求内执行时,该管道中不具有该属性的所有其他作业将从管道中删除。起初,这对我来说似乎是一个bug,但实际上:
为了将所有其他作业重新引入到合并请求的管道中,我必须将仅:[merge\u requests]
应用于所有其他作业。这种方法的问题是,现在这些常规作业不再为正常的git推送执行。我无法将这些常规作业重新引入到管道中进行正常推送,因为Gitlab不支持only:[始终]
或类似的功能
现在我还注意到,only
语法是不推荐使用的候选语法,人们应该更喜欢规则
语法,所以我看了一下。这种方法存在多个问题:
- 使用
检测管道是否为合并请求执行的唯一方法是评估与合并请求相关的变量,如规则
。不幸的是,这些变量只在使用了$CI\u merge\u request\u ID
时存在,这将重新引入上述问题only:[merge\u requests]
- 规则只允许有条件地应用其他属性,因此当属性实际从管道中删除或添加作业时,我仍然必须使用
、仅
或除外
。不幸的是,Gitlab不支持类似于
或only:[never]
,因此我无法实际删除或添加作业when:never
need
或dependencies
属性使作业依赖于另一个作业,这似乎对作业是否包含在管道中没有影响
最后一件我拼命尝试的事情是始终包含所有作业,并且只需在按下按钮手动触发时将它们标记为when:manual
。这在某种程度上是可行的,但非常繁琐,因为部署到staging是一个多作业过程,每个作业都需要相当长的时间才能完成。因此,我会看到一个合并请求,按下第一个作业的按钮,等待5分钟,按下下一个按钮,再次等待5分钟,然后才能使用暂存。对于许多小型合并请求,这将占用我大量的时间,并且不是一个有效的解决方案。我也不能仅仅将这些作业中的第一个标记为手动作业,因为Gitlab将跳过该作业,然后按顺序执行后面的作业(同样,需要
和依赖项
在处理手动触发的作业时似乎对此没有影响)
我有点困惑的是,在搜索网络后,我发现没有人有同样的问题。要么我是唯一一个只想为合并请求执行某些作业而不排除所有其他作业的Gitlab用户(这似乎不太可能),要么我错过了一些明显的东西(这似乎更有可能)。是我遗漏了什么,还是Gitlab真的不支持这个用例?可以向MR管道添加一些作业。我从这里得到了一个例子: 总体思路:为每个作业定义
仅:[branch,merge\u requests]
,并使用仅:[merge\u requests]
重写部署作业
.only-default: &only-default
only:
- branches
- merge_requests
build:
stage: build
tags:
- build
<<: *only-default
script:
- echo build
deploy mr:
stage: deploy
tags:
- build
only:
- merge_requests
script:
- echo "deploy on MR"
。仅默认值:&仅默认值
仅:
-分支机构
-合并请求
建造:
阶段:建造
标签:
-建造
从:
但有一个问题。本例在创建MR后,为每次推送启动两条管道。一个仅用于<代码>的:[分支机构]
,一个仅用于<代码>的:[合并请求]
检查最后一次(2021年1月)是否有帮助:
使用分支管道和MR管道,无需重复
以前,不可能先为分支运行管道,然后在创建MR时切换到
因此,对于某些配置,如果分支上已打开合并请求,则推送到分支可能会导致重复的管道:分支上的一个管道和合并请求的另一个管道
现在,您可以在CI配置中使用新的$CI\u OPEN\u MERGE\u REQUESTS
预定义环境变量,在正确的时间从分支管道切换到MR管道,并防止冗余管道
见和
把这个扔出去,你能用:
only:-merg吗
.only-default: &only-default
only:
- branches
- merge_requests
build:
stage: build
tags:
- build
<<: *only-default
script:
- echo build
deploy mr:
stage: deploy
tags:
- build
only:
- merge_requests
script:
- echo "deploy on MR"