介紹
GitLab CI/CD 是一個簡潔好用的的持續集成/持續交付的框架。通過為你的項目配置一個或者多個 GitLab Runner,然后撰寫一個 .gitlab-ci.yml,你就可以很方便地利用 GitLab CI/CD 來為你的項目引入持續集成/交付的功能。
執行流程
Stage
GitLab CI/CD 的執行過程中首先驅動的是 Stage。
每個 GitLab CI/CD 都必須包含至少一個 Stage。多個 Stage 是按照順序執行的。如果其中任何一個 Stage 失敗,則后續的 Stage 不會被執行,整個 CI 過程被認為失敗。
以圖中所示為例,整個 CI 環節包含三個 Stage:build
、test
和
deploy
。
-
build
被首先執行。如果發生錯誤,本次 CI 立刻失敗; -
test
在build
成功執行完畢后執行。如果發生錯誤,本次 CI 立刻失??; -
deploy
在test
成功執行完畢后執行。如果發生錯誤,本次 CI 失敗。
Stage 在 .gitlab-ci.yml
中通過如下的方式定義:
stages:
- build
- test
- deploy
如果文件中沒有定義 stages
,那么則默認包含 build
、test
和 deploy
三個 stage。
Stage 中并不能直接配置任何具體的執行邏輯,具體的執行邏輯應該在 Job 中配置。
Job
Job 可以被關聯到一個 Stage。當一個 Stage 執行的時候,與其關聯的所有 Job 都會被執行。需要注意的是,Job 在設計上是可并行執行的。這樣的好處是可以利用多個 Runner 來加速 CI/CD 的流程。
因此,如果 Job 之間有依賴關系的話,需要通過關聯到不同的 Stage 來實現。
Job 在 .gitlab-ci.yml
中通過如下的方式來和 Stage 關聯:
job_build_module_A:
stage: build
如果一個 Job 沒有顯式地關聯某個 Stage,則會被默認關聯到 test
Stage。
Job 的執行
Job 包含了真正的執行邏輯,例如調用 mvn
或者 gcc
等命令。
job_build_module_A:
script:
- cd module_A
- mvn clean compile
公共配置
隨著項目越來越大,Job 越來越多,Job 中包含的重復邏輯可能會讓配置文件臃腫不堪。.gitlab-ci.yml 中提供了 before_script
和 after_script
兩個全局配置項。這兩個配置項在所有 Job 的 script
執行前和執行后調用。
例如:
job_build_module_A:
script:
- export MAVEN_OPTS="-Xmx256m"
- cd module_A
- mvn clean compile
...
job_build_module_Z:
script:
- export MAVEN_OPTS="-Xmx256m"
- cd module_Z
- mvn clean compile
這其中 export MAVEN_OPTS="-Xmx256m"
顯然是可以抽取公用的部分,在 before_script
的幫助下,配置文件可以優化成:
before_script:
- export MAVEN_OPTS="-Xmx256m"
job_build_module_A:
script:
- cd module_A
- mvn clean compile
...
job_build_module_Z:
script:
- cd module_Z
- mvn clean compile
after_script
也可以起到類似的作用,不過是在每個 Job 執行完畢以后被調用。
公共數據 - Cache
Job 的執行過程中往往會產生一些數據,默認情況下 GitLab Runner 會保存 Job 生成的這些數據,然后在下一個 Job 執行之前(甚至不局限于當次 CI/CD)將這些數據恢復。這樣即便是不同的 Job 運行在不同的 Runner 上,它也能看到彼此生成的數據。
不過這些行為可能會帶來意料之外的問題,比如說上一次 CI/CD 執行的是 master 分支的 build,下一次 CI/CD 執行的卻是 devel 分支的 build,而 build 腳本偏偏是增量執行的,那么有可能導致第二次 build 的過程錯誤地引用了 master 編譯生成的中間結果。
這個情況下,我們需要配置 cache.key
:
cache:
key: "$CI_COMMIT_REF_NAME"
這個配置的意思是:所有的 Job 在恢復 cache 的時候,是根據當前的分支名稱去選擇對應的 cache。換句話說,前面例子中的兩次 build 會選中不同的 cache,數據自然就隔離開了。
當然,上面的隔離粒度是分支級別的,你還可以配置成 分支+Job 級別的:
cache:
key: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
上面兩個例子中的 CI_COMMIT_REF_NAME
、CI_JOB_NAME
是 GitLab CI/CD 的預定義變量。除了它們以外,還有許多預定義變量可以供我們選擇,詳情可以參閱《GitLab CI/CD Variables: Predefined variables》
Job 的執行總覽
在了解了 Job 配置的 script
、before_script
、after_script
和 cache
以后,我們便可以將整個 Job 的執行流程用一張圖概括下來了:
總結
通過上面的介紹,我們可以了解到:
- GitLab CI/CD 是通過 GitLab Runner 來執行的
- GitLab CI/CD 將按照 Stage 定義的順序來執行,任何一個 Stage 失敗,整個 CI/CD 將失敗
- 每一個 Stage 可以被若干個 Job 關聯。Stage 在執行的時候,關聯到這個 Stage 的所有 Job 都將被執行,不過不同的 Job 可能是并行執行的。
- 每個 Job 在執行的時候,會先按照緩存策略加載緩存數據,然后按照順序依次運行
before_script
、script
和after_script
中配置的腳本,運行完畢以后,會將生成的數據保存到緩存中。