CI作业中的嵌套阶段

3
在GitLab的工作描述中,可以指定阶段,在这些阶段中,作业将按阶段分组并并行执行。假设我想要完成以下操作:
1.构建发布二进制文件。 2.为发布二进制文件构建发布Docker镜像。 3.构建调试二进制文件。 4.为调试二进制文件构建调试Docker镜像。
如果没有嵌套阶段,我可以尝试同时构建发布和调试二进制文件,然后再构建两个镜像。但是,这样非常低效,因为其中一个构建比另一个构建花费更长的时间,然而,我不能开始创建先完成的构建的镜像。
如果能够安排Docker镜像构建作业在第一个构建完成后立即启动,那就太完美了。一种可能实现这一点的方式是,如果我可以指定嵌套阶段,例如,阶段build-all有两个嵌套阶段:build-releasebuild-debug,每个阶段由两个作业组成:build-release-binarybuild-release-image,以及类似的build-debug-binarybuild-debug-image
由于我是GitLab的新手,我也希望得到否定的答案,即知道不可能也是有用的。
2个回答

5

问题

首先确认您的问题,我想您的设置类似于以下情况:

.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-binaries阶段的所有作业完成(即使作业的依赖关系已满足),build-images阶段中没有作业会开始。

有一个GitLab问题正在讨论此问题:
gitlab-org/gitlab-ce#49964: 允许运行CI作业,如果其依赖项成功

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

 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   |
|_______________|

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


2
从Gitlab 12.2开始,这个问题已经通过需要子句得到解决,因此现在允许使用任意DAGs。您可以在Gitlab 13.1(Beta)中可视化图形
例如,假设您想并行运行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%"

请注意,'needs' 仅适用于在之前阶段定义的目标。因此,在这里需要两个阶段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接