我有一个 gitlab-ci.yml
文件,如下所示:
stages:
- test
- job1
- job2
test:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
...
myjob1:
stage: job1
script:
...
myjob2:
stage: job2
script:
...
根据文档 HERE(或至少我的理解),第一个阶段/作业仅在我创建合并请求时运行。
这是真的,但下一阶段 (job1
) 在第一个作业 (test
) 开始时并行运行.据我了解,以 test
-> job1
-> job2
) 顺序定义的阶段总是按顺序运行。
那我做错了什么?为什么作业 test
和 job1
并行运行,而不是按预期顺序运行?
答案 0 :(得分:2)
经过多次试错以及阅读和重读真正不清楚和令人困惑的部分documentation后,我可能已经找到了解决方案。
首先,您只想在合并请求上运行的阶段(或者如果您安排触发器或手动启动管道,您不想运行的阶段),您需要按如下方式更改该阶段:
test:
rules:
- if: $CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
stage: test
script:
- 'echo "Running Test"'
- 'echo $CI_PIPELINE_SOURCE'
在这里,您定义了一个规则来检查变量 CI_PIPELINE_SOURCE
是 web
还是 schedule
。如果变量是 web
,这意味着手动管道触发器(即您手动按下 Run pipeline
,documentation 中未解释),或者如果管道由计划触发(未测试,但我认为这就是 schedule
的意思)。
因此,如果管道由计划事件或手动触发,never
会告诉 gitlab 不执行该阶段。 when: on_success
就像一个 else
语句,它告诉 gitlab 在任何其他情况下运行该阶段。
然而,这不是完整的故事。因为当您使用 git
对代码进行更改并通过 git push
将其推送到 gitlab 时,您在 gitlab 中有两个触发器!触发器 merge_request_event
和触发器 push
。这意味着,管道启动两次!
为避免管道启动两次,您需要使用 workflow
键,这有助于定义管道 (=workflow) 是否运行。 (术语 workflow
似乎意味着 pipeline
)。这是要放入 gitlab-ci.yml
文件的代码:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- when: always
当触发器为 merge_request_event
时,此构造禁止运行管道。在这种情况下,不会运行附加管道。在所有其他情况下(例如,当触发器为 push
时),管道会运行。
这里是完整的 gitlab-ci.yaml
代码:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- when: always
stages:
- test
- stage1
- stage2
test:
rules:
- if: $CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
stage: test
script:
- 'echo "Running Test"'
my_stage1:
stage: stage1
script:
- 'echo "Running stage 1"'
my_stage2:
stage: stage2
script:
- 'echo "Running stage 2"'
如果您创建一个 git push
,那么一个管道将在阶段 test
、my_stage1
和 my_stage2
中运行,并且当您手动启动管道或它被触发时按照计划,一个管道以阶段 my_stage1
和 my_stage2
启动。
至于为什么这么复杂和混乱,我没有丝毫的想法。
答案 1 :(得分:-1)
来自 GitLab CI: Run jobs sequentially, in parallel or build a custom pipeline 的 2016 年博客文章“Ivan Nemytchenko”建议确实使用 stages
。
The basics of CI: How to run jobs sequentially, in parallel, or out of order 于 2020 年 12 月在“Itzik Gan Baruch”中对其进行了修订。
也许有不止一个 runner(因为 duplicate pipelines),给人一种流水线运行的不同阶段的错觉。在这种情况下,您可以向阶段添加标签,with concurrency
set to 1。
用“Avoid duplicate pipeline”表示的想法是避免同一管道运行两次。
就您而言,如“Switch between branch pipelines and merge request pipelines”中所述:
这就是以下工作流程的作用:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
这将有助于确保管道不会被触发两次,避免任何“job1
”阶段(看似)与 test
并行运行。