前言
假如我們有一個(gè)項(xiàng)目,已經(jīng)部署在服務(wù)器上面了,然后但是我們想要修改其中的一個(gè)頁面的部分功能,我們需要做些什么事情呢?
先拉取gitlab上的代碼
對代碼進(jìn)行修改開發(fā)
測試代碼是否正常運(yùn)行
打包我們的前端代碼
將代碼重新上傳服務(wù)器【要是是第一次部署服務(wù)器,那你得在服務(wù)器上安裝你的項(xiàng)目所需要的環(huán)境,比如node,還得維護(hù)環(huán)境】
在服務(wù)器上看代碼是否正常運(yùn)行
提交代碼
這樣一看,非常麻煩,但凡我們想要修改一點(diǎn)兒東西都得經(jīng)歷上述步驟,時(shí)間也浪費(fèi)了,也沒法保證每次提交服務(wù)器都是正常運(yùn)行的。
所以我們有了GitLab CI,讓我們關(guān)注于開發(fā),而不是這些提交部署的流程,直接一鍵上傳,自動部署
1.什么是GitLab CI?
GitLab CI/CD是一個(gè)GitLab工具,是基于GitLab的CI/CD系統(tǒng),用于持續(xù)方法進(jìn)行軟件開發(fā),CI/CD就是一個(gè)流程(也稱管道)
持續(xù)集成 (CI):指的是,頻繁地(一天多次)將代碼集成到主干。
持續(xù)交付/持續(xù)部署 (CD):當(dāng)開發(fā)人員在主分支合并一個(gè)提交時(shí),這個(gè)分支將被構(gòu)建,測試,如果一切順利,則部署到生產(chǎn)環(huán)境中
從GitLab8.0開始,GitLab全面集成了GItLab-CI,且對所有項(xiàng)目默認(rèn)開啟。只要在項(xiàng)目倉庫的根目錄添加 .gitlab-ci.yml 文件,并且配置了 Runner (運(yùn)行器),那么每一次合并請求(MR)或者 push 都會觸發(fā) CI pipeline
每次推送時(shí),都要運(yùn)行一系列腳本來構(gòu)建、測試和驗(yàn)證代碼更改,然后再將其合并到主分支中。持續(xù)交付和部署相當(dāng)于更進(jìn)一步的CI,可以在每次推送到倉庫默認(rèn)分支的同時(shí)將應(yīng)用程序部署到生產(chǎn)環(huán)境。
意思是把測試、打包、發(fā)布都交給自動化的工具,提高效率,減少失誤,開發(fā)人員只需要開發(fā)和提交代碼到git就可以完成后續(xù)工作
2.基礎(chǔ)概念
(1)Pipelines
是CI/CD的最上層組件,就是流水線,一次Pipeline 其實(shí)相當(dāng)于一次構(gòu)建任務(wù),可以包含安裝依賴、運(yùn)行測試、編譯、部署等流程,任何提交或者M(jìn)erge Request的合并都可以觸發(fā)Pipeline
(2)Stages
一次Pipeline 中可以有多個(gè)Stages,一個(gè)Stages失敗,后面就都失敗,構(gòu)建Pipeline也就失敗
+--------------------------------------------------------+
| Pipeline |
| +-----------+ +------------+ +------------+ |
| | Stage 1 |---->| Stage 2 |----->| Stage 3 | |
| +-----------+ +------------+ +------------+ |
+--------------------------------------------------------+
(3)Jobs
job是任務(wù),是GitLab CI中可以獨(dú)立控制并運(yùn)行的最小單位,一次提交可能完成一個(gè)或者多個(gè)job
一次Stages 中可以有多個(gè)Jobs,一個(gè)Jobs失敗,后面就都失敗,Stages也就失敗,Pipelines也失敗
+------------------------------------------+
| Stage 1 |
| +---------+ +---------+ +---------+ |
| | Job 1 | | Job 2 | | Job 3 | |
| +---------+ +---------+ +---------+ |
+------------------------------------------+
(4)Runners
Runner 是用來用執(zhí)行Pipeline的應(yīng)用,保證每次代碼變更就根據(jù).gitlab-ci.yml執(zhí)行
GitLab-Runner是配合GitLab-CI進(jìn)行使用的。GitLab里面的每一個(gè)工程都會定義一個(gè)屬于這個(gè)工程的軟件集成腳本,用來自動化地完成一些軟件集成工作。
在GitLab的項(xiàng)目上,側(cè)邊的CI/CD上可以看到上述的Pipelines和Jobs,可以看到項(xiàng)目pipelines和jobs的關(guān)系。

