【问题标题】:Nested stages in CI jobsCI 作业中的嵌套阶段
【发布时间】:2018-10-14 12:20:52
【问题描述】:

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

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

没有嵌套阶段,我可以尝试同时构建发布和调试二进制文件,然后构建两个映像。但是,这非常低效,因为其中一个构建需要的时间比另一个要长得多,但是,我无法开始为先完成的构建创建映像。

如果可以安排 Docker 映像构建作业在第一个构建完成后立即开始,那就完美了。一种可能的方法是,如果我可以指定嵌套阶段,例如,阶段build-all 有两个嵌套阶段:build-releasebuild-debug,每个阶段都由两个作业组成:build-release-binarybuild-release-image、同样,build-debug-binarybuild-debug-image

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

【问题讨论】:

    标签: continuous-integration gitlab gitlab-ci


    【解决方案1】:

    问题

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

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

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

    【讨论】:

      【解决方案2】:

      从 Gitlab 12.2 开始,此问题已通过 needs clause 修复,因此现在允许任意 DAGs。从 Gitlab 13.1(Beta)开始,您可以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%"
      

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

      【讨论】:

        猜你喜欢
        • 2021-05-31
        • 2021-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-13
        • 1970-01-01
        • 2019-01-08
        • 1970-01-01
        相关资源
        最近更新 更多