iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0
DevOps

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

Day16 - GitLab CI 如何製作一個其他專案也能用的流水線?談 include 及其特性

在有點規模的團隊中,可能需要有一個專案,專門協助管理可共同的流水線內容,甚至必須要作到,一致的測試流程,那麼在 GitLab CI 中,可以怎麼作到這件事情?

除了把統一的流程整理在 .gitlab-ci.yml 還可以怎麼獨立出來呢?

關於統一流程把可重複使用的內容獨立出來,可以透過 include 語法來達到,其就是把想獨立的內容挪移到另外一個 yaml 檔案中,並透過 include 的語法將之載入。舉例來說,假如有一個 yaml 檔,名稱為 template.yml 內容如下:

  • template.yml 的內容如下:
test01:
  stage: test
  script:
    - echo 'echo from template test01 job'
  • .gitlab-ci.yml 的內容如下:
include:
  - 'template.yml'

test02:
  stage: test
  script:
    - echo 'echo from test02'

如上面的內容,透過 include: 'template.yml 就可以把宣告在 template.yml 的內容載入到工作流程中。在 Pipeline 上會同時啟動 test01 以及 test02 兩個工作。

在 GitLab CI 的語法中,還可以更簡略的載入本地端的檔案,如下:

include: 'template.yml'

在只載入一個檔案的場合,於 include 後方直接承接從 Git 根目錄開始算起的檔案路徑會是最簡潔的標示方式。

還可以怎麼載入外部的 template.yml 檔?

在 GitLab CI 的 include 語法中,共提供了四種載入 template 的方法:

  • local:從同一專案中透過路徑載入檔案
  • file:從其它專案中載入檔案
  • remote:從一個公開連結的 URL 載入檔案。特別注意,其必須要確保 GitLab Server 可以存取。
  • template:載入 GitLab 官方提供的模板。(模板清單)

從其它專案中載入工作流程檔案 include:file

要如何從其他專案載入檔案呢?如底下的例子:

include:
  - project: 'some-group/ci-template-project'
    file: '/templates/gitlab-ci-template.yml'

上面的例子,代表的是,從同一 GitLab Serversome-group/ci-template-project 專案中,「 Git 分支」上,從根目錄開始計算的路徑 /templates/gitlab-ci-template.yml 載入檔案。

如果是要載入特定 SHA 或版本的檔案呢?

如果是要載入特定 SHA 或版本的檔案,則可以增加一個 ref 的參數,這個參數可以是版本號、分支名稱或 Git SHA 代號。底下的範例即是載入 v1.0.0 這個 Git Tag 上的檔案:

include:
  - project: 'some-group/ci-template-project'
    ref: v1.0.0
    file: '/templates/gitlab-ci-template.yml'

從一個遠端連結載入工作流程檔案 include:template

如果要從遠端的 URL 載入的檔案,則可以這樣使用:

include:
  - remote: 'https://domain.com/gitlab-ci-tmpl/some-template.yml

但要特別注意,這個連結的網址,必須要是 GitLab Server 可以直接透過 http/https 存取到的,頂多只能透過 http GET method 做簡單的認證。

使用 GitLab 官方提供的 template

GitLab 官方提供了許多的 gitlab-ci 樣板,可以從GitLab 的連結來查看到。例如想直接使用 Auto-DevOps.gitlab-ci.yml 則可以透過底下方法來引用:

include:
  - template: Auto-DevOps.gitlab-ci.yml

同時引入多個檔案 include

如果有需要在一份 .gitlab-ci.yml 中引入多個工作流程檔案,在 include 語法中是支援陣列的,如下範例,就是載入五個不同來源的模板,同時也是上面所提到的各種語法整合:

include:
  - template: Auto-DevOps.gitlab-ci.yml
  - project: 'some-group/ci-template-project'
    ref: v1.0.0
    file: '/templates/gitlab-ci-template.yml'
  - remote: 'https://domain.com/gitlab-ci-tmpl/some-template.yml
  - local: 'template01.yml'
  - 'template02.yml'  