Pipelines和Stages和jobs的關(guān)系可以如下所示,一個(gè)pipelines可包含多個(gè)Stages,一個(gè)Stages可以包含多個(gè)Jobs,一旦其中一個(gè)失敗,后續(xù)的都不會成功,但是如果某個(gè)任務(wù)設(shè)置為可以失敗,那就可以繼續(xù)運(yùn)行

3.CI/CD發(fā)布流程
正常的發(fā)布流程可以包括檢查樣式-測試-構(gòu)建-部署,但是可以根據(jù)項(xiàng)目的實(shí)際情況而定
觸發(fā)CI/CD有多種方式,比如git tag 合并分支,調(diào)用api各種,可以配置.gitlab-ci.yml文件來達(dá)到你想要的效果
CICD的好處
持續(xù)集成加快開發(fā)周期:讓開發(fā)者的工作效率變高,減少代碼檢測的時(shí)間,交給自動化工具去實(shí)現(xiàn)
持續(xù)部署讓發(fā)布頻率變快,風(fēng)險(xiǎn)變低:容易發(fā)現(xiàn)問題,一旦構(gòu)建哪一步出錯(cuò),就可以在幾秒鐘幾分鐘內(nèi)得到反饋進(jìn)行修正
構(gòu)建測試部署自動化,輕松應(yīng)對代碼變更,加速迭代
降低測試成本:語言可以檢查編譯錯(cuò)誤,測試檢查輸入輸出錯(cuò)誤,CICD直接全部一次性檢查,
4.GitLab CI/CD環(huán)境搭建及使用教程
如果要觸發(fā)CI、CD,就需要一個(gè)可以用來執(zhí)行pipeline的Runner,git runner 安裝注冊如下流程
gitlab-runner是一個(gè)執(zhí)行Gitlab CI/CD的應(yīng)用,先注冊gitlab-runner,然后配置的.gitlab-ci.yml的任務(wù)和指令就可以成功執(zhí)行,然后再通過api將結(jié)果反饋Gitlab。
(1)GitLab Runner分類
runner有下面三種分類,每種分類對應(yīng)不同場景
shared runners:共享runner 可以讓當(dāng)前gitlab倉庫的所有項(xiàng)目共用,是gitlab管理員統(tǒng)一配置的runner,只要你在當(dāng)前的gitlab中,就可以使用
group runners:組runner 可以讓組中的項(xiàng)目共用,在組cicd中注冊
Specific Runners:項(xiàng)目runner 僅可以在當(dāng)前項(xiàng)目使用,在當(dāng)前項(xiàng)目下配置
GitLab Runner在不同的類型中,我們所扮演的角色不同,權(quán)限不同,是否能看到runner也不一樣,這個(gè)也需要進(jìn)行安裝和注冊之后,才可以進(jìn)行使用。
(2)安裝注冊過程
官網(wǎng)安裝教程:在windows上,選擇64位

1.以管理員身份安裝
右鍵PowerShell,跳轉(zhuǎn)到gitlab-runner.exe所在目錄
.\gitlab-runner.exe install // 安裝
.\gitlab-runner.exe start // 運(yùn)行
2.注冊新建runner
在不使用已經(jīng)建好的shared runners和group runners情況下
注冊新建新的runner,新建Specific Runners【僅在當(dāng)前項(xiàng)目使用的runner】
.\gitlab-runner.exe register
要注冊新建runner,需要url和token
url和token在gitlab項(xiàng)目里面的setting->CI/CD里面,找到Runners展開可查看


