在使用 anchors 來整理重複語法時是否會覺得其語法的「語意」上有一點難懂?正是因為如此,在 GitLab 11.3 之後,因應而生了新的方便整理可重複利用的 script 的語法 extends
。
extends
語法呢?在使用 anchors 時透過 hidden job 來建立模板工作,在 extends
語法中也是一樣的,舉例來說:
.test_template:
script: echo 'echo from template'
stage: test
before_script:
- echo 'echo from templabe before_script'
test_v1:
extends: .test_template
script: echo 'echo from test_v1'
上面的例子,即是基本的 extends
語法運用,其透過 GitLab CI 翻譯後如下:
test_v1:
stage: test
before_script:
- echo 'echo from templabe before_script'
script: echo 'echo from test_v1'
其中,script
的部分因為在 test_v1
重新宣告了一次,因此 .test_template
的 script
被覆寫掉了。
extends
嗎?只能從隱藏的工作作 extends
嗎?答案是「錯」的,extends
語法也可以從一般的工作作「衍伸」,如上面這案例,也可以把 .test_template
的 .
符號移除,如此便會有兩個測試工作。
extends
嗎?在 GitLab 12.0 之後,一層 extends
後,再次的被 extends
的多階層 extends
,如底下的例子就是兩層的 extends
:
.level_one_tmpl:
stage: test
before_script:
- echo 'echo from level 1'
.level_two_tmpl:
extends: .level_one_tmpl
after_script:
- echo 'echo from level 2'
test_01:
extends: .level_two_tmpl
script: echo 'echo from test01'
在上面的這個例子中,最終 GitLab CI 會翻譯出:
test_01:
stage: test
before_script:
- echo 'echo from level 1'
after_script:
- echo 'echo from level 2'
script: echo 'echo from test01'
如下圖進行 CI Lint 後的結果:
截至目前 GitLab 13.4 版本,系統提供了最多 11 個階層的
extends
。
extends
的運用過程中,如果發生重複的內容 GitLab CI 會怎麼處理?.echo_script: &echo_script
- echo "Build OS ${BUILD_OS} and Ver ${BUILD_VER}"
- echo "tmpl_name ${TMPL_NAME}"
.tmpl_one:
variables:
BUILD_OS: 'ubuntu'
TMPL_NAME: 'tmpl_one'
tags:
- self-docker
stage: test
script:
- echo "echo from tmpl_one script"
- *echo_script
before_script:
- echo 'echo from tmpl_one before_script'
.tmpl_two:
variables:
BUILD_VER: 'v1.0'
TMPL_NAME: 'tmpl_two'
tags:
- docker
script:
- echo 'echo from tmpl_two script'
- *echo_script
after_script:
- echo 'echo from tmpl_two after_script'
test_01:
image: ubuntu:20.04
extends:
- .tmpl_one
- .tmpl_two
script:
- echo 'echo from test01 script'
- *echo_script
從上面這例子來看,在工作 test_01
裡頭,使用 extends
了 .tmpl_one
及 .tmpl_two
這兩個樣板,其中變數宣告的部分各有兩個,但 TMPL_NAME
是重疊的,也同時都擁有 script
的宣告,也都有宣告 tags
,那麼,在這個狀況下,其執行結果會是如何呢?
可以發現幾個 extends
除 paramter 內容可以合併在一起外,還有底下的特性:
variables
:變數的部分當不重複的變數,會合併在一起,但重複的部分則會取較晚載入的。如上範例,TMPL_NAME
變數最終的內容為 tmpl_two
。tags
:tags 主要在選擇執行此工作 runner 的特徵,其可允許設定多個 tag,但當重複宣告 tags
時,較晚宣告的會覆寫前面的 tags
,如本次的案例,最終選擇 GitLab 官方提供的 shard runner 其標籤為有標注 docker
的。script
:特徵也是後面宣告的會覆寫前面標注的,以上面的範例,最終畫面僅列印出 echo from test01 script
。因此,上面的案例中,其透過 GitLab CI 翻譯後的工作描述如下:
test_01:
image: ubuntu:20.04
variables:
BUILD_OS: 'ubuntu'
BUILD_VER: 'v1.0'
TMPL_NAME: 'tmpl_two'
tags:
- docker
stage: test
before_script:
- echo 'echo from tmpl_one before_script'
script:
- echo 'echo from test01 script'
- echo "Build OS ${BUILD_OS} and Ver ${BUILD_VER}"
- echo "tmpl_name ${TMPL_NAME}"
after_script:
- echo 'echo from tmpl_two after_script'
在 extends
語法推出之後,個人喜愛使用 extends
的使用多於 anchors
的使用,主要也是因為語法上,其可讀性較 anchors
的使用上清楚。另外,縱使 extends
規格上提供了 11 層的連續 extends
但,個人認為,使用多層的 extends
會致使整個語法較難懂,因此在使用上必須謹慎考慮。
接下來,依然還是關於內容的重複使用,我們將談 include
的特性,我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。