iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 30
0
DevOps

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

Day30-1 - GitLab CI 可以怎麼重構及整理 .gitlab-ci.yml 讓內容更好瞭解?

隨著專案的演進,當團隊導入 GitLab CI 工作流程之後,通常會是陸續的針對專案需要增加更多的流程,而時間一久 .gitlab-ci.yml 的內容就很有可能變得的冗長,工作流程的樣貌變的不容易判讀。為了避免後續維護上的困擾,通常會建議,當覺得 .gitlab-ci.yml 開始變得冗長了,開始不容易判讀了的時候,就是需要針對它重構的時候了。

連續三十篇的最後一篇,就來談談該怎麼真對 .gitlab-ci.yml 的內容進行整理,甚至是重構以讓內容更好瞭解。

一、一個簡單的例子小談重構 .gitlab-ci.yml,原貌:

如果現在有一個已經寫好的編譯工作用 .gitlab-ci.yml,期間因為陸續增加需求,現在的版本是主要可以完成,針對兩個作業系統版本分別編譯三個不容內容版本的原始碼。

其初步的 .gitlab-ci.yml 概略長這樣:

build:ubuntu:20.04:v1.0:
  image: ubuntu:20.04
  stage: build
  script:
    - echo "prepare build env"
    - echo "build ubuntu:20.04 v1.0 application"
    - echo "clean up env"

build:ubuntu:18.04:v1.0:
  image: ubuntu:18.04
  stage: build
  script:
    - echo "prepare build env"
    - echo "build ubuntu:18.04 v1.0 application"
    - echo "clean up env"

build:ubuntu:20.04:v2.0:
  image: ubuntu:20.04
  stage: build
  script:
    - echo "prepare build env"
    - echo "build ubuntu:20.04 v2.0 application"
    - echo "clean up env"

...etc

二、重構:萃取出相同的內容 Extract to common section, ex: default

因為是編譯相同的內容,所以環境準備的前置作業跟結束的作業很有可能是一樣的,因此,可以思考,是不是統一整理讓前置作業及結束的整理作業變成統一的內容。GitLab CI 有提供 before_scriptafter_script 剛好前置作業及作業後的結束作業可以使用,再加上 default 關卡的設計,可以把所有工作都需要的內容透過 default 放置。因此上述內容可以改為:

default:
  before_script:
    - echo "prepare build env"
  after_script:
    - echo "clean up env"

build:ubuntu:20.04:v1.0:
  image: ubuntu:20.04
  stage: build
  script:
    - echo "build ubuntu:20.04 v1.0 application"

build:ubuntu:18.04:v1.0:
  image: ubuntu:18.04
  stage: build
  script:
    - echo "build ubuntu:18.04 v1.0 application"

...etc

三、把不一樣的地方變成變數

從上一段落最終的內容可以發現,每個工作都長得很像,只差在一些版本及作業系統不同,那這些可以變成變數嗎?當然是可以的,在這邊把作業系統變為變數 BUILD_OS 版本變為 BUILD_VER

default:
  before_script:
    - echo "prepare build env"
  after_script:
    - echo "clean up env"

build:ubuntu:20.04:v1.0:
  variables:
    BUILD_OS: ubuntu:20.04
    BUILD_VER: v1.0
  image: ${BUILD_OS}
  stage: build
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"

build:ubuntu:18.04:v1.0:
  variables:
    BUILD_OS: ubuntu:18.04
    BUILD_VER: v1.0
  image: ${BUILD_OS}
  stage: build
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"

...etc

四、再次找到相同的內容變成隱藏工作(hide job) 後各工作繼承

因為在上一個段落把不一樣的內容都變成了變數,因此執行的工作內容再次的變的一樣,這時候就可以思考,可以把內容變為共用的隱藏工作,讓個工作使用繼承的方式套入各自不同的變數。如下調整:

default:
  before_script:
    - echo "prepare build env"
  after_script:
    - echo "clean up env"

.build_template:
  image: ${BUILD_OS}
  stage: build
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"

build:ubuntu:20.04:v1.0:
  extends: .build_template
  variables:
    BUILD_OS: ubuntu:20.04
    BUILD_VER: v1.0

build:ubuntu:18.04:v1.0:
  extends: .build_template
  variables:
    BUILD_OS: ubuntu:18.04
    BUILD_VER: v1.0

...etc

變為隱藏工作後,其實也會發現 default 關卡的兩個 script 也可以考慮放入到隱藏工作中,變為如下的樣子,這樣的好處是在同一個隱藏工作裡就可以看到完整的樣貌。但這僅是因為這個案例中 before 及 after script 只有 build 關卡使用,如果有其他關卡也同時使用到,則要再多考慮。

.build_template:
  image: ${BUILD_OS}
  stage: build
  before_script:
    - echo "prepare build env"
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"
  after_script:
    - echo "clean up env"

五、套用平行工作矩陣

接著看現行的 Script 可以再次發現,每個工作的內容都只是在更改變數內容,能一起修改嗎?在談對平行工作設置的時候有提到工作並行陣列,套用後,原本需要六個工作才能描述完成的內容,現在在一個工作之中就完成了。

build_application:
  image: ${BUILD_OS}
  stage: build
  before_script:
    - echo "prepare build env"
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"
  after_script:
    - echo "clean up env"
  parallel:
    matrix:
      - BUILD_OS: ["ubuntu:20.04", "ubuntu:18.04"]
        BUILD_VER: [v1.0, v2.0, v3.0]

六、總結

在上面的小型重構中,其可以參考的原始碼放在 GitLab 上,這邊總共使用了幾個小技巧:

這些是實務上可能可以用的方法,接下來的下一篇將談談別人怎麼想以及還可以到哪裡參考範例,我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。


上一篇
Day29 - GitLab CI 如何讓工作流程流水線跑快一點?之三 讓 Runner 執行更快一點
下一篇
Day30-2 - GitLab CI 還可以怎麼重構及整理 .gitlab-ci.yml ?
系列文
用 GitLab CI 玩轉自動化測試與佈署31

尚未有邦友留言

立即登入留言