Community寫作與編輯github.com

GitLab 工作流程技能

使用 `glab` CLI 管理 GitLab 合併請求、議題及 Git 最佳實務。

GitLab 工作流程技能 是什麼?

此技能提供使用 `glab` CLI 進行 GitLab 工作流程管理的詳細指南,涵蓋合併請求建立與更新、議題管理、工作項目處理、程式碼審查、問題連結、史詩 (Epics)、巢狀群組操作、搜尋以及 Git 提交規範。它特別強調避免常見的 Shell 陷阱,例如在 `-m` 參數中內嵌反引號或 `$` 符號可能導致的指令替換錯誤,並提供安全的替代方案(如使用 heredoc 寫入檔案後再以 `$(cat ...)` 讀取)。技能支援多個 GitLab 實例(透過 `remote_alias` 或 `GITLAB_HOST` 設定),並指出 `glab` 與 `gh` 在旗標名稱上的差異(如 `--description` 而非 `--body`)、工作項目需使用 Issues API、史詩評論需使用 GraphQL,以及嵌套群組 URL 需使用 `%2F` 編碼等關鍵細節。此技能適用於 Claude Code、Cursor 等 AI 代理,旨在減少試錯,提升開發者在 GitLab 上的操作效率。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add BINGWU2003/skills

Installed? Explore more 寫作與編輯 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

GitLab 工作流程技能 是做什麼的?

使用 glab CLI 管理 GitLab 合併請求、議題,並遵循 Git 最佳實務。

多個 GitLab 實例

glab 會從你的 git remote 自動偵測 GitLab 主機。當你在儲存庫內工作時,不需要設定 GITLAB_HOST。對於非 origin 的 remote(例如作為次要 remote 新增的本機 GDK 實例),請使用 glab config set remote_alias <remote>。僅在 Git 儲存庫外部執行指令,或針對特定實例執行一次性指令時,才設定 GITLAB_HOST。關於非 origin remote 的設定以及從 remote URL 推斷主機名稱的詳細資訊,請參閱 references/multi-host.md。

⚠️ 訊息跳脫——常見陷阱

如果你的訊息包含反引號 (`)、$ 或其他 Shell 特殊字元,千萬不要直接將它們內嵌在 -m "..." 中。 Shell 會將反引號解讀為指令替換,默默地破壞你的訊息,並產生類似 /bin/bash: line 1: client_name: command not found 的錯誤。

這已經導致過真實的生產事故:代理程式在 GitLab MR/Issue 上發布了格式錯誤的評論,緊接著又發送道歉修正的訊息。

❌ 不要這樣做——在雙引號的 -m 中內嵌反引號

# 錯誤:Shell 嘗試將 `client_name` 作為指令執行
glab mr note 100 -m "Use `client_name` and `wor/` here." -R org/repo
# 錯誤訊息:/bin/bash: line 1: client_name: command not found
# 評論被發布為:"Use  and  here."(識別符號被無聲地移除)

# 同樣錯誤:在巢狀/腳本環境中,反斜線跳脫的反引號會失效
glab mr note 100 -m "Use \`client_name\`" -R org/repo
# 在簡單情況下可行,但當指令被呼叫者用雙引號括起來時則會失敗:
# bash -c "glab mr note 100 -m \"Use \`client_name\`\"" → 仍然會執行 client_name

✅ 正確做法——先寫入檔案,再透過 $(cat ...) 傳遞

為你的環境選擇一個合適的路徑(mktemp 的結果、限定了作用範圍的工作區暫存檔,任何適合的方式都可以——這個技能不會指定特定路徑;代理程式應選擇一個在其調用中是唯一的路徑,以避免與平行執行衝突):

# MSG = 你選擇的路徑(例如 mktemp、~/workspace/tmp/note-$$.md 等)
MSG=<代理程式選擇>

cat > "$MSG" << 'EOF'
Use `client_name` and `wor/` here. The `glab` tool handles this.
EOF
glab mr note 100 -m "$(cat "$MSG")" -R org/repo

使用單引號括起來的 'EOF' heredoc 分隔符,可以在寫入檔案時防止所有變數/反引號擴展。由於檔案內容已經是逐字寫入的,因此 $(cat "$MSG") 替換是安全的。在 <<'EOF' heredoc 內部使用三重反引號程式碼區塊 (```) 也是安全的——無需跳脫;只有單一反引號和 $ 會觸發指令替換。

