Gitlab-ci:從零開(kāi)始的前端自動(dòng)化部署
目錄
一.概念介紹
1.1 gitlab-ci && 自動(dòng)化部署工具的運(yùn)行機(jī)制
1.2 自動(dòng)化部署給我們帶來(lái)的好處
二.知識(shí)預(yù)備
2.1 gitlab-ci涉及的抽象概念(Runner/PipeLine/Executor/Job )
2.2 YML文件的基本語(yǔ)法規(guī)則
2.3 .gitlab-ci.yml配置的特定關(guān)鍵字
三.CI實(shí)戰(zhàn)
3.1 編寫(xiě)一個(gè)gitlab-ci的“hello world”
四.坑點(diǎn)總結(jié)
五.gitlab-ci進(jìn)階
5.1 YML的片段復(fù)用和模塊化
5.2 gitlab-ci提供的其他配置關(guān)鍵字
一.概念介紹
1.1 gitlab-ci && 自動(dòng)化部署工具的運(yùn)行機(jī)制
以gitlab-ci為例:
(1) 通過(guò)在項(xiàng)目根目錄下配置**.gitlab-ci.yml**文件,可以控制ci流程的不同階段,例如install/檢查/編譯/部署服務(wù)器。gitlab平臺(tái)會(huì)掃描.gitlab-ci.yml文件,并據(jù)此處理ci流程

(2) ci流程在每次團(tuán)隊(duì)成員「push/merge」后之后觸發(fā)。每當(dāng)你push/merge一次,gitlab-ci都會(huì)檢查項(xiàng)目下有沒(méi)有.gitlab-ci.yml文件,如果有,它會(huì)執(zhí)行你在里面編寫(xiě)的腳本,并完整地走一遍從「intall =>」 「eslint檢查=>編譯 =>部署服務(wù)器」的流程

(3)gitlab-ci提供了指定ci運(yùn)行平臺(tái)的機(jī)制,它提供了一個(gè)叫「gitlab-runner」的軟件,只要在對(duì)應(yīng)的平臺(tái)(機(jī)器或docker)上下載并運(yùn)行這個(gè)命令行軟件,并輸入從gitlab交互界面獲取的token,就可以把當(dāng)前機(jī)器和對(duì)應(yīng)的gitlab-ci流程綁定,也即:每次跑ci都在這個(gè)平臺(tái)上進(jìn)行。
(4).gitlab-ci的所有流程都是可視化的,每個(gè)流程節(jié)點(diǎn)的狀態(tài)可以在gitlab的交互界面上看到,包括執(zhí)行成功或失敗。如下圖所示,因?yàn)樗膱?zhí)行看上去就和多節(jié)管道一樣,所以我們通常用“pipeLine”來(lái)稱(chēng)呼它

(5).不同push/merge所觸發(fā)的CI流程不會(huì)互相影響,也就是說(shuō),你的一次push引發(fā)的CI流程并不會(huì)因?yàn)榻酉聛?lái)另一位同事的push而阻斷,它們是互不影響的。這一個(gè)特點(diǎn)方便讓測(cè)試同學(xué)根據(jù)不同版本進(jìn)行測(cè)試。
(6)pipeline不僅能被動(dòng)觸發(fā),也是可以手動(dòng)觸發(fā)的。

