ワンクリックで
glab
GitLab workflow automation using glab CLI
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
GitLab workflow automation using glab CLI
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Write, refine, run, and QA promptfoo evaluation suites for Premortem: promptfooconfig.yaml, providers, vars, tests, assertions, and CI gates. Use for canonical prompt regression in @premortem/evals. Do not use for adversarial redteam plugin setup (see security/llm-security).
Use when the user wants to decide whether implementation is ready, what remains blocked, and what the exact next build step should be.
Use when the user wants the singular Meta-Architect in-session autonomous manager: choose the best next workflow step, manage the fixed gated workflow, and route bounded helper handoffs inside Codex.
Comprehensive Cloudflare platform skill covering Workers, Pages, storage (KV, D1, R2), AI (Workers AI, Vectorize, Agents SDK), feature flags (Flagship), networking (Tunnel, Spectrum), security (WAF, DDoS), and infrastructure-as-code (Terraform, Pulumi). Use for any Cloudflare development task. Biases towards retrieval from Cloudflare docs over pre-trained knowledge.
Automated Dynamic Application Security Testing (DAST) using Playwright MCP plus standard OS pentest tooling. Performs blackbox or greybox scans on single or multiple domains with orchestrated crawling, vulnerability detection, and structured output. Trigger on requests like "scan this domain", "run DAST on these URLs", "automated pentest", or "security-test the staging app".
Comprehensive Android mobile application penetration testing with rooted-device ADB and Frida-based MCP tooling. Covers OWASP MASTG full methodology: recon, static + dynamic analysis, SSL/root bypass, IPC fuzzing, data exfiltration, crypto audit, and reporting. Triggers on requests to pentest Android apps, analyze APKs, bypass mobile security controls, or run MASVS/MASTG assessments.
| name | glab |
| description | GitLab workflow automation using glab CLI |
| version | 1.10.0 |
| category | Development Workflow |
| license | MIT |
| metadata | {"audience":"developers","author":"dgruzd","workflow":"gitlab"} |
GitLab workflow management using glab CLI for merge requests, issues, and Git best practices.
glab auto-detects the GitLab host from your git remote. No GITLAB_HOST is needed when
working inside a repository. For non-origin remotes (e.g. a local GDK instance added
as a secondary remote), use glab config set remote_alias <remote>. Set GITLAB_HOST
only when running outside a git repository or for a one-off command targeting a specific
instance. See references/multi-host.md for non-origin remote
setup and hostname derivation from remote URLs.
If your message contains backticks (`), $, or other shell special characters, NEVER inline them directly in -m "...". The shell interprets backticks as command substitution, silently mangling your message and producing errors like /bin/bash: line 1: client_name: command not found.
This has caused real production failures: agents posting malformed comments to GitLab MRs/issues, followed by apologetic correction notes.
# BROKEN: shell tries to execute `client_name` as a command
glab mr note 100 -m "Use `client_name` and `wor/` here." -R org/repo
# Error: /bin/bash: line 1: client_name: command not found
# The comment is posted as: "Use and here." (identifiers silently stripped)
# Also BROKEN: backslash-escaped backticks break in nested/scripted contexts
glab mr note 100 -m "Use \`client_name\`" -R org/repo
# Works in simple cases but fails when the command is double-quoted by a caller:
# bash -c "glab mr note 100 -m \"Use \`client_name\`\"" → still executes client_name
Pick a path appropriate for your environment (a mktemp result, a scoped workspace tmp file, whatever fits — the skill doesn't prescribe a specific path; agents choose one that's unique to their invocation to avoid clobbering parallel runs):
# MSG = path you choose (e.g. mktemp, ~/workspace/tmp/note-$$.md, etc.)
MSG=<agent picks>
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
The single-quoted 'EOF' heredoc delimiter prevents ALL variable/backtick expansion when writing the file. The $(cat "$MSG") substitution is safe because the file content is already written literally. Triple-backtick code blocks (```) are also safe inside <<'EOF' heredocs — no escaping needed; only single-backticks and $ trigger command substitution.
glab api --method POST "projects/org%2Frepo/merge_requests/100/notes" \
-f "body=$(cat "$MSG")"
# BROKEN: unquoted EOF delimiter — backticks in body are still interpreted
cat > "$MSG" << EOF
Use `client_name` here. # ← shell executes client_name when writing the file
EOF
If your content itself contains a heredoc example with an unindented EOF terminator, the inner EOF at column 0 closes the outer heredoc early:
# BROKEN: the inner EOF is at column 0 — it closes the OUTER heredoc early
cat > "$OUTER" << 'EOF'
Here is the safe pattern:
cat > "$MSG" << 'EOF'
Use `client_name` here.
EOF
# ↑ This EOF terminates the OUTER heredoc — the lines below run as shell commands!
echo "more content..."
EOF
# ↑ This stray EOF becomes a command: "EOF: command not found"
Fix — use a different delimiter for the outer heredoc:
cat > "$OUTER" << 'OUTEREOF'
Here is the safe pattern:
cat > "$MSG" << 'EOF'
Use `client_name` here.
EOF
OUTEREOF
Or write the file in chunks — first chunk uses >, subsequent chunks use >>, each with its own delimiter.
Rule of thumb: If the message contains `, $, !, or \ — write to a file with << 'EOF' first, always. If the content itself contains heredoc syntax, use a unique outer delimiter (e.g. OUTEREOF, MSGEOF) that won't appear in the body.
Always pass --push and -H <owner/repo>. Without --push, the branch may not exist on
any remote yet. Without -H, glab may pick the wrong remote (e.g. a security mirror) as
the source project, creating the MR from the wrong fork.
# Simple MR
glab mr create --push -H <owner/repo> --title "Add feature" --description "Brief description" --assignee <username>
# Complex MR - write description to file first (pick your own path)
glab mr create --push -H <owner/repo> --title "Add feature" --description "$(cat "$DESC")" --assignee <username>
Templates: Check .gitlab/merge_request_templates/ for project-specific templates.
Full flag list (Claude Code injects this automatically; other agents should run it):
!glab mr create --help
glab mr update <number> --description "$(cat "$DESC")"
glab mr view <number> -R <owner>/<repo>
The full, always-current flag list (Claude Code injects this automatically; other agents should run it):
!glab issue --help
view, note, list, create, update work as you'd expect. The non-obvious traps that
--help won't warn you about:
# List is open by default and has NO --state flag — use --closed / --all instead
glab issue list --closed -R <owner>/<repo>
glab issue list --all -R <owner>/<repo>
# Labels — use --label / --unlabel, NEVER +label or -label syntax
glab issue update 123 --label "new-label"
glab issue update 123 --unlabel "old-label"
# Scoped labels auto-replace within their scope — no --unlabel needed:
glab issue update 123 --label "status::doing" # removes any existing status:: label
# Messages with backticks/$ — write to a file first (see Message Escaping above)
glab issue note <number> -m "$(cat "$MSG")" -R <owner>/<repo>
For issue state transitions (close/reopen via API) and posting notes via glab api: references/issue-api.md
GitLab is migrating issues to work items. The URL shows /work_items/<iid> but the REST API is the same.
# ✅ Use the issues API — same IID, same endpoints
glab api "projects/org%2Fproject/issues/<iid>"
# ❌ /work_items/ REST endpoint does not exist
glab api "projects/org%2Fproject/work_items/<iid>" # → 404
URL parsing: https://gitlab.com/org/project/-/work_items/539076
→ glab api "projects/org%2Fproject/issues/539076"
Full details, GraphQL alternative, and group-level work items: references/work-items.md
Since glab v1.94.0, glab mr note handles every common MR-comment shape (list, general, diff-line, reply, resolve/reopen) without raw glab api calls or hand-built position objects. Prefer it for any single-comment workflow. The MR IID is a positional argument (not --mr); omit it to auto-detect from the current branch.
# ✅ Use glab mr note for read/write/reply/resolve — single command per operation
glab mr note list 123 -F json # read discussions
glab mr note create 123 -m "comment" # general
glab mr note create 123 --file main.go --line 42 -m "..." # diff comment
glab mr note create 123 --reply abc12345 -m "..." # reply
glab mr note resolve 123 abc12345 # resolve thread
# ❌ Do NOT use glab api .../discussions for these operations
glab api "projects/<id>/merge_requests/123/discussions" # use mr note list
glab api --method PUT ".../discussions/<id>" -f resolved=true # use mr note resolve
Full flag list for the subcommands above (Claude Code injects this automatically; other agents should run it):
!glab mr note --help
Fall back to raw glab api .../draft_notes only for batched draft reviews (multiple inline comments published together via bulk_publish) — glab mr note has no draft mode.
Full reference (all flags, code suggestions, drafts/batch fallback, position objects): references/mr-review.md
blocked_by, relates_to): references/issue-links.md%2F encoding): references/nested-groups.mdFull flag list (Claude Code injects this automatically; other agents should run it):
!glab mr list --help
Note: glab mr list lists open MRs by default and has no --state or --status flag —
use --all, --merged, or --closed to change the state filter.
For full search examples (instance / group / project, scope table, pagination): references/search.md
Quick reference:
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 '.[]'
Follow the repo's own git conventions when present (a project may document them and enforce them with a commit linter). GitLab defaults:
git checkout -b feature/description # feature branches
git checkout -b fix/description # bug fixes
Closes https://gitlab.com/org/project/-/issues/123.git commit -m 'Add note from https://gitlab.com/org/project/-/merge_requests/123'.The sections above cover the common workflows. These are the non-obvious traps and
API quirks that are easy to get wrong and not discoverable from glab <cmd> --help:
glab issue view / glab mr view before implementing; check .gitlab/issue_templates/ and .gitlab/merge_request_templates/ for templates--jq works on subcommands, not on glab api — glab issue list/glab mr list/glab ci list accept a global --jq flag (filters JSON output); glab api does not — pipe its output through | jq '...' instead--body flag — glab uses --description, not --body (which is a gh flag); they are not interchangeable/work_items/<iid> URLs → projects/.../issues/<iid>; the /work_items/ REST endpoint is a 404/notes GET+POST both → 404 (still true on GitLab 19.1); pass body/noteableId as GraphQL variables, never string-interpolate. See references/epic-comments.md-R for group-level API — -R expects OWNER/REPO; group endpoints use glab api "groups/..." directly%2F — groups/org%2Fsubgroup/epics; unencoded slashes → 404workItem(iid: "16428") not workItem(iid: 16428)groups/<id>/work_items is 404 — use groups/<id>/epics (REST) or GraphQLproject exposes workItems (plural), not workItem — under project use workItems(first: 1, iid: "IID") with no filter: argument; the singular workItem(iid:) field exists only under group/namespacestate_event=close/reopen on PUT groups/<id>/epics/<iid> works; no GraphQL needed--label "status::doing" removes any existing status::* label; no --unlabel needed (this is a platform fact, true via the API generally, not just glab)--unique — glab mr note create -m "..." --unique skips posting if an identical body already exists; matches on body only, so identical bodies on different diff lines still postremote_alias — if origin points at one instance but you want glab to target another remote (e.g. a local GDK added as gdk), run glab config set remote_alias gdk rather than setting GITLAB_HOST per command. See references/multi-host.md`/$ in -m "..." or --description "..."; write to a file you name (unique per invocation) using << 'EOF' (single-quoted delimiter, critical), then pass via $(cat "$FILE"). See the Message Escaping section above.This skill is maintained in the GitLab monolith
(gitlab-org/gitlab, under
.claude/skills/glab/) and synced out to
gitlab-org/ai/skills — the monolith copy
is the source of truth. If you discover that any guidance here is inaccurate or
outdated (e.g. a command that no longer works, a wrong flag, an incorrect API
behavior), confirm with the user and open an MR against the monolith with the fix.
Keep changes focused — one fix per MR.