TL/DR:我的目标是拥有一个 Gitlab (CE-12.4.2) 管道,该管道仅在合并请求上执行某些作业,而始终执行其他作业(在合并请求上和所有正常推送上)。必须如何.gitlab-ci.yml
想要这样做吗?
我的用例:我有一个运行大量作业的大型管道(测试、验证、dep、构建、文档......)。现在,我添加了一个临时环境(使用 kubernetes),并让管道构建一个新映像并将其部署在临时环境中。这使我能够立即打开更改后的(网络)应用程序并查看更改的行为和外观,而无需在本地检查它们。现在,构建一个映像并将其部署到暂存对于每次推送来说都太耗费资源,因此我只希望在有人创建合并请求供我审查时部署到暂存。
一个非常简单的例子:
install:
script: ...
test:
script: ...
build-image:
script: ...
only: [merge_requests]
deploy-staging:
script: ...
only: [merge_requests]
对于所有正常的推送,作业install
and test
应该被执行。
对于合并请求,作业install
, test
, build-image
and deploy-staging
应该被执行。
我尝试过的:Gitlab有这个功能来定义only: [merge_requests]
在作业上,这会导致该作业仅在为合并请求执行管道时才执行。听起来正是我正在寻找的东西,但有一个很大的问题。一旦将该属性应用于管道中的一项作业,则该管道中不具有该属性的所有其他作业在合并请求内执行时将从管道中删除。起初这对我来说似乎是一个错误,但实际上是记录的行为 https://docs.gitlab.com/ee/ci/merge_request_pipelines/index.html#configuring-pipelines-for-merge-requests:
In the above example, the pipeline contains only a test job. Since the build and deploy jobs don’t have the only: [merge_requests] parameter, they will not run in the merge request.
为了将所有其他作业重新引入管道以进行合并请求,我必须申请only: [merge_requests]
到所有其他工作。这种方法的问题是,现在这些常规作业不再针对正常的 git-push 执行。而且我没有办法将这些常规作业重新引入管道进行正常推送,因为 Gitlab 不支持only: [always]
或类似的东西。
现在我也注意到了only
语法是弃用的候选者,人们应该更喜欢rules
相反,所以我看了一下。这种方法存在多个问题:
- 检测的唯一方法是
rules
是否为合并请求执行管道是为了评估与合并请求相关的变量,例如$CI_MERGE_REQUEST_ID
。不幸的是,这些变量仅在以下情况下存在:only: [merge_requests]
使用,这会再次引入上述问题。
- 规则只允许有条件地应用其他属性,所以我仍然必须使用
only
, except
or when
属性来实际从管道中删除或添加作业。不幸的是 Gitlab 不支持类似的东西only: [never]
or when: never
,所以我无法实际删除或添加作业。
我还尝试让工作依赖于另一个使用need
or dependencies
属性,这似乎对作业是否包含在管道中没有影响。
我拼命尝试的最后一件事是始终包含所有工作并将它们标记为when: manual
通过按下按钮手动触发。这在某种程度上可行,但非常乏味,因为部署到暂存是一个多作业过程,每个作业都需要相当长的时间才能完成。因此,我会看到合并请求,按下第一个作业的按钮,等待 5 分钟,按下下一个按钮,再次等待 5 分钟,然后才能使用暂存。对于许多小的合并请求,这会占用我大量的时间,并且不是一个有效的解决方案。我也不能只将这些作业中的第一个标记为手动,因为 Gitlab 将跳过该作业并按顺序执行后面的作业(再次强调,needs
and dependencies
在处理手动触发的作业时似乎对此没有影响)。
我有点困惑的是,在网上搜索后,我发现没有人遇到同样的问题。要么我是唯一一个只想为合并请求执行某些作业而不排除所有其他作业(这似乎极不可能)的 Gitlab 用户,要么我错过了一些明显的东西(这似乎更有可能)。我是否遗漏了什么或者 Gitlab 真的不支持这个用例?