# gitlab CI/CD 介紹 https://ithelp.ithome.com.tw/users/20120986/ironman/2733 https://ithelp.ithome.com.tw/articles/10238027 https://ithelp.ithome.com.tw/articles/10219083 https://docs.gitlab.com/ee/user/application_security/sast/ https://docs.gitlab.com/ee/ci/introduction/#a-deeper-look-into-the-cicd-basic-workflow https://www.gliyao.com/57/%E7%82%BA%E4%BB%80%E9%BA%BC%E5%B0%8E%E5%85%A5-gitlab-ci https://gitlab-book.tw/ithelp/gitlab-ci/install-runner/ https://chengweichen.com/2021/03/gitlab-ci-executor.html ## 何謂CI CI(Continuous integration),即是「持續整合」 針對軟體系統的每個變動,能持續且自動地進行驗證。 ### CI該做些什麼事? CI流程可能包含 - 建置(build) 開發人員在每一次的 Commit & Push 後,都能夠於統一的環境自動 Build 程式,透過此一步驟可以避免每個開發人員因本機的環境&套件版本不相同,造成 Service 異常。 - 測試(test) 當程式編譯完成後,將會透過「單元測試」或「整合測試」測試新寫的功能是否正確,以及確認是否有影響到現有功能 - 程式碼分析(source code analysis) - Static Application Security Testing (SAST) ### CI之目的 - 降低人為疏失風險。 - 減少人工手動的繁複程序。 - 可隨時產生一版可部署的版本。 - 增加系統透明度。 ## 何謂CD CD(Continuous Deployment),即是「持續佈署」 透過自動化方式,將寫好的程式碼更新到機器上並公開對外服務,另外需要確保套件版本&資料庫資料完整性,也會透過監控系統進行服務存活檢查,若服務異常時會即時發送通知告至開發人員。 ## gitlab CI/CD 基礎流程 ![](https://about.gitlab.com/images/blogimages/cicd_pipeline_infograph.png) 圖片為官方提供架構圖 ### CI pipeline - BUILD - UNIT TEST - INTEGRATION TEST ### CD pipeline - REVIEW - STAGING - PRODUCTION 以上 關卡及工作皆由 ==.gitlab-ci.yml== 來定義 ### GitLab Server and GitLab CI Runner ![](https://about.gitlab.com/images/ci/ci-cd-architecture_2x.png) 上圖為官方所提供的 Runner Server 與 GitLab Server 的關係圖 ==.gitlab-ci.yml==定義完工作後,由==GitLab Server==建立工作並由==GitLab CI Runner==處理工作 GitLab Server可以對應多個Runner,Runner Server上可執行多個Runner 由於GitLab Server建立工作時,是由GitLab Runner來詢問有無工作,因此Runner需透過GitLab API連線至GitLab Server :::info 必須要注意,執行 Runner 的環境,必須可以讓 Runner 透過 GitLab API 網路連線到 GitLab Server 上 ::: ## 講解-安裝GitLab CI Runner 在進行CI/CD之前我們需先安裝GitLab CI Runner Gitlab CI Runner 可以在各種平台執行 如 Linux、Docker、macOS、Kubernetes(K8S)甚至是 Windows 等等。 以下範例為使用docker安裝 及在Liunx(Centos)上安裝 ### 使用docker安裝 $ docker run -d --name my-gitlab-runner --restart always \ -v ~/Shared/gitlab-runner/config:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest ### Liunx(Centos)上安裝 #### 下載gitlab runner 不同系統下載檔案不同 [下載位置](https://gitlab-runner-downloads.s3.amazonaws.com/latest/index.html) curl -LJO "https://gitlab-runner-downloads.s3.amazonaws.com/latest/rpm/gitlab-runner_amd64.rpm" 透過proxy 安裝 curl -x http://XXXX:3128 -LJO "https://gitlab-runner-downloads.s3.amazonaws.com/latest/rpm/gitlab-runner_amd64.rpm" #### 安裝git runner sudo rpm -i gitlab-runner_<arch>.rpm ### 註冊gitlab runner 官方文件 https://docs.gitlab.com/runner/register/ 註冊指令(docker) docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register 註冊指令(liunx) sudo gitlab-runner register 須設定基本資訊及選擇executor - Enter your GitLab instance URL: 輸入gitlab網址 https://glab01.ascc.sinica.edu.tw/ - Enter the => registration token: 輸入註冊token => Cxh4djgW4rvDHzBSegzv 進入專案gitlab 點選左方選單Setting中的CI/CD 點擊Runners 右方Expand按鈕,圖如下 ![](https://hackmd.io/_uploads/BJyP6E382.png) - Enter a description for the runner: 會顯示於 runner 列表,相當於 friendly name => 226_12_shell_test - Enter tags for the runner: tag很重要,之後CI/CD可以使用tag來指定runner => 226_12_shell_test - Enter optional maintenance note for the runner: Enter即可 - Enter an executor: executor的選擇可以參考下方網址,本範例使用Shell [GitLab CI 之 Runner 的 Executor 該如何選擇?](https://chengweichen.com/2021/03/gitlab-ci-executor.html?fbclid=IwAR3t5XHXNI2CEfhWLIMNb_NkrO6UKXH5vrVxWy91SJfFSP5ZVPwlrrEDSMQ) - Enter the default Docker image 若executor選擇docker則會多這個選項,需輸入預設的image(yml檔未指定時使用) 執行結果 ![](https://i.imgur.com/ygMGIqG.png) 執行成功後如下圖 ![](https://i.imgur.com/BjWx2f2.png) ## 講解-.gitlab-ci.yml 安裝完gitlab runner之後 我們就可以來開始撰寫.gitlab-ci.yml ### 官方流程範例 撰寫.gitlab-ci.yml之前 我們要先定義我們有哪些階段 那些工作 以下方官方提供的流程圖為範例 ![](https://docs.gitlab.com/ee/ci/introduction/img/gitlab_workflow_example_extended_v12_3.png) 圖中共有三個階段(Verify、Package、Release),各階段裡面又有不同工作 - Verify - Code Quality - Performance testing - JUnit tests - ... - Package - Container Registry - NPM Registry - ... - Release - Auto Deploy - ... :::info - 整個流水線稱pipeline,而一個pipeline裡面會有N的stage(階段) - 一個stage(階段)可以有N個Job(工作),每個工作可以在獨立的 container 執行 - 同 pipeline 下,stage 有先後順序;同 stage 下的 job,可以平行執行 ::: ### 定義自己的簡易pipeline 由於公司環境我們在上板以前就需打包成完整狀態,因此我們不需要Package階段 Verify階段我們保留測試的部分(改由PHP 單元測試),而Release我們則是保留自動部屬的部分 - Verify - PHP UnitTest - Release - Auto Deploy ### 撰寫.gitlab-ci.yml 依據上方自訂義的流程來撰寫.gitlab-ci.yml stages: - Verify - Release PHP_UnitTest: stage: Verify script: - echo 'hello PHP_UnitTest' Auto_Deploy: stage: Release script: - echo 'hello Auto_Deploy' 講解: - 定義有哪寫stages(1行-3行) - 工作名稱(PHP_UnitTest、Auto_Deploy部分) - 各工作屬於哪個stage及定義工作內容(script) 工作內容依照不同專案會有不同的執行工作 範例則用echo取代 ### 運行.gitlab-ci.yml ![](https://i0.wp.com/cdn-images-1.medium.com/max/1600/0*lkeuA35sqFus7M96.png?w=1080&ssl=1) 只要將.gitlab-ci.yml檔案加入git之後 每一次的commit push 都會依照yml之內容來執行CI/CD流程 點選專案左方選單CI/CD中的pipelines 即可看到執行結果(如下圖) ![](https://i.imgur.com/yziWeQK.png) 點擊各pipeline可以看此pipeline執行的stage及job ![](https://i.imgur.com/XwHTIvm.png) 點擊各job可以看到每個job的執行內容 - PHP_UnitTest ![](https://i.imgur.com/wEcbg0s.png) - Auto_Deploy ![](https://i.imgur.com/2x60U2q.png) ### 檢查gitlab-ci.yml 語法 gitlab有提供檢查gitlab-ci.yml語法之工具 點選專案左方CI/CD中的Pipelines ![](https://i.imgur.com/sdSu1AH.png) 點擊右方CI lint按鈕,則會進入檢查畫面 輸入剛剛的gitlab-ci.yml,點擊下方Validate即可知道語法有無錯誤 ![](https://i.imgur.com/Dg6Bxy2.png) ## 常見問題 ### 若執行pipeline時發現一直處於pending中 出現以下錯誤訊息 ![](https://i.imgur.com/qYNrwjN.png) ![](https://i.imgur.com/vvdAmuR.png) 可能是工作找不到適合的runner執行 需檢查專案中是否有註冊gitlab-ci runner 點選專案左方選單Setting中的CI/CD 展開runner區塊 查看下方Available specific runners ![](https://i.imgur.com/h3eiqn0.png) 若已有成功註冊runner的 但是還是出現錯誤訊息 則有可能runner有使用tags 但job沒有 #### 解決方式一 點選專案左方選單Setting中的CI/CD 展開runner區塊 點下方Available specific runners 任意runner編輯按鈕 ![](https://i.imgur.com/nyu18tg.png) 勾選Run untagged jobs 並按下Save change按鈕存檔 ![](https://i.imgur.com/MWjRfmg.png) 此runner及可以執行沒有tag之工作 #### 解決方式二 修改.gitlab-ci.yml檔案 在job加入runner tags 來指定此工作有哪個runner執行 範例如下 stages: - Verify - Release PHP_UnitTest: stage: Verify tags: - 226_12_shell_test script: - echo 'hello PHP_UnitTest2' Auto_Deploy: stage: Release tags: - 226_12_shell_test script: - echo 'hello Auto_Deploy'