✅ 同樣安全——使用 -f 旗標的 glab api

glab api --method POST "projects/org%2Frepo/merge_requests/100/notes" \
  -f "body=$(cat "$MSG")"

⚠️ 未引號的 heredoc 仍會解譯反引號

# 錯誤:EOF 分隔符未引號——主體中的反引號仍會被解譯
cat > "$MSG" << EOF
Use `client_name` here.    # ← 寫入檔案時,Shell 會執行 client_name
EOF

⚠️ Heredoc 內嵌 Heredoc 會破壞 Shell 解析

如果你的內容本身包含一個帶有未縮排的 EOF 終止符的 heredoc 範例,那麼位於第 0 欄位的內部 EOF 會提前關閉外層的 heredoc:

# 錯誤:內部的 EOF 位於第 0 欄位——它會提前關閉外層的 HEREDOC
cat > "$OUTER" << 'EOF'
Here is the safe pattern:
cat > "$MSG" << 'EOF'
Use `client_name` here.
EOF
# ↑ 這個 EOF 終止了外層的 heredoc——下面的行會作為 Shell 指令執行!
echo "more content..."
EOF
# ↑ 這個多餘的 EOF 會變成一個指令:"EOF: command not found"

修復方式——為外層 heredoc 使用不同的分隔符:

cat > "$OUTER" << 'OUTEREOF'
Here is the safe pattern:
  cat > "$MSG" << 'EOF'
  Use `client_name` here.
  EOF
OUTEREOF

或者分塊寫入檔案——第一塊使用 >,後續塊使用 >>,每個塊使用自己的分隔符。