注冊流程選項(xiàng)如下

成功之后會出現(xiàn)新的runner在這個(gè)Runners下面,注冊成功之后就可以進(jìn)行g(shù)itlab.yml文件的編寫工作了,編寫之前先學(xué)習(xí)常用的配置,看這些命令是什么意思。
(3).gitlab-ci.yml常用配置學(xué)習(xí)
GitLab Runner準(zhǔn)備就緒之后,就應(yīng)該學(xué)習(xí)配置文件,知道如何編寫配置文件達(dá)到運(yùn)行的目的。
將.gitlab-ci.yml文件添加到存儲庫的根目錄,并將GitLab項(xiàng)目配置為使用Runner,則每次提交或推送都會觸發(fā)CI 管道。
常用命令如下
(1)Stages
用來定義pipeline的,比如發(fā)布(publish)之前需要進(jìn)行l(wèi)int、test、build,那這四個(gè)stage就構(gòu)成一個(gè)pipeline
stages
- lint
- test
- build
- publish
(2)Job
假如我們需要看lint是否有錯(cuò)誤,就加一個(gè)job進(jìn)行判斷,并寫出該job屬于哪個(gè)stage,一個(gè)stage可以有多個(gè)job
job-lint: //任務(wù)名稱
stages:lint // 是哪個(gè)stage的
script:npm run lint // 執(zhí)行命令是什么
(3)variables
在.gitlab-ci.yml中定義變量,Jobs中定義的變量有作用域。
在跑一個(gè)job的時(shí)候,我們或許需要環(huán)境變量,或者不希望展示的東西,在variables下可以配置變量名和值,通常是需要保密的變量
variables:
TEST: "HELLO WORLD"
然后讓這個(gè)變量被引用
script: - echo $TEST //執(zhí)行打印變量TEST
(4)only/except
只希望在什么時(shí)候觸發(fā),不執(zhí)行某項(xiàng)任務(wù)
job-lint: // 任務(wù)名稱
stages:lint // 是哪個(gè)stage的
script:npm run lint // 執(zhí)行命令是什么
only:
-tags // 希望在打tag的時(shí)候觸發(fā)
//或者
expect:/^hotfix-.+$/ // 不對某個(gè)文件進(jìn)行l(wèi)int
(5)when
什么時(shí)候執(zhí)行什么當(dāng)前job,默認(rèn)值on_success,表示當(dāng)前任務(wù)之前的任務(wù)全部執(zhí)行成功,則執(zhí)行當(dāng)前工作,其他的常見屬性有:on_failure,always,manual,delayed,never
build_job:
when: on_success // 當(dāng)前面成功的時(shí)候,就執(zhí)行
stage: build
needs: lint_job
(6)image
需要的docker鏡像
image: node:12.18
(7)tags
定義執(zhí)行該Job的runner,值為定義runner的tag,不寫則無法執(zhí)行
job:
tags:
- hello //runner的名字
當(dāng)前job會在對應(yīng)名字的Runner中執(zhí)行,如果已經(jīng)有了其他的shared runners或者group runners,也可以直接使用,就不需要新建runner了
(8)script
script是Job的必選字段,用來寫shell腳本,可以執(zhí)行多個(gè)行命令
before_script、after_script分別在Job開始之前前和結(jié)束后執(zhí)行的腳本,可以寫在全局變量中
job:
before_script:
- npm install
script:
- npm install --registry=https://registry.npm.taobao.org
- npm run build
(9)cache、artifacts
cache:定義緩存文件或緩存文件夾
artifacts:可以在任務(wù)執(zhí)行完畢后,緩存對應(yīng)的資源,可以直接下載本地
artifacts:
paths: //執(zhí)行任務(wù)完成之后,可以下載對應(yīng)的dist文件
- dist/
學(xué)習(xí)完.gitlab-ci.yml文件中的基本命令之后,進(jìn)行一個(gè)項(xiàng)目實(shí)戰(zhàn),并結(jié)合上一篇文章中的docker進(jìn)行使用,一舉完成自動化構(gòu)建部署。
5.GitLab CI+Docker+GitLab Runner自動化部署
有了前期的docker基礎(chǔ),有了Dockerfile文件,編寫.gitlab-ci.yml文件
(1).gitlab-ci.yml文件示例
image: node:alpine //使用的docker鏡像
stages: //兩個(gè)stages,build和push
- build
- push
cache: //定義緩存文件夾,緩存node_modules包
paths:
- node_modules/
- packages/font/node_modules/
- packages/back/node_modules/
install:// 前端項(xiàng)目build
stage: build
script: // script里面寫執(zhí)行的命令
- yarn install // 安裝依賴
- cd packages/font //進(jìn)入前端目錄
- npm run build //打包前端項(xiàng)目
only: //主分支提交的時(shí)候該job運(yùn)行
- master
tags: // 在名字是shell的runner上
- shell
artifacts:// 在這個(gè)job完成之后可以下載packages/back/page文件
paths:
- packages/back/page
docker-image: // 上傳docker
stage: build
script:
- docker image build ./ -t file_upload:$CI_COMMIT_REF_NAME // 新建docker鏡像 名字是file_upload:tag名字
only:
- tags // 在打tag的時(shí)候執(zhí)行該job
tags:
- shell
docker-push:// 部署到遠(yuǎn)程私有倉庫
stage: push
script:
- docker login 遠(yuǎn)程接口地址 -u 賬號名 -p 密碼 //登錄遠(yuǎn)程倉庫
- docker tag file_upload:$CI_COMMIT_REF_NAME 遠(yuǎn)程倉庫接口地址/node/fileupload:$CI_COMMIT_REF_NAME // 給docker鏡像打tag
- docker push 遠(yuǎn)程倉庫接口地址/node/fileupload:$CI_COMMIT_REF_NAME //上傳到遠(yuǎn)程倉庫
- docker rmi 遠(yuǎn)程倉庫接口地址/node/fileupload:$CI_COMMIT_REF_NAME //刪除本地的鏡像
only:
- tags
tags:
- shell //在哪個(gè)runner上運(yùn)行,這個(gè)是runner的名字
寫好.gitlab-ci.yml文件和Dockerfile文件之后,相當(dāng)于Docker和GitLab CI都已經(jīng)準(zhǔn)確就緒,現(xiàn)在上傳代碼到GitLab,就可以自動化構(gòu)建和檢測代碼這些了
其中的構(gòu)建流程全是靠.gitlab-ci.yml文件實(shí)現(xiàn)的,所以需要會寫.gitlab-ci.yml文件
(2)遇到的問題
在新的 WIN10 機(jī)器上安裝帶有 shell 執(zhí)行器(即 powershell)的 gitlab-runner 并啟動 CI 構(gòu)建會引發(fā)以下錯(cuò)誤

修改config.toml文件
// 修改
[[runners]]
name = "ci-runner"
url = "http://xxx.yyy.xx/"
token = "XXXXX"
executor = "shell"
shell = "pwsh"
// 成為
[[runners]]
name = "ci-runner"
url = "http://xxx.yyy.xx/"
token = "XXXXX"
executor = "shell"
shell = "powershell"
(3)總結(jié)
我們要進(jìn)行CI /CD,就需要一個(gè)可以用來執(zhí)行pipeline的Runner,所以安裝注冊了GitLab Runner,然后編寫.gitlab-ci.yml文件達(dá)到自動化構(gòu)建的目的
6.參考資料
(1)基于 GitLab CI 搭建前端自動構(gòu)建環(huán)境
(2)基于 GitLab CI/CD 的前端自動化構(gòu)建、發(fā)布實(shí)踐
(3)Install GitLab Runner on Windows
(4)gitlab CI/CD