學習目標
- 會用 GitLab 內建的
CI_*變數。 - 會定義全域變數與 job 變數,知道誰會覆寫誰。
- 知道密碼與權杖要放在專案設定,不能寫進 repo。
- 會用
artifacts:reports:dotenv把一個 job 算出的值交給下一個 job。
觀念:優先順序(高 → 低)
| 順序 | 來源 | 例子 |
|---|---|---|
| 1 | 手動執行或觸發時帶入的變數 | 「Run pipeline」表單 |
| 2 | 專案/群組設定的變數 | Settings → CI/CD → Variables |
| 3 | dotenv 報告傳進來的變數 | 本關的 BUILD_VERSION |
| 4 | job 裡的 variables | custom 的 GREETING: 午安 |
| 5 | 全域 variables | GREETING: 早安 |
| 6 | 內建變數 | CI_COMMIT_SHORT_SHA |
常用內建變數
| 變數 | 內容 |
|---|---|
CI_COMMIT_SHORT_SHA | commit 前 8 碼,常拿來當映像標籤(Lv.10 就是這樣) |
CI_COMMIT_REF_NAME/CI_COMMIT_REF_SLUG | 分支或標籤名稱;slug 是轉成可當網址或資源名稱的版本 |
CI_COMMIT_BRANCH | 分支名稱;標籤 pipeline 沒有這個變數 |
CI_DEFAULT_BRANCH | 預設分支,通常是 main |
CI_PIPELINE_SOURCE | push、web、schedule、merge_request_event、parent_pipeline…… |
CI_PIPELINE_IID | 專案內的 pipeline 流水號 |
機密要怎麼放
- 「Settings → CI/CD → Variables」新增變數。
- 勾 Masked:紀錄裡會顯示成
[MASKED]。 - 勾 Protected:只有受保護分支(例如
main)拿得到,從分支或 MR 偷印出來也拿不到。 - 憑證檔用 File 類型,變數內容會是一個暫存檔的路徑。
不要用 echo $TOKEN 測試機密有沒有設好,改用 test -n "$TOKEN"。
動手做
- 在「Build → Pipelines → Run pipeline」看到
GREETING與DEPLOY_TARGET兩個欄位,改值後執行。 - 在專案設定新增
TUTORIAL_GREETING(一般變數,不是機密),重跑後custom會印出它。 - 看
use-version的紀錄,版本號是make-version算出來的。
常見錯誤
- 在
variables裡用$(date):不會執行,只會當成字串。要算的值請在script裡算,再用 dotenv 傳。 - 變數值是
yes、on、08:YAML 可能誤判型別,加上引號最保險。
下一關
Lv.5 用 cache 讓安裝套件不用每次重新下載。
範例檔案
資料夾 lv04-variables/ 的全部檔案。.gitlab-ci.yml 可以直接複製到自己的專案根目錄執行。
lv04-variables/.gitlab-ci.yml
lv04-variables/.gitlab-ci.yml
# Lv.4 Variables:內建變數、自訂變數、覆寫順序,以及在 job 之間傳值(dotenv)
# 密碼、權杖不要寫在這裡:一律放「Settings → CI/CD → Variables」,並勾選 Masked、Protected。
stages:
- info
- build
- use
default:
image: alpine:3.22
# 全域變數:每個 job 都拿得到
variables:
COURSE_NAME: "GitLab CI/CD 十關"
LESSON: "Lv.4"
FULL_TITLE: "$COURSE_NAME - $LESSON" # 變數可以引用其他變數
# 有 description 的全域變數,會出現在「手動執行 pipeline」的表單裡
GREETING:
value: "早安"
description: "手動執行 pipeline 時可以改成別的招呼語"
DEPLOY_TARGET:
value: "staging"
options: ["staging", "production"]
description: "手動執行時只能從這兩個選一個"
predefined:
stage: info
script:
- echo "專案:$CI_PROJECT_PATH"
- echo "分支:$CI_COMMIT_REF_NAME(slug:$CI_COMMIT_REF_SLUG)"
- echo "commit:$CI_COMMIT_SHORT_SHA"
- echo "觸發來源:$CI_PIPELINE_SOURCE"
- echo "預設分支:$CI_DEFAULT_BRANCH"
- echo "job 編號:$CI_JOB_ID"
custom:
stage: info
# job 變數會覆寫同名的全域變數
variables:
GREETING: "午安"
script:
- echo "$FULL_TITLE"
- echo "招呼語:$GREETING(job 覆寫了全域的「早安」)"
- echo "部署目標:$DEPLOY_TARGET"
# 專案變數在「Settings → CI/CD → Variables」設定;沒設時用預設值
- echo "專案變數:${TUTORIAL_GREETING:-尚未設定 TUTORIAL_GREETING}"
make-version:
stage: build
script:
- echo "BUILD_VERSION=1.4.$CI_PIPELINE_IID" > build.env
- echo "BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> build.env
- cat build.env
artifacts:
reports:
dotenv: build.env # 後面的 job 會自動拿到這兩個變數
use-version:
stage: use
needs: [make-version]
script:
- test -n "$BUILD_VERSION"
- echo "上一個 job 算出的版本:$BUILD_VERSION,時間:$BUILD_TIME"