GitLab中的无阶段管线

145 阅读4分钟

GitLab 14.2的发布为CI/CD管道的管理带来了一个令人兴奋的新功能。阶段现在可以被完全省略。相反,管道工作之间的依赖关系可以用needs 关键字来指定。在这篇文章中,我将详细介绍这些变化,并向你展示一个使用无阶段管道的管道定义文件的例子。

传统上,GitLab中的CI/CD管线由多个阶段组成,每个阶段包含多个作业。

这种结构背后的原因是,一个阶段的所有工作都会在下一个阶段的工作之前执行,而同一阶段的所有工作可以并行运行。这种执行模式对简单的流水线来说没有问题,但它限制了更复杂的流水线的性能。

相反,一个更好的解决方案是为每个作业单独指定它所依赖的其他作业。这就是为什么GitLab引入了needs 这个关键字。然而,直到GitLab 14.2,它仍然需要定义阶段。很高兴的是,这一点已经改变了。让我们来看看这种新的流水线编写方式。

简单的管线实例

我们将从gitlab.com提供的一个基本管道模板开始。

stages:
  - build
  - test
  - deploy

build-job:
  stage: build
  script:
    - echo "Compiling the code..."
    - echo "Compile complete."

unit-test-job:
  stage: test
  script:
    - echo "Running unit tests... This will take about 60 seconds."
    - sleep 60
    - echo "Code coverage is 90%"

lint-test-job:
  stage: test
  script:
    - echo "Linting code... This will take about 10 seconds."
    - sleep 10
    - echo "No lint issues found."

deploy-job:
  stage: deploy
  script:
    - echo "Deploying application..."
    - echo "Application successfully deployed."

这个管道定义了三个阶段(构建、测试和部署),分别由一个、两个和一个作业组成。唯一有一个以上工作的阶段是test ,该阶段既包含unit-test-job ,也包含lint-test-job

我们可以通过两个步骤将这个简单的流水线转变为无阶段的流水线。

  • 删除stages: 定义块
  • 将每个stage: 关键字替换为needs: 关键字,引用所有工作的依赖关系

这种转换的结果是以下配置。

build-job:
  script:
    - echo "Compiling the code..."
    - echo "Compile complete."

unit-test-job:
  needs: [build-job]
  script:
    - echo "Running unit tests... This will take about 60 seconds."
    - sleep 60
    - echo "Code coverage is 90%"

lint-test-job:
  needs: [build-job]
  script:
    - echo "Linting code... This will take about 10 seconds."
    - sleep 10
    - echo "No lint issues found."

deploy-job:
  needs: [unit-test-job, lint-test-job]
  script:
    - echo "Deploying application..."
    - echo "Application successfully deployed."

正如你所看到的,这个新的配置既短(前30行,后24行)又更明确(对于每个作业,你可以在作业的块中直接看到依赖关系)。

当你执行这个流水线时,你也可以在GitLab的流水线视图中看到依赖关系。

有了这个新的配置,我们实际上只是复制了和以前一样的管道,只是没有阶段而已--但优势在哪里?为了证明为什么这种灵活性可以带来更好的整体性能,我们可以考虑添加一个新的作业,它只依赖于lint-test-job的结果。如果我们还有阶段,我们就需要在测试和部署阶段之间的新阶段添加这个新工作。然而,新工作也需要等待单元测试工作的完成,尽管新工作根本不关心这些结果。

在新的无阶段世界中,这种变化就像添加这个配置块一样简单。

post-linting-job:
  needs: [lint-test-job]
  script:
    - echo "Postprocessing linting results... This will take about 10 seconds."
    - sleep 10
    - echo "Postprocessing completed."

由此产生的管道会在lint-test-job完成后自动安排新作业。

而这里是最美丽的事情:当unit-test-job 还在运行时,新的post-linting-job 已经被执行了,从而提高了管道的整体执行时间。

完整的模板

我鼓励你尝试使用这个新功能,因为它将提高你的CI/CD管道的清晰度和性能。请随意根据我的模板开始。

build-job:
  script:
    - echo "Compiling the code..."
    - echo "Compile complete."

unit-test-job:
  needs: [build-job]
  script:
    - echo "Running unit tests... This will take about 60 seconds."
    - sleep 60
    - echo "Code coverage is 90%"

lint-test-job:
  needs: [build-job]
  script:
    - echo "Linting code... This will take about 10 seconds."
    - sleep 10
    - echo "No lint issues found."

post-linting-job:
  needs: [lint-test-job]
  script:
    - echo "Postprocessing linting results... This will take about 10 seconds."
    - sleep 10
    - echo "Postprocessing completed."

deploy-job:
  needs: [unit-test-job, lint-test-job]
  script:
    - echo "Deploying application..."
    - echo "Application successfully deployed."

The postStageless Pipelines in GitLabappeared first onBernhard Knasmüller on Software Development.