Repeat and fullfill your GitLab Agent tasks.
Workboard or any other tools to manage your work, just use GitLab.glab CLI. This includes creating and updating issues, merge requests, branches, comments, and more.Skip the owner membership check when the authenticated GitLab user is the configured owner. Otherwise, the gate is mandatory and is performed by {baseDir}/scripts/list-active-items.py during discovery.
GITLAB_AGENT_OWNER, or from the active workspace USER.md field GitLab Username when the environment variable is unset.workflow::forbidden: it removes the label after an allowed check, and on denial replaces existing workflow::* labels with workflow::forbidden and silently omits the object from the queue.workflow::forbidden directly; only the discovery helper owns that label.The check fails closed when the current GitLab user has no active project membership, membership data is incomplete, the membership was not created by the configured owner, or labels cannot be read. A denied object must not be analyzed, cloned, pushed, commented on, or retried.
Before working an existing issue, work item, or merge request, check the current GitLab user and the assignees on that object.
size::*, type::*, and workflow::* labels when the correct label state is clear, except that workflow::forbidden is owned exclusively by the discovery helper.An assigned item that passes both gates may authorize work in an external project only when its description or a later owner/Maintainer note names the exact upstream URL. Inspect only that scope, use an agent-owned fork, and open a cross-project MR; do not run the security gate on the upstream project or require upstream assignment. Keep workflow state on the controlling item and do not change the upstream issue's labels, status comments, time tracking, assignment, or state. Missing upstream membership alone is not workflow::forbidden or workflow::need-human.
Before posting an issue, work item, or merge request status comment, compare the current object state with the last agent-authored status comment for the same object.
{baseDir}/scripts/list-active-items.py to fetch all open issues and merge requests assigned to the current GitLab user across projects.type::support and workflow::in-progress, and maps known GitLab severity levels to priority::*. Unknown severity does not invent a priority.workflow::forbidden label if access becomes allowed.activity_cursor as acknowledged only after that item's notes and, for merge requests, discussions have been fully paginated and inspected. Persist acknowledged cursors in the durable cycle checkpoint, keyed by the item's web_url; never advance a cursor for an unaudited item.{baseDir}/scripts/mr-create.py <project-path> <source-branch>. The helper calls glab mr create, assigns the current user, and returns structured evidence including any fallback reason. Pass --title, --description, and --related-issue when the MR needs an explicit plan, acceptance criteria, and issue relation. An exact target from the item, a later owner/Maintainer note, or AGENTS.md may be passed using --target <branch> --target-source <item|owner-note|agents>.feat/*fix/*workflow::need-human label, escalate it to all team members by assigning it to them in addition to you.workflow::paused.workflow::blocked and return to the merge request once fixed.blocking_discussions_resolved=true or "discussion-clean".requested changes, reviewer comments, and non-resolvable top-level notes as actionable feedback until addressed, even when blocking_discussions_resolved=true.{baseDir}/scripts/select-reviewer.py <project-path> <merge-request-iid> and inspect its structured dry-run result.--apply. Never select or mutate a reviewer free-form.workflow::need-human with the actionable diagnostic.Generated-By: <current model> to the commit message.git push origin <branch> -o ci.skipglab ci run --mr, unless there are active pipelines in main or dev. Never use more than X [setting: 2 # AGENTS.md -> active-pipelines] pipelines for your work. Add workflow::paused, if you delay the pipeline start and revisit later.workflow::done.AGENTS.mdAGENTS.md file from only the main branch of the project.[setting: <value> # <AGENTS.md -> key >] per project.Before moving a merge request to review, complete this checklist:
Reviewer selection is deterministic and must be performed by {baseDir}/scripts/select-reviewer.py. The helper reads AGENTS.md only from the project default branch, validates active project membership and exclusions, then applies this precedence:
AGENTS.md->reviewers order.The helper excludes the MR author, assignees, blocked or locked users, bots, service accounts, and the current automation account. Dry-run is the default. --apply revalidates the MR, selected membership, and human-user status immediately before the reviewer mutation.
Rules apply to all GitLab items.
@owner only when requested. Use per default owner.fetch and fast-forward before touching an MR branch, and use --force-with-lease only, never blind force-push.Read current labels; skip unchanged updates. Send only actual additions/removals, preserving unrelated labels. Change workflows only when work changes; security checks fail closed if labels cannot be read.
If the labels are missing, add them via a merge request using the label component.
yaml
include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/common@stable
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/label@stable
GitLab labelCommon nameMeaningsize::smallSmallNeeds only minor changes and is trivial. Within a day's resolutionsize::mediumMediumNeeds moderate changes and is somewhat complex. Within a few days' resolutionsize::largeLargeNeeds significant changes and is complex. Within a week or more resolutionsize::xlargeExtra largeNeeds extensive changes and is very complex. Within a month or more resolution
size is added before workflow::in-progress.GitLab labelCommon nameMeaningtype::supportSupport RequestSomeone need help, but no change. Maybe it resolves in new work item after investigation.type::bugBugfixSomething that needs to be fixed and existstype::featureFeatureSomething newtype::hotfixHotfixUrgent fix for a critical issue that merges directly in main.
type, if nothing of the above matches.type is added before workflow::in-progress.Use the labels in your merge requests to set the current status of the work. Only use one workflow status label at a time.
GitLab labelCommon nameMeaningworkflow::backlogBacklogNot yet started. Initial state.workflow::forbiddenForbiddenProject access failed the owner membership security gate; only the discovery helper manages this label.workflow::in-progressRunningActively worked onworkflow::pausedPausedAgent will continue later automatically. Temporarily paused for one hour to one day.workflow::need-humanNeed HumanRequires human intervention to fullfill current task and all other options are exhausted. Before adding the label, explain reason by comment in the issue. Its status is not blocked or paused.workflow::blockedBlockedCurrently blocked by a dependency or issue. On each assignment, check the status of the blocker. Reevaluate the blocker from time to time.workflow::reviewReviewWhen DoD has been checked and reviewer was assignedworkflow::doneDoneCompleted , final state, everything done and closedworkflow::staleStaleNo change in status for 2 Weeks and may need attention
Rendering diagram...
Additional rules
workflow::paused an item if it is prioritized as priority::blocker.workflow::blocked items.If the software has a fix for the CVE already released:
If unfixed:
workflow::blocked.fix: CVE-XXX-XXXXX;yaml
vulnerabilities:
# CVE-XXX-XXXXX: Temporarily accepted while the embedded glab dependency is fixed upstream.
# Tracked in https://gitlab.com/xrow-public/helm-openclaw/-/work_items/72.
- id: CVE-XXX-XXXXX
Once the CVE is fixed
workflow::blocked from the work item{baseDir}/... instead of hardcoding workspace-specific skill paths.allow_failure: true, skips, or bypasses to make CI green unless the job is genuinely optional/manual, and document why.AGENTS.md file, if requested by a maintainer.{baseDir}/references/documentation-style.md. Verify examples and review the rendered page before committing.glab CLI to interact with GitLab#Use the glab CLI to interact with GitLab. Specify --repo owner/repo or --repo group/namespace/repo when not in a git directory. Also accepts full URLs.
When you are using glab you are always authenticated as a GitLab user.
bash
glab api graphql -f query='
query {
currentUser { username }
}
'
<gitlab-username> is a reference in queries to your username.
<gitlab-username> is a refence to your username.
For issues:
bash
glab api graphql -f query='
query($username: String) {
issues(state: opened, assigneeUsername: $username, first: 50) {
nodes {
iid
title
webUrl
description
author {
username
name
emails {
email
}
}
createdAt
updatedAt
userNotesCount
labels(first: 20) {
nodes {
title
}
}
notes(first: 100) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
system
body
updatedAt
author {
username
}
}
}
}
}
}
' -f username=<gitlab-username>
To get the team members of a project:
bash
glab api graphql -f query='
query($fullPath: ID!) {
project(fullPath: $fullPath) {
fullPath
projectMembers(first: 100) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
accessLevel {
stringValue
}
user {
username
name
}
}
}
}
}
' -f fullPath=<group/namespace/repo>
For Merge Requests:
bash
glab api '/merge_requests?state=opened&scope=assigned_to_me'
List all Repositories:
bash
glab repo list --member
List open merge requests:
bash
glab mr list --repo owner/repo
View MR details:
bash
glab mr view 55 --repo owner/repo
Select and validate the target, then create the MR through the helper:
bash
{baseDir}/scripts/mr-create.py --title "Add example" --description "## Plan\n\n1. Add the change.\n\n## Acceptance criteria\n\n- [ ] The change is verified." --related-issue 42 owner/repo feat/42-example
Approve, merge, or check out:
bash
glab mr approve 55
glab mr merge 55
glab mr checkout 55
View MR diff:
bash
glab mr diff 55
Check pipeline status for current branch:
bash
glab ci status
View pipeline interactively (navigate jobs, view logs):
bash
glab ci view
List recent pipelines:
bash
glab ci list --repo owner/repo
Trace job logs in real time:
bash
glab ci trace
glab ci trace 224356863 # specific job ID
glab ci trace lint # by job name
Retry a failed pipeline:
bash
glab ci retry
Validate .gitlab-ci.yml:
bash
glab ci lint
All your current work items:
bash
glab api graphql -f query='
query($username: String) {
issues(state: opened, assigneeUsername: $username, first: 50) {
nodes {
iid
title
webUrl
}
}
}
' -f username=<gitlab-username>
List and view issues:
bash
glab issue list --repo owner/repo
glab issue view 42
Create an issue:
bash
glab issue create --title "Bug report" --label bug
Add a comment:
bash
glab issue note 42 -m "This is fixed in !55"
Use glab api for endpoints not covered by subcommands. Supports REST and GraphQL.
Get project releases:
bash
glab api projects/:fullpath/releases
Get MR with specific fields (pipe to jq):
bash
glab api projects/owner/repo/merge_requests/55 | jq '.title, .state, .author.username'
Paginate through all issues:
bash
glab api issues --paginate
GraphQL query:
bash
glab api graphql -f query='
query {
currentUser { username }
}
'
Pipe to jq for filtering:
bash
glab mr list --repo owner/repo | jq -r '.[] | "\(.iid): \(.title)"'
Manage CI/CD variables:
bash
glab variable list
glab variable set MY_VAR "value"
glab variable get MY_VAR
Create a release:
bash
glab release create v1.0.0 --notes "Release notes here"
\n for newlines in messages not \\n.-C flag.Send features and bugfixes for this skill as merge requests to the skills project.
Before enabling it:
Confirm the gitlab-agent skill exists.
Only enable the recurring job after the manual run succeeds.
Confirm GitLab auth works.
Add this cron, if it existed and was enabled then leave it enabled.
json
{
"name": "GitLab Agent",
"enabled": false,
"deleteAfterRun": false,
"schedule": {
"kind": "every",
"everyMs": 900000
},
"sessionTarget": "isolated",
"wakeMode": "now",
"payload": {
"kind": "agentTurn",
"message": "Read skill gitlab-agent and run.",
"thinking": "high",
"timeoutSeconds": 3600,
"model": "openai/gpt-6.1-sol"
},
"delivery": {
"mode": "none",
"bestEffort": false
}
}