1.2 自動(dòng)化部署給我們帶來(lái)的好處
自動(dòng)化部署的好處體現(xiàn)在幾個(gè)方面
「1.提高前端的開(kāi)發(fā)效率和開(kāi)發(fā)測(cè)試之間的協(xié)調(diào)效率」
「Before」
如果按照傳統(tǒng)的流程,在項(xiàng)目上線(xiàn)前的測(cè)試階段,前端同學(xué)修復(fù)bug之后,要手動(dòng)把代碼部署之后。才能通知測(cè)試同學(xué)在測(cè)試環(huán)境進(jìn)行測(cè)試。
這會(huì)造成幾個(gè)問(wèn)題:本身手動(dòng)部署服務(wù)的工作是比較繁瑣的,占用了開(kāi)發(fā)時(shí)間。同時(shí)開(kāi)發(fā)-測(cè)試之間的環(huán)節(jié)的耦合問(wèn)題,則會(huì)增加團(tuán)隊(duì)溝通成本。
「After」
通過(guò)gitlab-ci,前端開(kāi)發(fā)在提交代碼之后就不用管了,ci流程會(huì)自動(dòng)部署到測(cè)試或集成環(huán)境的服務(wù)器。很大程度上節(jié)約了開(kāi)發(fā)的時(shí)間。
同時(shí),因?yàn)殚_(kāi)發(fā)和測(cè)試人員可以共用gitlab里的pipeline界面, 測(cè)試同學(xué)能夠隨時(shí)把握代碼部署的情況,同時(shí)還可以通過(guò)交互界面手動(dòng)啟動(dòng)pipeline,自己去部署測(cè)試,從而節(jié)約和開(kāi)發(fā)之間的溝通時(shí)間。
「2.從更細(xì)的粒度把握代碼質(zhì)量」
我們可以把eslint或其他的代碼檢查加到pipeline流程中,每當(dāng)團(tuán)隊(duì)成員提交和合并一次,pipeline都會(huì)觸發(fā)一次并對(duì)代碼做一次全面檢測(cè),這樣就從一個(gè)更細(xì)的粒度上控制代碼質(zhì)量了。
二.知識(shí)預(yù)備
介紹完gitlab-ci的基本概念,接下來(lái)我將會(huì)介紹編寫(xiě)一個(gè)gitlab-ci用例所需要的知識(shí)。這是在實(shí)戰(zhàn)之前的一點(diǎn)準(zhǔn)備工作,主要包括三部分
gitlab-ci涉及的抽象概念 YML文件的基本語(yǔ)法規(guī)則 .gitlab-ci.yml配置的特定關(guān)鍵字
2.1 gitlab-ci涉及的抽象概念
首先要了解的是gitlab-ci中涉及的一些基本概念
「1.Pipeline & Job」
Pipeline是Gitlab根據(jù)項(xiàng)目的.gitlab-ci.yml文件執(zhí)行的流程,它由許多個(gè)任務(wù)節(jié)點(diǎn)組成, 而這些Pipeline上的每一個(gè)任務(wù)節(jié)點(diǎn),都是一個(gè)獨(dú)立的Job
Job在YML中的配置我們將會(huì)在下面介紹,現(xiàn)在需要知道的是:「每個(gè)Job都會(huì)配置一個(gè)stage屬性,來(lái)表示這個(gè)Job所處的階段。」
「一個(gè)Pipleline有若干個(gè)stage,每個(gè)stage上有至少一個(gè)Job」,如下圖所示:

「2.Runner」
Runner可以理解為:「在特定機(jī)器上」根據(jù)項(xiàng)目的**.gitlab-ci.yml「文件,對(duì)項(xiàng)目執(zhí)行pipeline的」程序**。Runner可以分為兩種:「Specific Runner」 和 「Shared Runner」
「Shared Runner」是Gitlab平臺(tái)提供的免費(fèi)使用的runner程序,它由Google云平臺(tái)提供支持,每個(gè)開(kāi)發(fā)團(tuán)隊(duì)有十幾個(gè)。對(duì)于公共開(kāi)源項(xiàng)目是免費(fèi)使用的,如果是私人項(xiàng)目則有每月2000分鐘的CI時(shí)間上限。 「Specific Runner」是我們自定義的,在自己選擇的機(jī)器上運(yùn)行的runner程序,gitlab給我們提供了一個(gè)叫g(shù)itlab-runner的命令行軟件,只要在對(duì)應(yīng)機(jī)器上下載安裝這個(gè)軟件,并且運(yùn)行g(shù)itlab-runner register命令,然后輸入從gitlab-ci交互界面獲取的token進(jìn)行注冊(cè), 就可以在自己的機(jī)器上遠(yuǎn)程運(yùn)行pipeline程序了。
?Gitlab-runner下載鏈接:https://docs.gitlab.com/runner/install/
?
「Shared Runner 和 Specific Runner的區(qū)別」
Shared Runner是所有項(xiàng)目都可以使用的,而Specific Runner只能針對(duì)特定項(xiàng)目運(yùn)行 Shared Runner默認(rèn)基于docker運(yùn)行,沒(méi)有提前裝配的執(zhí)行pipeline的環(huán)境,例如node等。而Specific Runner你可以自由選擇平臺(tái),可以是各種類(lèi)型的機(jī)器,如Linux/Windows等,并在上面裝配必需的運(yùn)行環(huán)境,當(dāng)然也可以選擇Docker/K8s等 私人項(xiàng)目使用Shared Runner受運(yùn)行時(shí)間的限制,而Specific Runner的使用則是完全自由的。

