學習目標
- 用
stages決定執行順序。 - 知道同一個 stage 的 job 會平行執行。
- 會用
default、before_script、after_script、allow_failure、when: always。
觀念
.pre build test deploy .post
prepare → build-app → test-unit → deploy-demo → cleanup
test-lint
test-experimental(允許失敗)- 前一個 stage 的 job 全部成功,下一個 stage 才開始。
.pre、.post是內建階段,不用寫在stages裡。default是所有 job 的共用設定;job 自己寫了同一個鍵就以 job 為準。
範例解說
| 設定 | 用途 |
|---|---|
before_script | 每個 job 在 script 前先跑,適合印資訊、裝工具 |
after_script | script 成功或失敗都會跑,適合清理。它是另一個 shell,變數不會延續 |
allow_failure: { exit_codes: [42] } | 只有結束碼 42 當成警告(黃色驚嘆號),pipeline 仍然通過 |
when: always | 前面失敗也照跑 |
timeout | 單一 job 的執行上限 |
interruptible: true | 有新 commit 時可以取消舊的 job |
allow_failure: true 會放過所有失敗,容易把真的問題藏起來;能指定結束碼就指定結束碼。
動手做
- push 後看 pipeline 圖:
test欄有三個 job 同時跑。 - 把
test-experimental的exit 42改成exit 1,pipeline 會失敗、deploy-demo不會執行,但cleanup仍然會跑。 - 在
stages裡把test移到build前面,觀察順序改變。
常見錯誤
- job 寫了
stage: tests,但stages裡是test:pipeline 會直接報錯。 - 以為
after_script失敗會讓 job 失敗:不會,它的失敗只會出現在紀錄裡。
下一關
Lv.3 讓 job 之間傳遞檔案:artifacts。
範例檔案
資料夾 lv02-stages-jobs/ 的全部檔案。.gitlab-ci.yml 可以直接複製到自己的專案根目錄執行。
lv02-stages-jobs/.gitlab-ci.yml
lv02-stages-jobs/.gitlab-ci.yml
# Lv.2 Stages 與 Jobs
# 同一個 stage 的 job 平行執行;前一個 stage 全部成功,下一個 stage 才開始。
# .pre 與 .post 是內建階段,一定排在最前與最後,不用寫進 stages。
stages:
- build
- test
- deploy
# default:所有 job 共用的設定,job 自己有寫就以 job 為準
default:
image: alpine:3.22
before_script:
- echo "[$CI_JOB_STAGE] $CI_JOB_NAME 開始"
# 推了新 commit 時,舊 pipeline 裡還沒跑完的 job 可以被取消,省 runner 時間
interruptible: true
prepare:
stage: .pre
script:
- echo "檢查工具版本"
- sh --help 2>&1 | head -1
build-app:
stage: build
timeout: 5 minutes
script:
- echo "編譯中……"
- sleep 3
- echo "編譯完成"
test-unit:
stage: test
script:
- echo "單元測試:3 項通過"
test-lint:
stage: test
script:
- echo "風格檢查:沒有問題"
# 允許失敗:只有結束碼 42 會被當成「警告」,其他結束碼一樣算失敗
test-experimental:
stage: test
allow_failure:
exit_codes: [42]
script:
- echo "實驗中的測試,失敗不擋 pipeline"
- exit 42
deploy-demo:
stage: deploy
script:
- echo "部署到示範環境(Lv.9 會用 environment 正式做)"
# after_script 不論 script 成功或失敗都會跑,適合清理
after_script:
- echo "清理暫存檔"
cleanup:
stage: .post
# when: always:前面就算失敗也會跑
when: always
script:
- echo "pipeline 結束,狀態彙整完成"