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