「3.Executor」
什么是Executor?我們上面說(shuō)過(guò) Specific Runner是在我們自己選擇的平臺(tái)上執(zhí)行的,這個(gè)平臺(tái)就是我們現(xiàn)在說(shuō)到的“Executor”,我們?cè)谔囟C(jī)器上通過(guò)gitlab-runner這個(gè)命令行軟件注冊(cè)runner的時(shí)候,命令行就會(huì)提示我們輸入相應(yīng)的平臺(tái)類(lèi)型。可供選擇的平臺(tái)一共有如下幾種,下面是一張它們各方面特點(diǎn)的比較表格

下面是表格的原文鏈接
?參考鏈接:https://docs.gitlab.com/runner/executors/#selecting-the-executor
?
「為了簡(jiǎn)單起見(jiàn),我下面的實(shí)踐部分使用的是我自己的本地Mac機(jī)器作為Executor,并且在注冊(cè)時(shí)選擇“Shell”作為Executor類(lèi)型。」
「2.2 YML文件的基本語(yǔ)法規(guī)則」
CI流程的運(yùn)行控制,決定于項(xiàng)目根目錄下編寫(xiě)的配置文件—— 「.gitlab-ci.yml」,正因如此,我們需要掌握YML的基本語(yǔ)法規(guī)則。
YML是一種編寫(xiě)配置文件的語(yǔ)言,比JSON更為簡(jiǎn)潔和方便,因此,我們首先要掌握的就是YML文件的編寫(xiě)語(yǔ)法。
一份簡(jiǎn)單的YML文件長(zhǎng)下面這個(gè)樣子:
install-job: # 注釋
tags:
- sss
stage: install
script:
- npm install
從這里我們就可以看出:
YML通過(guò)縮進(jìn)組織層級(jí) YML里允許通過(guò)#符號(hào)編寫(xiě)注釋
在基本結(jié)構(gòu)上,YML和 JSON也類(lèi)似
JSON是由對(duì)象,數(shù)組,以及對(duì)象和數(shù)組的嵌套結(jié)構(gòu)組成的 YML也是由對(duì)象,數(shù)組,以及對(duì)象和數(shù)組的嵌套結(jié)構(gòu)組成的。
如下所示:
「YML中的數(shù)組寫(xiě)法」
colors
- red
- blue
- yellow
相當(dāng)于JSON中的
{?"colors":?["red","blue","yellow"]?}
「YML中的對(duì)象寫(xiě)法:」
people:
name: zhangsan
age: 14
相當(dāng)于JSON中的
{
??"people":?{
?????"name":?"zhangsan"
?????"age":?14
??}?
}
當(dāng)然也可以是數(shù)組和對(duì)象之間形成的嵌套結(jié)構(gòu)
a:
b:
- d
c: e
相當(dāng)于
{
??"a":?{
????"b":?[?"d"?],
????"c":?"e"
???}
}
「從JSON到Y(jié)ML之間的過(guò)渡學(xué)習(xí)的注意要點(diǎn):」
你不再需要“{}”這種符號(hào)去區(qū)分層級(jí)邊界了,你需要考慮使用縮進(jìn) 這里可以使用注釋?zhuān)?符號(hào) 如果不涉及特殊符號(hào)比如“[”,你一般是不需要給YML中的字符串加雙引號(hào)或者單引號(hào)的(當(dāng)然加了也可以)
了解了這些,對(duì)于編寫(xiě)一個(gè)gitlab-ci的「hello world」已經(jīng)沒(méi)有問(wèn)題了。
當(dāng)然YML還有著比JSON更為豐富的功能,比如用”&"符號(hào)和"<<:*”符號(hào)可以實(shí)現(xiàn)的片段導(dǎo)入的功能,以及gitlab-ci提供的include關(guān)鍵字和extend關(guān)鍵字等提供的結(jié)構(gòu)編排功能。這些我將在最后面的小節(jié)中講解,這里暫時(shí)不多贅述
2.3 gitlab-ci.yml配置的特定關(guān)鍵字
在了解了YML文件的語(yǔ)法格式后,接下來(lái)需要了解的就是gitlab-ci獨(dú)特的配置關(guān)鍵字,這些關(guān)鍵字將在.gitlab-ci.yml中使用,并用來(lái)控制一個(gè)pipeline具體的運(yùn)作過(guò)程
gitlab提供了很多配置關(guān)鍵字,其中最基礎(chǔ)和常用的有這么幾個(gè)
stages stage script tags
「stages & stage」
stages定義在YML文件的最外層,它的值是一個(gè)數(shù)組,用于定義一個(gè)pipeline不同的流程節(jié)點(diǎn)
例如我們定義如下:
stages: # 分段
- install
- eslint
- build
- deploy
則在Gitlab交互界面中能夠看到如下展示

我們上面說(shuō)過(guò):「Job是pipeline的任務(wù)節(jié)點(diǎn),它構(gòu)成了pipeline的基本單元」
而stage/script/tags這三個(gè)關(guān)鍵字,都是作為Job的子屬性來(lái)使用的,如下所示,install就是我們定義的一個(gè)Job
install:
tags:
- sss
stage: install
script:
- npm install
「stage」
是一個(gè)字符串,且是stages數(shù)組的一個(gè)子項(xiàng),表示的是當(dāng)前的pipeline節(jié)點(diǎn)。
當(dāng)前stage的執(zhí)行情況能在交互面板上能看的清清楚楚:
正在執(zhí)行是藍(lán)色 尚未執(zhí)行是灰色 執(zhí)行成功是綠色 執(zhí)行失敗是紅色


「script」
它是當(dāng)前pipeline節(jié)點(diǎn)運(yùn)行的shell腳本(以項(xiàng)目根目錄為上下文執(zhí)行)。
這個(gè)script是我們控制CI流程的核心,我們所有的工作:從安裝,編譯到部署都是通過(guò)script中定義的shell腳本來(lái)完成的。
如果腳本執(zhí)行成功,pipeline就會(huì)進(jìn)入下一個(gè)Job節(jié)點(diǎn),如果執(zhí)行失敗那么pipeline就會(huì)終止
「tags」
tags是當(dāng)前Job的標(biāo)記,「這個(gè)tags關(guān)鍵字是很重要,因?yàn)間itlab的runner會(huì)通過(guò)tags去判斷能否執(zhí)行當(dāng)前這個(gè)Job」
例如我們?cè)趃itlab的面板中能看到當(dāng)前激活的runner的信息
Gitlab項(xiàng)目首頁(yè)=> setting => CI/CD => Runners

