CICD 入門指北
目錄
- 簡介
- 持續整合
- 持續部署
- Gitlab CICD
- 如何使用 Gitlab CI/CD
- CICD 工作流
- .gitlab-ci.yml 檔案結構
- stages
- variables
- before_script
- test_stage
- stage
- script
- artifacts
- allow_failure
- build_stage
- when
- only
- deploy_stage
簡介
CICD 是 持續整合(Continuous Integration)和持續部署(Continuous Deployment)簡稱。指在開發過程中自動執行一系列指令碼來減低開發引入 bug 的概率,在新程式碼從開發到部署的過程中,儘量減少人工的介入。
持續整合
持續整合指在和向遠端倉庫 push 程式碼後,在這次提交合併入主分支前進行一系列測試,構建等流程。假設現在有個應用的程式碼儲存在 gitlab 上,每天開發者都 push 很多次提交,針對每次 push,你可以建立一系列指令碼進行自動測試,降低往應用裡引入錯誤的概率。這就是持續整合,它可應用在包括開發分支在內的多個分支上。
持續部署
持續部署在持續整合的基礎上更進一步,指將推送指倉庫預設分支的部署至產品環境。如果這部分需要手動觸發,這就是一個持續交付(Continuous Delivery)環節。
Gitlab CICD
Gitlab 內建了 CICD 工具,不需要使用第三方工具。
如何使用 Gitlab CICD
使用 Gitlab 的 CICD ,只需要在 Gitlab 的倉庫的根目錄中新增 .gitlab-ci.yml
檔案。
這個檔案中,可以定義CICD 的各個環節,配置每個環節執行的命令,觸發方式等。這個配置檔案其實就是按照 YAML 規定了一些結構的 shell 指令碼,裡面的命令會在符合條件時逐一執行。一旦在倉庫中新增這個檔案,Gitlab 會檢測到它並用名為 Gitlab Runner 工具執行它。每次觸發的 CICD 會把配置中的腳劃分為不同的 job,多個 job 組成一個 pipeline。最簡單的 .gitlab-ci.yml
檔案可以包含:
before_script:
- apt-get install rubygems ruby-dev -y
run-test:
script:
- ruby --version
其中 before_scripts
屬性會在執行任一指令碼前預裝一些需要的依賴(類似 unittest
的 setUp
方法),此後名為 run-test
的指令碼會顯示當前系統的 ruby 版本。這兩個步驟組成了一個 pipeline 會在這個倉庫的每次push後執行。這行任務的執行情況也可以在 Gitlab 的對應頁面上檢視,就像在 Terminal 中看日誌一樣。
而每個 pipeline 的 job 的執行情況也可以在頁面上檢視
如果中途報錯了,可以一鍵回滾
CICD 工作流
假設你在本地修改了一些程式碼以增加一些特性,當你把這些改動 push 到遠端倉庫的特性分支後,專案裡設定的 CICD pipeline 就被觸發了,一般流程如下:
- 執行自動指令碼(序列或並行):
- 構建並測試應用
- 在合併前 review 改動
上述流程如果沒有問題就可以把改動合併入主分支,CD 會自動把它部署到產品中,如果發現了任何問題,還能一鍵回滾。
工作流程圖如下:
該圖簡要顯示了基本的工作流,想要了解 Gitlab CICD 的更多特請,請參閱CICD 索引表
.gitlab-ci.yml 檔案結構
.gitlab-ci.yml 是指定了 CICD 相關配置的 YAML 檔案。(YAML 是專門用來寫配置檔案的語言,簡潔強大,和 python 一樣用縮排代表層級,表達能力和 JSON 基本一致,但格式更方便。相關知識可以參考阮昱峰老師的博文。
一般而言,CICD 過程會包含如下最外層的 key:
stages
: 定義整個 CICD pipeline 的job
數量和名稱variables
: 定義 CICD 流程中的一些環境變數before_scripts
: 在每個job
的scripts
執行前進行的命令集,一般是建立目錄,列印 context 目錄等操作,可類比unittest
的setUp
方法stage
: 定義了一個job
的具體流程,可以在前面加上名稱
下面通過一個例子進行一些講解
stages:
- test
- build
- deploy
variables:
GIT_STRATEGY: none
PROJECT_REPO_NAMESPACE: test
PROJECT_REPO_NAME: cicd_learn
DEPLOYMENT_REPO_NAMESPACE: test
DEPLOYMENT_REPO_NAME: deploy_test
before_script:
- export ROOT_PATH=$(pwd)
- echo 'root path:' $ROOT_PATH
- mkdir $PROJECT_REPO_NAME
- cd $PROJECT_REPO_NAME
- <some git manipulation here>
- echo 'date:' $DATE
test_stage:
stage: test
script:
- <test related command here>
artifacts:
paths:
- xxxx.html
when: always
allow_failure: false
build_stage:
stage: build
script:
- <build related command here>
when: manual
allow_failure: false
only:
- master
deploy:
stage: deploy
script:
- <deploy related command here>
allow_failure: false
only:
- master
stages
例子中 stages
值為一個陣列(p.s. 用 - 代表陣列和 markdown 類似)。包含了三個 job
,test
, build
, deployr
分別實現自動測試,打包專案和部署。下方的 stage
必須在全域性定義的 stages
內。
variables
值為鍵值物件,為了後續的流程,此處定義了開發專案和部署專案的 namespace 和 repo_name。同 shell 類似,後續使用其值需要加上 $ 符號。定義的變數也有對應的作用域,定義在頂層就可以作為全域性變數供所有 job
使用,如果是一些 job
特有的變數,就定義在 job
內部。
before_script
值為陣列,每一個元素其實就是一個 linux 命令,寫的時候裝作自己在寫 shell 就好。該部分主要生成了後續構建需要的映象標籤,切換當前目錄等。為了 debug 方便,這些變數最好列印。類似的,如果在 job
完成後有一些時候操作,可以定義 after_script
。需要注意的是如果定義在頂層,內部的命令會在每個 job
執行之前執行,如果某些 job
需要特別的預操作,可以在 job 內部再配置一個 before_script
物件,它會複寫外部的全域性預操作。
test_stage
名為 test
的 job
的具體配置,一般是個複合物件。
stage
job
對應的 stage
,如果有多個 job
對應同一個 stage
,在執行時會並行執行這些 job
。
script
這個 job
執行的命令,此處是進入的專案倉庫目錄,並且執行了一個 shell 指令碼,這個指令碼定義了執行專案的所有單元測試。一般建議如果要執行的命令過多,就把這些命令寫成指令碼放在專案內。CICD 流程直接執行這個指令碼。
artifacts
這個物件用來定義 job
的產出,比如我們讓 test_stage
產出一個 html 格式的報告,顯示每個單元測試的執行情況(報告生成相關程式碼寫在專案內)。 陣列內的 paths
和 when
分別定義報告的路徑和產出場景。此處表示報告放置於根目錄下,任何時候都要提供報告。設定正確後,就可以 Gitlab 的 pipline 頁面上可以下載相關檔案。
allow_failure
見名知意,如果值為 true,那麼即使沒通過測試,也可以執行後續的 job
.
build_stage
該步驟在測試通過的基礎上,把專案編譯打包,方便後續部署。
when
此處的 when
定義在 job
內的頂層,值為 manual 表示其需要在 Gitlab 上手動觸發(頁面上點選按鈕即可)。
only
only
指明瞭 job
的執行場景,可以是分支名,表明只有 master 分支可以執行 build
,如果要用排除法反向指定,可以用 except
。
deploy_stage
所有的 key 現在你應該都瞭解了,這裡不再贅述。這一步驟主要是將部署產品的伺服器上的內容更新。
相關文章
- Electron入門指北
- SourceGenerator入門指北
- Electron 入門指北(二)
- Electron 入門指北(三)
- Electron 入門指北(一)
- Redis 入門權威指北Redis
- Knative 初體驗:CICD 極速入門
- Flutter 入門指北(Part 6) 之路由Flutter路由
- Flutter 入門指北(Part 1)之 DartFlutterDart
- Nginx 簡單入門指北不指南Nginx
- [譯] IBM 工程師的 TensorFlow 入門指北IBM工程師
- Flutter 入門指北(Part 2)之基礎部件Flutter
- Flutter 入門指北(Part 11)之狀態管理,BLoCFlutterBloC
- Flutter 入門指北(Part 10)之手勢處理和動畫Flutter動畫
- Flutter 入門指北(Part 9)之彈窗和提示(SnackBar、BottomSheet、Dialog)Flutter
- DroneCI+Github入坑指北Github
- 戰鬥數值新手入門指北:MOBA基礎及裝備篇
- Koa:核心探祕與入坑指北
- Redux:全揭祕與入坑指北(中)Redux
- Redux:全揭祕與入坑指北(上)Redux
- 『併發包入坑指北』之阻塞佇列佇列
- 入門入門入門 MySQL命名行MySql
- 基於Gitlab的CICD流程Gitlab
- UIAppearcance 使用指北UIAPP
- proxychains 使用指北AI
- React Hooks 指北ReactHook
- 『併發包入坑指北』之向大佬彙報任務
- CICD最簡實踐————github actionsGithub
- 基於github的CICD實踐Github
- 何入CTF的“門”?——所謂入門就是入門
- 如何入CTF的“門”?——所謂入門就是入門
- scala 從入門到入門+
- makefile從入門到入門
- gRPC(二)入門:Protobuf入門RPC
- Protocol Buffer 使用指北Protocol
- Ansible 學習指北
- Flutter路由管理指北Flutter路由
- TCP學習指北TCP