在有點規模的團隊中,可能需要有一個專案,專門協助管理可共同的流水線內容,甚至必須要作到,一致的測試流程,那麼在 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 根目錄開始算起的檔案路徑會是最簡潔的標示方式。
在 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 Server 的 some-group/ci-template-project
專案中,「 Git 主分支」上,從根目錄開始計算的路徑 /templates/gitlab-ci-template.yml
載入檔案。
如果是要載入特定 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 官方提供了許多的 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
引入的內容,如果本體內容有重疊的部分 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 取代,並「非」合併取合集。
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'
如上,例子,結果與上一合併後的變數範例是一致的。
但不一樣的地方是,因為在 template 中使用隱藏工作,因此不必擔心工作流程中有不想執行的工作被執行了,在使用端,僅需要把需要引用的工作透過 extends
引入,而後修改為需要的內容。
GitLab 在 10.5 版後推出的 include
語法,可以做到讓部分工作流程可以獨立拆分出來,而這個功能也在 11.4 版之後轉移到免費版本,讓大家都可以使用。我覺得這是很大的一個功能下放,因為 include
語法,除了可以讓部分工作流程重複使用,也可以藉由拆解讓龐大的 .gitlab-ci.yml
檔可以拆解成多個檔案,讓每個檔案專注在特定工作上。也是一個重構 GitLab CI 檔案時,不可或缺的功能之一。
接下來,將談談關於 GitLab CI 的其他小參數,我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。