上面的這個(gè)sss就是當(dāng)前Runner的tags,這意味著:**這個(gè)runner只會(huì)執(zhí)行tag為sss的Job。**如果一個(gè)Job沒(méi)有tag或者tag不是sss,那么即使這個(gè)Runner是激活且空閑的,也不會(huì)去執(zhí)行!
基本的gitlab-ci關(guān)鍵字就介紹結(jié)束了,有了這些知識(shí)對(duì)于編寫(xiě)一個(gè)gitlab-ci的”hello world”已經(jīng)足夠了。對(duì)于更多的關(guān)鍵字的相關(guān)知識(shí),將在文章最后再進(jìn)行介紹
三.gitlab-ci實(shí)戰(zhàn)
「3.1 編寫(xiě)一個(gè)gitlab-ci的"hello world"」
好,說(shuō)了這么多終于到了實(shí)踐的部分了,請(qǐng)?jiān)徢懊娴膯拢旅嫖覍?huì)展示一下如何從零開(kāi)始實(shí)踐一個(gè)gitlab-ci的Hello world:
「1.在平臺(tái)上下載并安裝Gitlab-runner命令行」
我是在Mac上跑的ci,所以下面的適用于OSX系統(tǒng)(如果是其他平臺(tái),可自行參考以下官方鏈接中的相關(guān)資料)
?參考資料:https://docs.gitlab.com/runner/install/
?
依次運(yùn)行:
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
?備注:這個(gè)下載過(guò)程可能會(huì)很慢,你可以復(fù)制上面的鏈接到瀏覽器中翻墻下載,然后下載完畢再進(jìn)行后續(xù)處理
?
「2.初始化gitlab-runner」
cd ~
gitlab-runner install
gitlab-runner start
最后輸出如下,說(shuō)明成功了。

