iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0
DevOps

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

Day15 - GitLab CI 如何整理流水線工作中重複的內容?談 extends 語法

在使用 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_templatescript 被覆寫掉了。

只能從隱藏的工作作 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 後的結果:

進行 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 的特性,我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。


上一篇
Day14 - GitLab CI 流水線工作中重複的內容,可以怎麼整理利用?談 hide job、anchor
下一篇
Day16 - GitLab CI 如何製作一個其他專案也能用的流水線?談 include 及其特性
系列文
用 GitLab CI 玩轉自動化測試與佈署31

尚未有邦友留言

立即登入留言