隨著專案的演進,當團隊導入 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
default
因為是編譯相同的內容,所以環境準備的前置作業跟結束的作業很有可能是一樣的,因此,可以思考,是不是統一整理讓前置作業及結束的整理作業變成統一的內容。GitLab CI 有提供 before_script
、after_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
因為在上一個段落把不一樣的內容都變成了變數,因此執行的工作內容再次的變的一樣,這時候就可以思考,可以把內容變為共用的隱藏工作,讓個工作使用繼承的方式套入各自不同的變數。如下調整:
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 上,這邊總共使用了幾個小技巧:
這些是實務上可能可以用的方法,接下來的下一篇將談談別人怎麼想以及還可以到哪裡參考範例,我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。