昨天我們從架構的角度理解了 GitLab CI/CD 的運作方式,掌握了 pipeline、Runner 與 stage、job 的基本概念。今天要進一步聚焦在 .gitlab-ci.yml
的撰寫。
一份設定檔大致可以拆解為五個主要區塊,從共用邏輯、全域參數,到流程骨架、觸發條件與實際任務,它們共同構成了整個 pipeline 的框架。
下面先用一張圖來快速勾勒這五大區塊的樣貌,再逐一解析其用途與設計要點。
+----------------+
| default |
| (templates / & )|
+----------------+
│
▼
+----------------+
| variables |
| (全域 / secret) |
+----------------+
│
▼
+----------------+
| stages |
| (順序 / 名稱) |
+----------------+
│
▼
+----------------+
| workflow |
| (何時啟動) |
+----------------+
│
▼
+----------------+
| jobs |
| (job 定義) |
+----------------+
default (共用模板 / anchor)
│
├─> variables (注入點:環境 / secret)
│
├─> stages (骨架:build → test → deploy)
│
├─> workflow (集中控制何時啟動 pipeline)
│
└─> jobs (具體執行單位;可從 default / include 擴展)
之所以先提供圖示,是希望能建立起對 .gitlab-ci.yml
撰寫的共同認知。這樣一來,不僅能讓團隊內的新進成員更快上手,也能讓後續的維護者在面對修改需求時,更容易判斷該調整哪個區塊。
接下來,我會逐一介紹這五大區塊的功能,並提供最基礎的範例模板,幫助大家理解如何在實務中套用。
default
用途:定義整個 pipeline 的共用行為(image、script 前置命令、artifacts/when、retry、before_script/after_script 的預設值等)。
特色實務點:
.dot
命名配合 YAML anchor(&)來封裝一系列行為(良好寫法),再用 extends
或 YAML alias 取用。範例:
default:
image: python:3.11
before_script:
- pip install -r requirements.txt
interruptible: true
YAML anchor 的範例(用 &
定義,<<: *
合併):
.default-build: &default-build
image: node:20
before_script:
- npm ci
cache:
paths:
- node_modules/
build-job:
<<: *default-build
script:
- npm run build
或用 extends
(GitLab 支援):
.build-template:
image: node:20
before_script:
- npm ci
build:
extends: .build-template
script:
- npm run build
variables
用途:儲存 pipeline 會用到的全域變數(可被 job override)。
實務建議:
rules
、script
、when
判斷。variables:
DEPLOY_ENV: "staging"
TIMEOUT: "20m"
stages
用途:宣告 pipeline 的階段順序(必需預先列出),jobs 會宣告所屬 stage。
實務提示:
stages:
- build
- test
- deploy
workflow
用途:決定整個 pipeline 是否被觸發(例如:依 branch、MR、變更檔案路徑、pipeline schedules)。
實務要點:
workflow: rules:
來集中控制,減少 job 層級 rules:
。workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: always
- if: $CI_COMMIT_BRANCH == "main"
when: always
- when: never
jobs
用途:實際執行的單位(script、image、artifacts、rules、dependencies、needs 等)。
實務細節:
優先使用 rules
來替代 only/except
(更靈活)。
範例 job:
build:
stage: build
script:
- make build
artifacts:
paths:
- dist/
rules:
- if: $CI_COMMIT_BRANCH =~ /^(main|release)/
when: on_success
明白 👍 這段其實是補充在「五大區塊」之外的延伸功能。我幫你重新梳理語句,讓它更有層次感、讀起來順暢,並保留技術重點與官方參考連結:
除了上述五大區塊外,在實務撰寫中也經常會用到 include
與 !reference
這兩個功能。
include
幾乎可以用在任何地方。在官方範例中(GitLab 官方 .gitlab-ci.yml
),可以看到他們將各個 job 的階段與所需變數一起打包,最後以獨立的 YAML 檔案存放,並透過 include
引入。這種作法能把設定模組化,便於維護與重複使用。
!reference
則與 YAML merge (<<:
) 的用法相近。
extends
關鍵字達到類似效果。.gitlab-ci.yml
中,主要仍以 YAML merge (<<:
) 為主,!reference
相對較少見。以下提供範例介紹 include
與 !reference
。
include
假設團隊將 部署相關的設定 拆成一個獨立檔案 deploy.yml
:
.gitlab/ci/deploy.yml
deploy:
stage: deploy
script:
- ./scripts/deploy.sh
environment:
name: production
url: https://example.com
only:
- main
主檔 .gitlab-ci.yml
:僅需要incclude將其當作job區塊的實現,將需要的參數與執行細節打包。
# .gitlab-ci.yml
stages:
- build
- test
- deploy
include:
- local: '.gitlab/ci/build.yml'
- local: '.gitlab/ci/test.yml'
- local: '.gitlab/ci/deploy.yml'
另一種方式則是使用extend,我較不推薦,因為會顯得多此一舉,上面提供的範例同樣來自GitLab 官方 .gitlab-ci.yml
很顯然這樣的寫法有以下優點:
.gitlab-ci.yml
保持非常乾淨,僅負責「流程順序(stages)」與「include 清單」。include
。!reference
接下來介紹 !reference,範例是在多個 job 中共用一段 script:
.default-scripts:
script:
- echo "Install dependencies"
- npm ci
build:
stage: build
script:
- !reference [.default-scripts, script]
- npm run build
test:
stage: test
script:
- !reference [.default-scripts, script]
- npm test
👉 這裡 !reference
直接取用了 .default-scripts
裡的 script
區塊,讓其可以重複使用。
除了!reference 事實上在GitLab 官方 .gitlab-ci.yml
中,更多的是使用YAML merge(<<:
)。
大多數情況下,YAML merge(搭配 anchor &)可以達成相同效果:
.default: &default-scripts
script:
- echo "Install dependencies"
- npm ci
build:
<<: *default-scripts
stage: build
script:
- npm run build
test:
<<: *default-scripts
stage: test
script:
- npm test
GitLab 官方 repo 幾乎以 YAML merge(
<<:
)為主,因其語法直觀易懂;實際採用!reference
或 merge 的方式,則可依個人或團隊偏好決定。
明白了,我幫你用「檢視 → 收束 → 引導」的風格整理今天 .gitlab-ci.yml
的文章小結如下:
今天我們從 .gitlab-ci.yml 的結構與實務撰寫 出發,檢視了 pipeline 配置的五大核心區塊:
extends
減少重複設定。我們也延伸檢視了 模組化技巧:
透過範例,我們看到從 流程骨架、變數注入到 job 執行,每個元素如何協同運作,使 pipeline 既清晰又可維護。
接下來,我們將透過實際範例,示範如何有效管理參數,並分享在 CI/CD 流程中可應用的最佳實踐。
感謝各位閱讀,我們明天見!