Pipeline 是 GitLab CI/CD 中的基础构建块(building blocks)。本文记录了与其相关的几个重要概念。
你有三种常见方法来设计(structure)你的 pipelines,它们各有优势。如有需要,这些方法也可以混用或连用(mixed and matched):
- Basic:适用于直观、简单的(straightforward)项目,所有的配置项都在一处容易找到的地方。
- Directed Acyclic Graph:有向无环图 pipeline 适用于对执行效率有需求的大型复杂项目。
- Child/Parent Pipelines:父子 pipeline 适用于带有大量自定义组件(independently defined components)的 monorepos 和项目。
对于下面提到的任何关键词,可以查询 CI YAML reference 来获取详情。
Basic Pipeline
这是 GitLab 中最简单的 pipeline,它先同时运行构建阶段(build stage)中的所有任务,当这些任务都完成的时候,再同时运行测试阶段中的所有任务,以此类推。这不是最高效的,如果你有许多步骤要做,它将变得相当复杂,但是它很容易维护。
与上图匹配的基本 ./gitlab-ci.yml
pipeline 配置示例:
stages:
- build
- test
- deploy
image: alpine
build_a:
stage: build
script:
- echo "This job builds something."
build_b:
stage: build
script:
- echo "This job builds something else."
test_a:
stage: test
script:
- echo "This job tests something. It will only run when all jobs in the"
- echo "build stage are complete."
test_b:
stage: test
script:
- echo "This job tests something else. It will only run when all jobs in the"
- echo "build stage are complete too. It will start at about the same time as test_a."
deploy_a:
stage: deploy
script:
- echo "This job deploys something. It will only run when all jobs in the"
- echo "test stage complete."
deploy_b:
stage: deploy
script:
- echo "This job deploys something else. It will only run when all jobs in the"
- echo "test stage complete. It will start at about the same time as deploy_a."
Directed Acyclic Graph(有向无环图)Pipelines
如果效率对你来说很重要,你希望所有的事情能尽快完成,你可以使用有向无环图(Directed Acyclic Graph) pipeline。使用关键词 needs
来定义任务之间的依赖关系。当 GitLab 清楚任务之间的关系时,它才能尽快执行需要执行的事情、甚至可能地话,直接跳进后面的阶段(stages)。
下面的示例中,如果 build_a
和 test_a
比 build_b
和 test_b
快很多,即使 build_b
仍未完成,GitLab 也可以直接开始 deploy_a
。
与上图匹配的 DAG /.gitlab-ci.yml
配置示例
stages:
- build
- test
- deploy
image: alpine
build_a:
stage: build
script:
- echo "This job builds something quickly."
build_b:
stage: build
script:
- echo "This job builds something else slowly."
test_a:
stage: test
needs: [build_a]
script:
- echo "This test job will start as soon as build_a finishes."
- echo "It will not wait for build_b, or other jobs in the build stage, to finish."
test_b:
stage: test
needs: [build_b]
script:
- echo "This test job will start as soon as build_b finishes."
- echo "It will not wait for other jobs in the build stage to finish."
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo "Since build_a and test_a run quickly, this deploy job can run much earlier."
- echo "It does not need to wait for build_b or test_b."
deploy_b:
stage: deploy
needs: [test_b]
script:
- echo "Since build_b and test_b run slowly, this deploy job will run much later."
Child / Parent Pipeline
上述示例中,很清晰的是我们有两个不同的事情可以独立构建。这也是通过使用关键词 trigger
使用父子(Child / Parent) pipeline 的理想案例。它把配置文件分成了多个文件,可令每个文件保持简洁。你可以通过以下方法进行组合:
- 关键词
rules
:例如,让子 pipeline 仅在某些情况下被触发。 - 关键词
include
:提供通用行为来避免重复编写配置文件。 - 在子 pipeline 中使用
DAG pipelines
可以利用两种 pipeline 的优势。
与上图匹配的 /.gitlab-ci.yml
父 pipeline 配置文件
stages:
- triggers
trigger_a:
stage: triggers
trigger:
include: a/.gitlab-ci.yml
rules:
- changes:
- a/*
trigger_b:
stage: triggers
trigger:
include: b/.gitlab-ci.yml
rules:
- changes:
- b/*
子 pipeline a 的配置文件,位于 /a/.gitlab-ci.yml
,使用了 DAG 关键词 needs
:
stages:
- build
- test
- deploy
image: alpine
build_a:
stage: build
script:
- echo "This job builds something."
test_a:
stage: test
needs: [build_a]
script:
- echo "This job tests something."
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo "This job deploys something."
子 pipeline b 的配置文件,位于 /b/.gitlab-ci.yml
,使用了 DAG 关键词 needs
:
stages:
- build
- test
- deploy
image: alpine
build_b:
stage: build
script:
- echo "This job builds something else."
test_b:
stage: test
needs: [build_b]
script:
- echo "This job tests something else."
deploy_b:
stage: deploy
needs: [test_b]
script:
- echo "This job deploys something else."
如果你在最后有些相同的配置步骤或者统一的部署操作,也可以设置一些任务在这些触发的子 pipeline 之前或者之后进行。