iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
0
DevOps

用 GitLab CI 玩轉自動化測試與佈署系列 第 26

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 流水線效能的議題,我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。


上一篇
Day25 - GitLab CI 在特定的環境使用特定變數,談變數管理與 environment
下一篇
Day27 - GitLab CI 如何讓工作流程流水線跑快一點?之一 從 .gitlab-ci.yml 大部分解
系列文
用 GitLab CI 玩轉自動化測試與佈署31

尚未有邦友留言

立即登入留言