iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
0
DevOps

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

Day19 - GitLab CI 返璞歸真談工作的核心 .gitlab-ci.yml 的 script

在 GitLab CI 中每個工作 (job) 最重要的區段,大概可以說是 script 的部分,每個工作都必須有 script 的宣告,才能夠運作,整份 .gitlab-ci.yml 也才可以正確執行;GitLab CI 的 script 使用上,只能一行一行的設定嗎?這一篇將針對 script 的一些小細節作說明。

如何自行設定錯誤訊息?

一般來說,在執行 script 時,系統或程式回傳的狀態值,只要是「 非 0 」,就代表該指令執行錯誤,後續的指令也就不繼續執行。因此,當有自訂錯誤碼的需求時,就可以利用這一點,其實作的方法也很簡單,只要 exit 後面接續非 0 的數字即可。舉例來說:

job:
  image: 'ubuntu:20.04'
  variables:
    WILL_EXECUTE: 'RUN'
  script:
    - if [[ "${WILL_EXECUTE}" != "RUN" ]]; then echo "can not run" && exit 10; fi;
    - echo "RUN RUN RUN"

上面的這個例子,當變數 WILL_EXECUTE 的數值為 RUN 的時候,則在畫面上顯示 RUN RUN RUN,當不為 RUN 時,則顯示 can not run 並且產生 response code 10,讓 runner 顯示錯誤。在這邊也可以透過手動啟動流水線(Pipeline)來刻意設定 WILL_EXECUTE 讓他對應的數值不為 RUN

設定手動執行的畫面

而後,就可以在執行結果中看到,因 WILL_EXECUTE 內容不為 RUN 因此畫面呈現了 can not run 並且錯誤代碼為 10 後續的工作也沒有再進行了。

顯示錯誤執行結果

當可以自行設定錯誤代碼時,就可以透過 script 來設計產生錯誤的條件,進而最佳化整個工作流程。

如何建立包含「多行(multi-line)」的 script

在上面的例子中,可以發現在設定判斷式時,因為內容都集中在同一行中,導致 script 可閱讀性降低。那麼,在 script 裡頭,可以怎麼撰寫多行 (multi-line) 的指令呢?

以上面的例子,因為是判斷式,因此個人通常會使用多個 script 並且以 space 作為 indent,修改後如下:

job:
  image: 'ubuntu:20.04'
  variables:
    WILL_EXECUTE: 'RUN'
  script:
    - if [[ "${WILL_EXECUTE}" != "RUN" ]]; then
    -   echo "can not run";
    -   exit 10;
    - fi;
    - echo "RUN RUN RUN"

這樣修改帶來額外的好處是,如果發生錯誤的是 echo "can not run" 這部分的 script,也可以在發生錯誤時,快速的找到真正錯誤的位置。

另外像是在 script 中要進行打包或壓縮多個檔案及資料夾時,也會透過希望將資料夾或檔案以一行一個的方式顯示,但壓縮打包的指令,通常需要一次完成,這時候就無法如上使用多個 script 來完成。如壓縮打包指令 tar -pcvf FILE_NAME.tgz readme.md changelog.md src,希望將 readme.mdchangelog.mdsrc 資料夾打包為 FILE_NAME.tgz。這時候在 script 中可以怎麼完成呢?

job:
  image: 'ubuntu:20.04'
  variables:
    WILL_EXECUTE: 'RUN'
  script:
    - "tar -pcvzf ${RELEASE_FILE_NAME} \
      readme.md \
      changelog.md \
      src"

如上面的指令,可以透過 shell script 可以透過 \ 符號做跨行串接的特性進行。

在 GitLab CI 官方手冊上,也有提到使用 YAML 語法來作多行指令的呈現,其是透過 | 符號 或 > 符號來標示為「多行」:

首先是使用 | 符號的範例:

job:
  script:
    - |
      echo "First command line."
      echo "Second command line."
      echo "Third command line."

呈現的結果如下:

呈現 | 符號多行指令的效果

其次是使用 > 指令的範例:

job:
  script:
    - >
      echo "First command line
      is split over two lines."

      echo "Second command line."

以及

job:
  script:
    - echo "First command line
      is split over two lines."

      echo "Second command line."

上面兩個範例的效果是一致的,其呈現的結果如下:

使用 > 符號執行的結果畫面

另外,在 YAML 檔案裡頭,要呈現多行文字,還有一些參考範例,可以查看YAML Multiline Strings上的其它範例。

如何幫輸出的畫面上色?

在 runner 輸出的畫面中,呈現系統上亮綠色深綠色以及自行輸出的白色字體三種顏色,那麼,有機會額外再自訂自己想要的顏色嗎?在 GitLab CI 的 script 是可以支援 ANSI 的色碼的,舉例來說:

job:
  image: 'ubuntu:20.04'
  script:
    - echo -e "\e[31mThis text is red,\e[0m but this text isn't\e[31m however this text is red again."

上面的範例,即可以呈現紅白交替的字樣,如下:

插入紅白交替的字樣

其便是透過 ANSI 控制碼來進行字體顏色的設定,如 \e[31m 即是宣告後續的字體使用「紅色」,而 \e[0m 則是設定回原本的白色字樣,因此,如果有需要時常的使用紅色字體的話,也可以把字體的設定變為一個變數供整個 script 使用。如下(手冊上的範例):

job:
  image: 'ubuntu:20.04'
  before_script:
    - TXT_RED="\e[31m" && TXT_CLEAR="\e[0m"
  script:
    - echo -e "${TXT_RED}This text is red,${TXT_CLEAR} but this part isn't${TXT_RED} however this part is again."
    - echo "This text is not colored"

對應之執行結果:

透過 before_script設定控制碼顏色

如果有 Windows 及 Linux 同時使用的跨平台需求時,在使用控制碼改變顏色的時候要特別注意,在 bash 中控制顏色的方法與 Windows 裡頭 PowerShell 的控制的啟用方法是不太一樣的,如上面的案例,在 PowerShell 中必須做以下的修改:

job:
  before_script:
    - $esc="$([char]27)"; $TXT_RED="$esc[31m"; $TXT_CLEAR="$esc[0m"
  script:
    - Write-Host $TXT_RED"This text is red,"$TXT_CLEAR" but this text isn't"$TXT_RED" however this text is red again."
    - Write-Host "This text is not colored"

最後,可以透過這個參考連結 ( bash:tip_colors_and_formatting - FLOZz' MISC ) 來找到需要的 ANSI color,像是閃爍、背景色等等的,都可以透過其中找到範例。

總結

在這一篇中,主要有三個重點,在編輯 script 時,如果需要撰寫一些邏輯,可以則可以透過多行指令來編排,而如果有需要自訂錯誤讓工作停止時,可以透過 exit 非零的數值來自定錯誤,另外,在編寫多行文字時,相對的較容易發生語法問題,導致 YAML 無法執行,因此在正式 commit 前,可以透過 CI Lint 工具先做一次語法確認,如此可以減少等待時間。最後是 script 的小技巧,透過 ANSI 控制碼為 script 的輸出上色。

接下來,依然會繼續介紹關於 script 的其他細節;我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。


上一篇
Day18 - GitLab CI 如何透過參數幫忙執行參數不同但內容相同的工作?工作並行陣列
下一篇
Day20 - GitLab CI 返璞歸真續談 script 之自訂段落 section
系列文
用 GitLab CI 玩轉自動化測試與佈署31

尚未有邦友留言

立即登入留言