昨天我們將 GitLab Runner 架設好了,今天要來試行昨天規劃好的 CI/CD Pipeline。
GitLab CI 預設會檢查 Project 內是否含有名為 .gitlab-ci.yml
的檔案,並根據該檔案所定義的內容自動建立 CI/CD Pipeline。因此如果要建立昨天規劃的 dev 與 stg 這兩條 Pipeline,我們可以按以下的步驟撰寫 .gitlab-ci.yml
。
首先要宣告 Pipeline 有哪些 stages
,並排定他們的先後順序。
stages:
- build
- deploy
- test
接著描述每一個 stage
裡面有哪些 job
。下面以 dev 的 Pipeline 為例,先為 build
這個 stage
設置 job
。
# 首先宣告 job 的名稱
dev-build:
# 宣告此 job 屬於哪一個 stage
stage: build
# 限制只有 develop branch 會執行此 job
only:
- develop
# 最後是此 job 要執行哪些動作
script:
- echo "dev build"
按同樣的概念,整個 dev 的 Pipeline 會類似如下:
stages:
- build
- deploy
- test
dev-build:
stage: build
only:
- develop
script:
- echo "dev build"
dev-deploy:
stage: deploy
only:
- develop
script:
- echo "dev deploy"
dev-test:
stage: test
only:
- develop
script:
- echo "dev testing"
接著再用同樣的概念,設置 stg 的 Pipeline,於是整份 .gitlab-ci.yml
就會變成下面的模樣。
stages:
- build
- deploy
- test
dev-build:
stage: build
only:
- develop
script:
- echo "dev build"
dev-deploy:
stage: deploy
only:
- develop
script:
- echo "dev deploy"
dev-test:
stage: test
only:
- develop
script:
- echo "dev testing"
stg-build:
stage: build
only:
- master
script:
- echo "stg build"
stg-deploy:
stage: deploy
only:
- master
script:
- echo "stg deploy"
stg-test:
stage: test
only:
- master
script:
- echo "stg testing"
是不是很簡單?只要一個檔案,就能產生兩條 CI/CD Pipeline。
(develop branch 的 CI Pipeline。)
(master branch 的 CI Pipeline。)
延續目前的案例,我們目前規劃的 Pipeline 只有三個 Stage、三個 Job,其實可以將 dev 與 stg 合併在一起,不用重複撰寫,只需要在 only:
中指定多個 branch 即可。
stages:
- build
- deploy
- test
build:
stage: build
only:
- develop
- master
script:
- echo "build"
deploy:
stage: deploy
only:
- develop
- master
script:
- echo "deploy"
test:
stage: test
only:
- develop
- master
script:
- echo "testing"
等到針對不同 branch 需要執行不同 Job 時,在做出區分即可。例如下面的範例,有可能你在 build
stage 需要針對 dev 與 stg 環境執行不同的 npm
指令。
build:
stage: build
only:
- develop
script:
- npm install
- npm run dev
build:
stage: build
only:
- master
script:
- npm install
- npm run producton
回到我們的案例。最後再加上 Production 的 Pipeline,整份 .gitlab-ci.yml
就變成下面的面貌。
stages:
- build
- deploy
- test
- prod-deploy
build-for-testing:
stage: build
only:
- develop
- master
script:
- echo "build for testing"
prod-build:
stage: build
only:
- production
script:
- echo "build for production"
deploy-for-testing:
stage: deploy
only:
- develop
- master
- production
script:
- echo "deploy for testing"
testing:
stage: test
only:
- develop
- master
- production
script:
- echo "auto testing"
prod-deploy:
stage: prod-deploy
only:
- production
script:
- echo "deploy to production server"
when: manual
最後的 .gitlab-ci.yml
有再多做了一些調整。我們假設的情境是 dev、stg 兩種環境與 prod 環境要執行的 build 指令不同。另外就是 production branch 會需要先部署至 pre-production 環境,等到通過測試之後,才由主管在指定的時間手動觸發自動部署。
因此上面將 build 的 Job 分為 build-for-testing
與 prod-build
兩種。同時第一個 deploy 改名為 deploy-for-testing
,而部署至 Production 環境的 Job 則命名為 prod-deploy
,並且增加了 when: manual
即是需要手動觸發。
不過實際將上面的 .gitlab-ci.yml
送進 GitLab 之後,卻發現 Pipeline 出現 stuck
的狀態。
(自以為規畫完美的 Pipeline,卻根本 stuck
卡住了,CI Job 沒有被執行。)
通常 Pipeline 會出現 stuck
,主要的原因都是代表當下沒有吻合該 Pipeline 需求的 GitLab Runner。於是我們查看一下昨天架設好的 Runner,Runner 被標上的 tag
為 shell
。因此我們再次修改 .gitlab-ci.yml
,為每一個 Job 加上如下範例的 tags:
。
build-for-testing:
stage: build
tags:
- "shell"
only:
- develop
- master
script:
- echo "build for testing"
(至 Group 的 Settings > CI/CD > Runners
去查看 Runner 的詳細資料,除了 Tags
之外,亦能查看 Runner 的其他資訊。)
本文最後版本的 .gitlab-ci.yml
在 master branch 會形成如下的 CI Pipeline。
(可以看見 Job 都如前述修改的,是 xxx-for-testing
。)
而最後 Production branch 則會形成下圖的 CI Pipeline,其中最後一個 Prod-deploy 則需要有人按下「箭頭」才會執行動作。
(Production branch 的 CI Pipeline 也如規劃的一樣,有兩個不同的 deploy。)
雖然只是模擬情境,尚未在 script:
中撰寫真實可用的動作,但在今天的進度中,我們已經成功練習建立了第一條 CI/CD Pipeline。透過這樣的練習,相信各位已經能體會,只透過一個 yml 檔就能建立 Pipeline 的方便之處。
但 CI/CD Pipeline 真的就這麼簡單嗎?其實一點也不簡單!今天的練習不過是個起步而已,我們還沒碰觸到 CI/CD Pipeline 真正讓人感到辛苦與頭痛的地方,CI/CD 到底難在哪裡?辛苦在哪裡?就讓我們在後續的文章逐一揭曉。(但有太多辛苦的環節了,大概 30 篇文章都不夠講,我們就先根據案例走到哪,揭曉到哪了~)
自 2021 年 12 月 12 日開始,我就一直想要將原發佈在 iT 邦幫忙的鐵人賽系列文章搬移至 https://gitlab-book.tw 並補充說明文章內容已有過期之處。
因為當初參加 iThome 鐵人賽時,GitLab 仍在 12 版,但如今 GitLab 已更新好幾版了,需要提醒大家注意一下。
本文已完成搬遷