CI作业中的嵌套阶段

时间:2018-10-14 12:20:53

标签: continuous-integration gitlab gitlab-ci

在GitLab作业描述中,可以指定阶段,其中作业将按阶段分组并并行执行。想象一下我想执行以下操作:

  1. 构建发布二进制文件。
  2. 为发行版二进制文件构建发行版Docker映像。
  3. 构建调试二进制文件。
  4. 为调试二进制文件构建调试Docker映像。

没有嵌套阶段,我可以尝试同时构建发行版和调试二进制文件,然后再构建两个映像。但是,这效率极低,因为其中一个构建要比另一个构建花费更长的时间,但是,我无法开始为先完成的构建创建映像。

如果只有在第一个构建完成后就可以安排Docker映像构建工作开始,那将是完美的。可能的一种可能方式是,如果我可以指定嵌套阶段,则阶段build-all有两个嵌套阶段:build-releasebuild-debug,每个嵌套阶段都由两个作业组成:{{ 1}},build-release-binary,以及类似的build-release-imagebuild-debug-binary

由于我是GitLab的新手,所以我也希望得到一个否定的答案,即,知道不可能是有用的。

2 个答案:

答案 0 :(得分:0)

问题

首先要确认您的问题,我想您具有这样的设置:

.gitlab-ci.yml

stages:
  - build-binaries
  - build-images

# Binaries
build-release-binary:
  stage: build-binaries
  script:
    - make release

build-debug-binary:
  stage: build-binaries
  script:
    - make debug

# Docker Images
build-release-image:
  stage: build-images
  dependencies:
    - build-release-binary
  script:
    - docker build -t wvxvw:release .

build-debug-image:
  stage: build-images
  dependencies:
    - build-debug-binary
  script:
    - docker build -t wvxvw:debug .

这应该产生这样的管道:

 build-binaries                       build-images
 ______________________              _____________________
|                      |            |                     |
| build-release-binary |----+--+--->| build-release-image |
|______________________|   /   \    |_____________________|
                           |    |
 ______________________    |    |    _____________________
|                      |   |    |   |                     |
| build-debug-binary   |---/    \-->| build-debug-image   |
|______________________|            |_____________________|

评估

您是正确的,build-images阶段中的任何作业都不会开始,直到build-binaries阶段的所有作业都完成(即使满足了作业的依赖性)。

有一个有关GitLab的问题正在讨论中:
gitlab-org/gitlab-ce#49964: Allow running a CI job if its dependencies succeeded

我添加了一条评论,指出在这种情况下可以进行的改进。将来,管道可能如下所示(请注意单独的连接线):

 build-binaries                       build-images
 ______________________              _____________________
|                      |            |                     |
| build-release-binary |----------->| build-release-image |
|______________________|            |_____________________|

 ______________________              _____________________
|                      |            |                     |
| build-debug-binary   |----------->| build-debug-image   |
|______________________|            |_____________________|

解决方法

有时,如果您有顺序的任务,则只需在单个作业中运行它们就容易了。当您已经准备好在第一份工作中准备就绪时,这可以避免启动另一份工作的开销。

作为一种解决方法,您可以将管道简化为一个阶段,该阶段将同时构建二进制和Docker映像:

.gitlab-ci.yml

stages:
  - build

build-release:
  stage: build
  script:
    - make release
    - docker build -t wvxvw:release .

build-debug:
  stage: build
  script:
    - make debug
    - docker build -t wvxvw:debug .

您的管道当然会像这样:

 build
 _______________
|               |
| build-release |
|_______________|

 _______________
|               |
| build-debug   |
|_______________|

我已经与一个团队合作,以类似的方式简化了他们的流程,我们对结果感到满意。

答案 1 :(得分:0)

从 Gitlab 12.2 开始,这已通过 needs clause 修复,因此现在允许任意 DAGs。从 Gitlab 13.1(测试版)开始,您可以visualize the graph

例如,假设您想并行运行 pylint 和单元测试,然后检查单元测试的覆盖率,但无需等待 pylint 完成。

stages:
    - Checks
    - SecondaryChecks

pylint:
    stage: Checks
    script: pylint

unittests:
    stage: Checks
    script: coverage run -m pytest -rs --verbose

testcoverage:
    stage: SecondaryChecks
    needs: ["unittests"]
    script: coverage report -m | grep -q "TOTAL.*100%"

请注意,“需求”仅适用于前一阶段定义的目标。因此这里需要两个阶段。