include 的巢狀載入支援

GitLab CI 的 include 語法是可以多層載入的,也就是 include 的檔案裡,還有 include 其他的檔案,最多可以支援到 100 個檔案的 include,但如發生重複載入,會造成錯誤。另外,解析 GitLab CI 的時間,也必須在 30 秒內完成。

關於 include 模板後的檔案覆寫及合併特性

透過 include 引入的內容,如果本體內容有重疊的部分 GitLab CI 會怎麼處理呢?以底下的範例來說,假設有一個 template 內容如下:

  • template.yml 的內容
test01:
  variables:
    BUILD_OS: Ubuntu
    BUILD_VER: v1.0.0
  stage: test
  before_script:
    - echo 'echo from template before_script'
  script:
    - echo 'echo from template test01 job'
  • .gitlab-ci.yml 的內容
include: 'template.yml'

test01:
  image: ubuntu:20.04
  variables:
    BUILD_VER: v2.0.0
    LOCAL_VAR: test01
  stage: test
  script:
    - echo "echo from local"
    - echo "OS ${BUILD_OS} VER ${BUILD_VER}"
    - echo "LOCAL ${LOCAL_VAR}"
  after_script:
    - echo 'echo from gitlab-ci after_script'

根據執行的結果,可以驗證幾個特性:

呈現執行結果的畫面

在上面的範例中,其中變數的部分有 BUILD_VER.gitlab-ci.yml 的內容是重複的,在引入者端數值為 v2.0.0,其被覆寫了。另外在 .gitlab-ci.yml 的變數中,增加了 LOCAL_VAR 其數值為 test01,變數的部分會是將兩個變數陣列合併,並且由引入端覆蓋被引入內容重複的部分,可以說是「合併後取連集」。

另外是 script 的內容,則完全由新宣告的 script 取代,並「非」合併取合集。

GitLab CI 中 extends 搭配 include 語法

除可以直接覆寫印入進來的工作外,也可以搭配前一篇所介紹的 extends。例如在模板中使用隱藏工作:

  • template.yml 的內容
.template-job:
  variables:
    BUILD_OS: Ubuntu
    BUILD_VER: v1.0.0
  stage: test
  before_script:
    - echo 'echo from template before_script'
  script:
    - echo 'echo from template test01 job'
  • .gitlab-ci.yml 的內容
include: 'template.yml'

test01:
  extends: .template-job
  image: ubuntu:20.04
  variables:
    BUILD_VER: v2.0.0
    LOCAL_VAR: test01
  stage: test
  script:
    - echo "echo from local"
    - echo "OS ${BUILD_OS} VER ${BUILD_VER}"
    - echo "LOCAL ${LOCAL_VAR}"
  after_script:
    - echo 'echo from gitlab-ci after_script'

如上,例子,結果與上一合併後的變數範例是一致的。

載入 extends 搭配 include 執行結果

但不一樣的地方是,因為在 template 中使用隱藏工作,因此不必擔心工作流程中有不想執行的工作被執行了,在使用端,僅需要把需要引用的工作透過 extends 引入,而後修改為需要的內容。

總結:

GitLab 在 10.5 版後推出的 include 語法,可以做到讓部分工作流程可以獨立拆分出來,而這個功能也在 11.4 版之後轉移到免費版本,讓大家都可以使用。我覺得這是很大的一個功能下放,因為 include 語法,除了可以讓部分工作流程重複使用,也可以藉由拆解讓龐大的 .gitlab-ci.yml 檔可以拆解成多個檔案,讓每個檔案專注在特定工作上。也是一個重構 GitLab CI 檔案時,不可或缺的功能之一。

接下來,將談談關於 GitLab CI 的其他小參數,我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。


上一篇
Day15 - GitLab CI 如何整理流水線工作中重複的內容?談 extends 語法
下一篇
Day17 - GitLab CI 如何讓讓一個工作同時拆成多個工作?談工作並行處理
系列文
用 GitLab CI 玩轉自動化測試與佈署31

尚未有邦友留言

立即登入留言