「3.注冊(cè)Runner」
運(yùn)行完gitlab-runner start只是完成了初始化,接下來(lái)你還要通過(guò)注冊(cè)才能運(yùn)行runner
?參考鏈接:https://docs.gitlab.com/runner/register/index.html
?
注冊(cè)runner只需要一條運(yùn)行命令:
sudo gitlab-runner register
然后寫(xiě)入相應(yīng)的token,url和tag等相關(guān)信息,就注冊(cè)完畢了。

上面要求輸入的Runner綁定的token和url, 獲取方式如下:
Gitlab項(xiàng)目首頁(yè)=> setting => CI/CD => Runners => Specific Runners

「4.激活Runner」
注冊(cè)完了可能還需要激活,這時(shí)我們可以看下面板,如果有個(gè)黑色的感嘆號(hào),這說(shuō)明runner注冊(cè)成功了,但是尚未激活(「如果是綠色的說(shuō)明已經(jīng)激活,本步驟跳過(guò)」)

激活方法是本地運(yùn)行:
sudo gitlab-runner verify
輸出

這時(shí)候回去看Gitlab面板里的Runner參數(shù):

是綠色就說(shuō)明激活成功了
「5.梳理和規(guī)劃Pipeline的不同階段和過(guò)程」
在編寫(xiě).gitlab-ci.yml前,首先需要考慮的是我們的pipeline分幾個(gè)階段處理。
從前端工程師的角度出發(fā),一個(gè)前端項(xiàng)目的PipeLine處理包括以下階段
「<1> install階段」
就是執(zhí)行npm install命令,根據(jù)package.json安裝node_modules依賴(lài)包
「<2> eslint階段」
執(zhí)行eslint檢查,判斷代碼格式是否符合規(guī)范,如果不符合則pipeline終止。
在這之前,我先通過(guò)npm install eslint安裝了eslint檢查工具,然后在項(xiàng)目根目錄下配置了.eslintrc文件。這部分可自行參考相關(guān)資料,這里暫不多贅述。
「<3>build階段」
編譯生成生產(chǎn)代碼,可以通過(guò)webpack之類(lèi)的打包工具執(zhí)行編譯。當(dāng)然可以通過(guò)框架提供的編譯命令進(jìn)行編譯,例如我這個(gè)示例項(xiàng)目是用 react-scripts腳手架搭建的,所以通過(guò)npx react-scripts build進(jìn)行編譯。
「<4>deploy階段」
deploy也就是部署階段,也就是把剛才bulid階段生成的生產(chǎn)代碼,部署到生產(chǎn)訪(fǎng)問(wèn)的服務(wù)器上。這里又具體有以下兩部分工作要做
「A.申請(qǐng)服務(wù)器 & 安裝web服務(wù) (準(zhǔn)備工作)」
(1)我本次使用的是百度云的「云服務(wù)器」(每天9點(diǎn)的時(shí)候可以搶有一定免費(fèi)使用期限的服務(wù)器)
(2)然后在本地終端通過(guò)ssh遠(yuǎn)程登陸服務(wù)器,并安裝「apache」以提供web服務(wù)
sudo apt-get install apache2
(3)然后,安裝完后的apache會(huì)在服務(wù)器下新增**/var/www/html/**目錄, 這個(gè)目錄就是存放網(wǎng)站資源的位置。
(4)最后我們只需要在每次部署的時(shí)候把生產(chǎn)的單頁(yè)面拷貝到這個(gè)頁(yè)面下,就能在瀏覽器上通過(guò)對(duì)應(yīng)的 「IP+路徑」 來(lái)訪(fǎng)問(wèn)Web頁(yè)面了。
「B. 部署資源(每次pipeline都進(jìn)行)」
我下面的示例中,是通過(guò) 「scp」 這一命令,將本地機(jī)器代碼遠(yuǎn)程拷貝到云服務(wù)器上。
因?yàn)檫@一命令需要輸入密碼,所以通過(guò) 「sshpass」 命令攜帶密碼再執(zhí)行scp:
sshpass -p $PASSWORD scp -r ./build $CUSTOM_USERNAME@$CUSTOM_IP:/var/www/html
這里說(shuō)明一下,「Gitlab有自定義變量的功能」,例如我們覺(jué)得直接在YML中寫(xiě)入密碼/賬號(hào)等信息不太好,那么「可以通過(guò)美元符號(hào)$寫(xiě)入一個(gè)預(yù)定義的變量,然后在Gitlab面板上輸入它」

「7.編寫(xiě).gitlab-ci.yml配置文件」
回顧一下之前YML語(yǔ)法規(guī)則和gitlab-ci配置關(guān)鍵字的知識(shí),就不難編寫(xiě)出以下YML文件
stages:?#?分段
??-?install
??-?eslint
??-?build
??-?deploy
cache:?#?緩存
??paths:
????-?node_modules
????-?build
install-job:
??tags:
????-?sss
??stage:?install
??script:
????-?npm?install
eslint-job:
??tags:
????-?sss
??stage:?eslint
??script:
????-?npm?run?eslint
build-job:
??tags:
????-?sss
??stage:?build
??script:
????-?npm?run?build
deploy-job:
??tags:
????-?sss
??stage:?deploy
??script:
????-?sshpass?-p?$PASSWORD?scp?-r?./build?$CUSTOM_USERNAME@$CUSTOM_IP:/var/www/html
「package.json」如下
{
??...
??"scripts":?{
????"start":?"react-scripts?start",
????"build":?"npx?react-scripts?build",
????"eslint":?"eslint?./src",
??},
??....
}
「8.提交項(xiàng)目代碼」
OK!終于到最后一步了,commit然后push
可以看到運(yùn)行如下

跑完后

最后輸入我們部署的IP看看我們部署的網(wǎng)頁(yè)

發(fā)現(xiàn)已經(jīng)把我們的項(xiàng)目代碼部署上去了

四. Gitlab-ci坑點(diǎn)詳解
說(shuō)多了都是淚。。。。。
下面總結(jié)一下使用過(guò)程中遇到的典型坑點(diǎn)
「1.Runner未激活問(wèn)題」
有時(shí)候注冊(cè)之后,查看面板上的Runner信息,可能會(huì)發(fā)現(xiàn)Runner處在未激活狀態(tài)

解決方法:
運(yùn)行以下命令重新啟動(dòng)runner
sudo gitlab-runner verify
sudo gitlab-runner restart
「2.Job一直掛起,沒(méi)有Runner來(lái)處理」

1.首先考慮的是不是Runner沒(méi)有激活,如果沒(méi)有那么按上面方式處理
2.還可能是tag沒(méi)有匹配到,上面說(shuō)過(guò),Runner注冊(cè)時(shí)是要填寫(xiě)綁定tag的,如果你在YML里面編寫(xiě)Job沒(méi)有帶上tag是不會(huì)有自定義Runner來(lái)處理。解決方法:給Job加tags
3.最后一種可能:你連續(xù)注冊(cè)了多個(gè)Runner,這些Runner沖突了,或者是新注冊(cè)的Runner和舊Runner使用了同一個(gè)token,這時(shí)候的解決方法如下:
「先刪掉本地其他舊的Runner」
sudo gitlab-runner unregister --all-runners
然后重置token,并使用更新后的token重新注冊(cè)一個(gè)Runner

「3.specific Runner被Share Runner搶占了Job」
有時(shí)候你可能會(huì)發(fā)現(xiàn):你的Job并沒(méi)有被你新建的Runner執(zhí)行,而是被Share Runner搶先執(zhí)行了。你如果不想要Share Runner,你可以在Gitlab面板上關(guān)掉

五.gitlab-ci進(jìn)階
5.1 YML的片段復(fù)用和模塊化
上面我們編寫(xiě)了gitlab-ci的**"hello world"**。但在實(shí)際項(xiàng)目的運(yùn)行中,.gitlab-ci.yml的編寫(xiě)可能會(huì)漸趨復(fù)雜。那么這個(gè)時(shí)候YML的一些其他語(yǔ)法功能就派上用場(chǎng)了,上面我們將JSON和YML的基本結(jié)構(gòu)做比較并發(fā)現(xiàn)它們的相似之處,但實(shí)際上,「YML提供了比JSON更為豐富的功能。」
「YML的片段復(fù)用功能」
「試思考」:如果有一段配置片段會(huì)被很多Job使用,那么如果重復(fù)寫(xiě)入片段,則會(huì)使我們的YML文件變得過(guò)分冗長(zhǎng)。
而如果能把這段提前進(jìn)行定義,并根據(jù)別名進(jìn)行導(dǎo)入,就能讓YML文件簡(jiǎn)潔很多了。
「YML的語(yǔ)法天然提供了這個(gè)功能:」
使用 **&**符號(hào)可以定義一個(gè)片段的別名 使用 **<<**符號(hào)和 ***** 符號(hào)可以將別名對(duì)應(yīng)的YML片段導(dǎo)入
.common-config:?&commonConfig
??only:?#?表示僅在develop/release分支上執(zhí)行
????refs:
??????-?develop
??????-?release
install-job:
??#?其他配置?....
??<<:?*commonConfig
build-job:
??#?其他配置?....
??<<:?*commonConfig
「YML的模塊化功能」
試思考,如果我們配置腳本很長(zhǎng)的話(huà),我們一定要把它寫(xiě)在.gitlab-ci.yml這單獨(dú)一個(gè)文件里嗎?
能否將它分成多個(gè)yml文件,然后把其他YML文件導(dǎo)入到入口YML文件(.gitlab-ci.yml)中呢。
gitlab-ci提供的include關(guān)鍵字便可實(shí)現(xiàn)這個(gè)功能, 它可以用來(lái)導(dǎo)入外部的YML文件。
例如我們有如下的YML結(jié)構(gòu)
├── .gitlab-ci.h5.yml'
├── .gitlab-ci.bd.yml'
├── .gitlab-ci.wx.yml
└── .gitlab-ci.yml
「那么在.gitlab-ci.yml中這么寫(xiě),就可以對(duì)它們做合并」
include:
??-?'/.gitlab-ci.wx.yml'
??-?'/.gitlab-ci.bd.yml'
??-?'/.gitlab-ci.h5.yml'
gitlab-ci還提供了extend關(guān)鍵字,它的功能和前面提到的YML的片段導(dǎo)入的功能是一樣的,
不過(guò)可讀性更好一些。
.common-config:?
??only:?#?表示僅在develop/release分支上執(zhí)行
????refs:
??????-?develop
??????-?release
install-job:
??#?其他配置?....
??extends:?.common-config
build-job:
??#?其他配置?....
??extends:?.common-config
5.2 Gitlab-ci的其他配置項(xiàng)
「cache關(guān)鍵字」
cache關(guān)鍵字是需要特別著重講的一個(gè)關(guān)鍵字。顧名思義,它是用來(lái)做緩存的。
為什么要做緩存呢?當(dāng)然是為了「重復(fù)運(yùn)行pipeline的時(shí)候不會(huì)重復(fù)安裝全部node_modules的包」,從而減少pipeline的時(shí)間,提高pipeline的性能。
「但是,這并不是cache關(guān)鍵字唯一的功能!」
在介紹cache的另外一個(gè)功能之前,我要先說(shuō)一下gitlab-ci的一個(gè)優(yōu)點(diǎn)“惡心人”的特點(diǎn):
它在運(yùn)行下一個(gè)Job的時(shí)候,會(huì)默認(rèn)把前一個(gè)Job新增的資源刪除得干干靜靜

沒(méi)錯(cuò),也就是說(shuō),我們上面bulid階段編譯生成的包,會(huì)在deploy階段運(yùn)行前被默認(rèn)刪除!(我生產(chǎn)包都沒(méi)了我怎么部署emmmmmmm)
而cache的作用就在這里體現(xiàn)出來(lái)了:如果我們把bulid生產(chǎn)的包的路徑添加到cache里面,雖然gitlab還是會(huì)刪除bulid目錄,但是因?yàn)樵趧h除前我們已經(jīng)重新上傳了cache,并且在下個(gè)Job運(yùn)行時(shí)又把cache給pull下來(lái),那么這個(gè)時(shí)候就可以實(shí)現(xiàn)在下一個(gè)Job里面使用前一個(gè)Job的資源了
總而言之,cache的功能體現(xiàn)在兩點(diǎn):
「在不同pipeline之間重用資源」 「在同一pipeline的不同Job之間重用資源」
雖然cache會(huì)緩存舊的包,但我們并不用擔(dān)心使用到舊的資源,因?yàn)閚pm install還是會(huì)如期運(yùn)行,并檢查package.json是否有更新,npm build的時(shí)候,生成的build資源包也會(huì)覆蓋cache,并且在當(dāng)前Job運(yùn)行結(jié)束時(shí),作為**"新的cache"**上傳
artifacts關(guān)鍵字
這個(gè)關(guān)鍵字的作用是:將生成的資源作為pipeline運(yùn)行成功的附件上傳,并在gitlab交互界面上提供下載
例如我們新增以下YML
Build-job:
??stage:?build
??script:
??-?'npm?run?build'
??artifacts:
????name:?'bundle'
????paths:?
??????-?build/
pipeline跑完后是這樣的:

image/services
這兩個(gè)關(guān)鍵字可使用Docker的鏡像和服務(wù)運(yùn)行Job,具體可參考Docker的相關(guān)資料,這里暫不多加敘述
only/except
這兩個(gè)關(guān)鍵字后面跟的值是tag或者分支名的列表。
故名思義
only的作用是指定當(dāng)前Job僅僅只在某些tag或者branch上觸發(fā) 而except的作用是當(dāng)前Job不在某些tag或者branch上觸發(fā)
job:
??#?use?regexp
??only:
????-?/^issue-.*$/
????-?develop
????-?release
allow_failure
值為true/false, 表示當(dāng)前Job是否允許允許失敗。
默認(rèn)是false,也就是如果當(dāng)前Job因?yàn)閳?bào)錯(cuò)而失敗,則當(dāng)前pipeline停止 如果是true,則即使當(dāng)前Job失敗,pipeline也會(huì)繼續(xù)運(yùn)行下去。
job1:
??stage:?test
??script:
????-?execute_script_that_will_fail
??allow_failure:?true
retry
顧名思義,指明的是當(dāng)前Job的失敗重試次數(shù)的上限。
但是這個(gè)值只能在0 ~2之間,也就是重試次數(shù)最多為2次,包括第一次運(yùn)行在內(nèi),Job最多自動(dòng)運(yùn)行3次
timeout
配置超時(shí)時(shí)間,超過(guò)時(shí)間判定為失敗
Job:
??script:?rspec
??timeout:?3h?30m
When
表示當(dāng)前Job在何種狀態(tài)下運(yùn)行,它可設(shè)置為3個(gè)值
「on_success」: 僅當(dāng)先前pipeline中的所有Job都成功(或因?yàn)橐褬?biāo)記,被視為成功allow_failure)時(shí)才執(zhí)行當(dāng)前Job 。這是默認(rèn)值。 「on_failure」: 僅當(dāng)至少一個(gè)先前階段的Job失敗時(shí)才執(zhí)行當(dāng)前Job。 「always」: 執(zhí)行當(dāng)前Job,而不管先前pipeline的Job狀態(tài)如何。
分享前端好文,點(diǎn)亮?在看?