經驗法則: 如果訊息包含 `, $, !, 或 \——總是先使用 << 'EOF' 寫入檔案。如果內容本身包含 heredoc 語法,請使用一個不會在主體中出現的唯一外層分隔符(例如 OUTEREOF, MSGEOF)。

建立合併請求

總是傳遞 --push 和 -H <owner/repo>。沒有 --push,分支可能尚未存在於任何 remote。沒有 -H,glab 可能會選錯 remote(例如安全性鏡像)作為來源專案,從而從錯誤的 fork 建立 MR。

第二個同家族的 remote? 在一個同時有 origin (gitlab-org/gitlab) 和 security 鏡像 (gitlab-org/security/gitlab) 的檢出 (checkout) 中,以非互動模式執行 glab mr create(無 TTY,代理程式就是這樣運行的)會默默地選擇 security fork 作為來源,並因 400 {source_branch: [does not exist]} 而失敗。持久修復方式,每個檢出設定一次:git config remote.origin.glab-resolved-head head。對於新檢出的每次指令備用方案:傳遞 -H <owner/repo>(例如 -H gitlab-org/gitlab)。-R 無法修復這個問題——它只固定了基礎儲存庫,而不是來源。

# 簡單 MR
glab mr create --push -H <owner/repo> --title "Add feature" --description "Brief description" --assignee <username>

# 複雜 MR - 先將描述寫入檔案(自己選擇路徑)
glab mr create --push -H <owner/repo> --title "Add feature" --description "$(cat "$DESC")" --assignee <username>

範本: 檢查 .gitlab/merge_request_templates/ 目錄以找尋專案特定的範本。

完整旗標列表(Claude Code 會自動注入;其他代理程式應自行執行):

!glab mr create --help

更新合併請求

glab mr update <number> --description "$(cat "$DESC")"
glab mr view <number> -R <owner>/<repo>

議題管理

完整且最新的旗標列表(Claude Code 會自動注入;其他代理程式應自行執行):

!glab issue --help

view, note, list, create, update 這些指令如預期般運作。--help 不會警告你的非顯而易見的陷阱:

# List 預設為開啟,且沒有 --state 旗標——改用 --closed / --all
glab issue list --closed -R <owner>/<repo>
glab issue list --all    -R <owner>/<repo>

# 標籤——使用 --label / --unlabel,絕不使用 +label 或 -label 語法
glab issue update 123 --label "new-label"
glab issue update 123 --unlabel "old-label"
# 範圍標籤會在其範圍內自動替換——不需要 --unlabel:
glab issue update 123 --label "status::doing"   # 移除任何現有的 status:: 標籤

# 包含反引號/$ 的訊息——先寫入檔案(參閱上方的訊息跳脫章節)
glab issue note <number> -m "$(cat "$MSG")" -R <owner>/<repo>

關於議題狀態轉換(透過 API 關閉/重新開啟)以及透過 glab api 發布評論:references/issue-api.md

工作項目

GitLab 正在將議題遷移到工作項目。URL 顯示 /work_items/<iid>,但 REST API 是相同的。

# ✅ 使用 issues API——相同的 IID,相同的端點
glab api "projects/org%2Fproject/issues/<iid>"

# ❌ /work_items/ REST 端點不存在
glab api "projects/org%2Fproject/work_items/<iid>"   # → 404

URL 解析:https://gitlab.com/org/project/-/work_items/539076 → glab api "projects/org%2Fproject/issues/539076"

完整詳細資訊、GraphQL 替代方案、群組層級工作項目以及代理計劃 (Workplan) 小工具:references/work-items.md

MR 審查

從 glab v1.94.0 開始,glab mr note 可以處理所有常見的 MR 評論形式(列表、一般、差異行、回覆、解決/重新開啟),而無需使用原始 glab api 呼叫或手動建構 position 物件。對於任何單一評論的工作流程,優先使用它。MR IID 是位置引數(不是 --mr);省略它以從當前分支自動偵測。

# ✅ 使用 glab mr note 處理讀/寫/回覆/解決——每個操作一個指令
glab mr note list 123 -F json                                       # 讀取討論
glab mr note create 123 -m "comment"                                # 一般評論
glab mr note create 123 --file main.go --line 42 -m "..."           # 差異行評論
glab mr note create 123 --reply abc12345 -m "..."                   # 回覆
glab mr note resolve 123 abc12345                                   # 解決討論串

# ❌ 不要對上述操作使用 glab api .../discussions
glab api "projects/<id>/merge_requests/123/discussions"             # 改用 mr note list
glab api --method PUT ".../discussions/<id>" -f resolved=true       # 改用 mr note resolve

上述子指令的完整旗標列表(Claude Code 會自動注入;其他代理程式應自行執行):

!glab mr note --help

僅在需要批次草稿審查(透過 bulk_publish 同時發布多個內嵌評論)時,才退回到使用原始 glab api .../draft_notes——glab mr note 沒有草稿模式。

完整參考資料(所有旗標、程式碼建議、草稿/批次備用方案、position 物件):references/mr-review.md

議題連結、史詩與巢狀群組

MR 列表與過濾

完整旗標列表(Claude Code 會自動注入;其他代理程式應自行執行):

!glab mr list --help

注意: glab mr list 預設列出開啟的 MR,且沒有 --state 或 --status 旗標——改用 --all、--merged 或 --closed 來變更狀態過濾器。

搜尋

完整的搜尋範例(實例 / 群組 / 專案、範圍表、分頁):references/search.md

快速參考:

glab api "search?scope=issues&search=<query>" | jq '.[] | {iid, title}'
glab api "groups/<group>/search?scope=merge_requests&search=<query>" | jq '.[]'
glab api "projects/<org>%2F<repo>/search?scope=issues&search=<query>" | jq '.[]'

Git 與提交規範

當存在時,請遵循儲存庫自身的 git 規範(專案可能會記錄規範並透過提交檢查工具執行)。GitLab 預設值:

git checkout -b feature/description   # 功能分支
git checkout -b fix/description       # 錯誤修復分支
  • 使用大寫開頭的祈使句作為提交標題(例如 "Add feature",而非 "Added feature" 或 "feat: add feature");GitLab 不使用 conventional-commit 規範。
  • 使用完整 URL 引用議題/MR:Closes https://gitlab.com/org/project/-/issues/123。
  • 對包含特殊字元的提交訊息使用單引號: git commit -m 'Add note from https://gitlab.com/org/project/-/merge_requests/123'。

代理指南

以上章節涵蓋了常見的工作流程。以下是不易從 glab <cmd> --help 發現的非顯而易見的陷阱和 API 特性:

  1. 先讀取上下文 — 在實作前先執行 glab issue view / glab mr view;檢查 .gitlab/issue_templates/ 和 .gitlab/merge_request_templates/ 目錄中的範本
  2. --jq 僅作用於子指令,不作用於 glab api — glab issue list/glab mr list/glab ci list 接受一個全域 --jq 旗標(過濾 JSON 輸出);glab api 不支援——改將其輸出透過管道傳給 | jq '...'
  3. 沒有 --body 旗標 — glab 使用 --description,而不是 --body(後者是 gh 的旗標);它們不可互換
  4. 工作項目使用 issues API — /work_items/<iid> URLs → projects/.../issues/<iid>;/work_items/ REST 端點會回傳 404
  5. 史詩評論需要 GraphQL — REST /notes 的 GET 和 POST 都會回傳 404(即使在 GitLab 19.1 上也是如此);將 body/noteableId 作為 GraphQL 變數傳遞,絕不要使用字串插值。請參閱 references/epic-comments.md
  6. 群組層級 API 不要使用 -R — -R 需要 OWNER/REPO 格式;群組端點應直接使用 glab api "groups/..."
  7. 巢狀群組 REST:使用 %2F — groups/org%2Fsubgroup/epics;未編碼的斜線會導致 404
  8. GraphQL iid 是字串 — workItem(iid: "16428") 而非 workItem(iid: 16428)
  9. groups/<id>/work_items 會回傳 404 — 使用 groups/<id>/epics(REST)或 GraphQL
  10. project 公開的是 workItems(複數),而非 workItem — 在 project 下使用 workItems(first: 1, iid: "IID"),不要加上 filter: 參數;單數的 workItem(iid:) 欄位僅存在於 group/namespace 下
  11. 透過 REST 關閉/重新開啟史詩 — 在 PUT groups/<id>/epics/<iid> 上使用 state_event=close/reopen 即可;不需要 GraphQL
  12. 範圍標籤會自動替換 — --label "status::doing" 會移除任何現有的 status::* 標籤;不需要 --unlabel(這是一個平台事實,通常透過 API 都是如此,不僅限於 glab)
  13. 冪等評論 → 使用 --unique — glab mr note create -m "..." --unique 若已存在相同的內文則跳過發布;僅比對內文,因此不同差異行上的相同內文仍會發布
  14. 非 origin remote → 使用 remote_alias — 如果 origin 指向一個實例,但你希望 glab 以另一個 remote 為目標(例如以 gdk 名稱新增的本機 GDK),請執行 glab config set remote_alias gdk,而不是每次都設定 GITLAB_HOST。請參閱 references/multi-host.md
  15. 訊息中的反引號 → 先寫入檔案 — 絕不要將 `/$ 內嵌在 -m "..." 或 --description "..." 中;使用 << 'EOF'(單引號括起來的分隔符,至關重要)寫入一個你自訂名稱的檔案(每個調用是唯一的),然後透過 $(cat "$FILE") 傳遞。請參閱上方的訊息跳脫章節。
  16. 第二個同家族 remote 會使 mr create 誤判來源 — 當存在 security 鏡像以及 origin 時,非互動式 mr create(無 TTY)會默默地選擇該 fork 作為來源。一次性的修復方式:git config remote.origin.glab-resolved-head head;每次指令的備用方案:-H <owner/repo>(-R 無法修復)。請參閱「建立合併請求」章節。
  17. glab api 評論內文: 檔案 → -F "body=@file"

…

[已截斷以利翻譯]

相關技能