如何让 gitlab 按顺序运行作业?

时间:2021-06-01 07:12:48

标签: gitlab

我有一个 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) 顺序定义的阶段总是按顺序运行。

那我做错了什么?为什么作业 testjob1 并行运行,而不是按预期顺序运行?

2 个答案:

答案 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_SOURCEweb 还是 schedule。如果变量是 web,这意味着手动管道触发器(即您手动按下 Run pipelinedocumentation未解释),或者如果管道由计划触发(未测试,但我认为这就是 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,那么一个管道将在阶段 testmy_stage1my_stage2 中运行,并且当您手动启动管道或它被触发时按照计划,一个管道以阶段 my_stage1my_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 并行运行。

相关问题