Day26 - GitLab CI 启动其它专案启动流水线或动态产出新的流水线,谈触发 trigger

在大型专案中,可能会把专案依功能、架构等等因素,切分为多个子专案,虽然切分为多个子专案,有些逻辑可能还是有类似的地方,例如前端或後端的部署可能只有环境变数的不同,但流程是相同的,这时候如果可以使用的共同的部署流程就避免维护重复维护的问题。那麽,在 GitLab CI 的流程中可以怎麽完成呢?

一、启动其它专案的流水线

在这系列的 GitLab 群组「GitLab PlayGround」中,有一个包含测试的 PHP Laravel 专案「i5-repository-sample」,其已经有基本的 GitLab CI 流程作 Laravel 专案测试,如果我们要在同一群组的「GitLab CI Try」启动这个这个流水线的测试,我们应该怎麽做呢?请看底下的范例:

staging:
  stage: test
  trigger: mouson-gitlab-playground/i5-repository-sample

如上面的这个范例,只需要使用 trigger 这个参数,并且在後方加上对应群组及专案的名称,就可以启动该专案主分支上的流水线。其执行的画面成果中,出现了新的流水线名为「Downstream」可以解读为「下游」,由目前这个流水线而产出的新流水线。

流水线出现Downstream

另外,在下游专案中的流水线上,也可以看到目前流水线启动的状态,这边以「Upstream」表示启动这次流水线的专案。

下游流水线上出现上游专案的名称

这边提到了,只设定群组及专案名称预设启动的是该专案上的主分支上的流水线,这时候,如果想要启动的流水线并非在主分支上该怎麽调整呢?

staging:
  stage: test
  trigger:
    project: mouson-gitlab-playground/i5-repository-sample
    branch: master

如上面的这个范例,只需要调整增加设定 trigger 的两个子参数 projectbranch 即可,范例中,启动的是该专案的 master 分支上的流水线。

二、设定下游流水线完成後才继续进行流水线工作

一般专案在触发其他专案开始进流水线後,主流水线後续的专案也会开始执行,如底下的例子,在 test-job 完成触发下游流水线工作後,紧接着会开始执行 deploy-job 的工作:

test-job:
  stage: test
  trigger:
    project: mouson-gitlab-playground/i5-repository-sample
    branch: master

deploy-job:
  stage: deploy
  script:
    - echo 'Job Total Finish'

下游工作还没完成,但下一阶段的工作已经开始了

如上图,下游工作还没完成,但下一阶段的工作已经开始了,但如果下一阶段的工作跟下游的工作有关,下游的工作失败了,上游的流水线则不继续进行流水线工作,该怎麽设定?

trigger 参数中,有另外一个子参数为 strategy 当设定为 depend 时,则上游流水线会「相依」下游流水线的工作执行结果。如底下的范例:

test-job:
  stage: test
  trigger:
    project: mouson-gitlab-playground/i5-repository-sample
    branch: master
    strategy: depend

deploy-job:
  stage: deploy
  script:
    - echo 'Job Total Finish'

在上面的这个范例中,deploy-job 会等到 test-job 触发的专案顺利执行完成後才开始进行,如下图:

test-job 工作 pending 中,等待下游工作完成才让 deploy-job 开始

三、让下游工作根据上游流水线最後的执行结果决定要不要执行

在上游可以根据下游的工作状态,来决定流水线要不要继续往下,那麽在下游的工作,可以依据上游的状态决定整个流水线要不要执行吗?当然是可以的,在下游的流水线 GitLab CI 档案里可以增加一个新的工作判断上游的工作状态,其判断的方法使用 needs:pipeline: 来做设定,范例如下:

bridge-job:
  stage: test
  needs:
    pipeline: other/project

根据上游状态决定要不要往下执行的这工作在 GitLab CI 的流程里,称为「bridge job」用来桥接上下游的工作,但它与一般工作有些许的不同,主要是在 bridge job 里头,允许的参数是有限的,可用的参数如下:

  • trigger
  • stage
  • allow_failure
  • rules
  • onlyexcept
  • when (只支援 on_successon_failurealways 三种状态)
  • extends

注意,参数中并没有「script」也就是说,bridge job 中不允许额外行为,仅做为承接工作用。这部分也可以透过 GitLab CI Lint 检查的时候看到,会提示:「jobs:bridge-job:needs config uses invalid types: bridge」。

另外,如上游设定了相依下游工作,下游也设定需要根据上游工作状态决定要不要作,则可能会发生上下游流水线互锁的状况,上下游都无法继续工作而 pending,这部分必须特别注意。

四、从上游流水线传递变数到下游的流水线

那麽,在上游流水线应该怎麽传递变数到或参数到下游呢?在上游流水线中,可以透过 variables 参数,直接将参数传送到下游的工作之中,像是底下这个范例:

staging:
  variables:
    FROM_UPSTREAM: 'from upstream'
  stage: test
  trigger:
    project: mouson-gitlab-playground/i5-repository-sample
    branch: master

在触发下游专案的工作中,透过 variables 带入「FROM_UPSTREAM」这个变数,如此在下游的流水线上的每个工作,就都可以收到来自上游的环境变数。同样以上面提到的 Laravel 专案「i5-repository-sample」为例子,在 test-1 这个工作中增加:

test-1:
  extends: .test_template
  after_script:
    - echo "FROM_UPSTREAM is ${FROM_UPSTREAM}"

在工作执行时,就可以收到来自上游流水线的带来的环境变数内容,执行结果如下:

接收来到来自上游的变数

五、总结

trigger 参数中,还可以选定本地其他的 GitLab CI 档案来执行,亦或者是在流水线中,动态产生新的 .gitlab-ci.yml 当作子流水线来启动,这部分可以在 trigger 参数後使用 include 子参数来设定,如下范例,细节可参考 GitLab 手册

trigger_job:
  trigger:
    include: path/to/child-pipeline.yml

无论是启动本地的其他 .gitlab-ci.yml 档案,或者是启动其它专案的流水线流程,其都是透过 trigger 参数来完成,GitLab CI 也因为 trigger 参数的使用,让它在 multi-project 的大型专案中,可以更轻易地整合在一起。

接下来的章节会开始谈 GitLab CI 流水线效能的议题,我是墨嗓(陈佑竹),期待这系列的文章能够让人有些帮助。


<<:  Day 26 - 范例动手做 - Ansible 安装 Grafana

>>:  [DAY 26] 分散式训练

DAY2 简单介绍Arduino的使用

大家好今天要介绍arduino的使用,首先要先请各位下载他们官方的arduino IDE Ardui...

selenium爬虫:使用xpath

from selenium import webdriver import openpyxl imp...

[Day1] Motivation

哈罗大家好,打ㄍㄟ厚,我是目前就读天大地大台科大的 Steven Meow,这是我第一次参加铁人赛,...

apt-get upgrade 和dist-upgrade的差别

Debian/Ubuntu Linux都使用apt,升级时都是: apt-get update ap...

Exchange 会议室可以分不同厂区吗?

各位前辈好 有一问题想请教各位 目前我面临一个问题,公司使用Exchange 2016主机,此EXC...