| --- |
| name: gerrit-task-query |
| description: Use when asked to check, list, or act on tasks for a Gerrit change. Triggers on phrases like "what tasks are blocking", "which tasks are actionable", "check task status", "what do I need to do for this change", "what is blocking this change". |
| allowed-tools: Bash, mcp__gerrit__get_task_tree, mcp__gerrit__get_actionable_tasks, mcp__gerrit__post_review_comment, mcp__gerrit__list_change_comments, mcp__gerrit__get_change_details |
| --- |
| |
| # Gerrit Task Query |
| |
| The Gerrit task plugin attaches a task tree to each change. Tasks represent CI |
| checks, review requirements, and dependency gates. This skill shows how to fetch |
| the task tree, find tasks that need action, and determine what to do. |
| |
| The tools `get_task_tree` and `get_actionable_tasks` are provided by the |
| `gerrit_mcp_server_task` extension (entry point `gerrit_mcp_server.extensions`). |
| They are available whenever `gerrit-mcp-server` is running with the task |
| extension installed and a configured Gerrit host that has the `task` plugin |
| enabled. |
| |
| ## 1. Fetch tasks for a change |
| |
| Task plugin options (`task--applicable`, `task--only`, etc.) are Gerrit |
| DynamicOptions — they are passed as direct HTTP query parameters |
| (`&task--applicable`), not as standard Gerrit output options (`&o=`). |
| |
| **Using the MCP tools (preferred — returns structured task tree JSON):** |
| |
| ```python |
| # All applicable tasks for a change |
| get_task_tree(change_id="123") |
| |
| # Scope to one root task |
| get_task_tree(change_id="123", task_only="Jenkins") |
| |
| # Convenience: returns only READY and FAIL nodes, pre-walked |
| get_actionable_tasks(change_id="123") |
| get_actionable_tasks(change_id="123", task_only="Jenkins") |
| ``` |
| |
| **Using `query_changes` / `get_change_details` (plain-text summary only):** |
| |
| ```python |
| # These pass task parameters but only return a text summary — use the task tools above instead |
| query_changes(query="change:123", parameters={"task--applicable": None}) |
| get_change_details(change_id="123", parameters={"task--applicable": None}) |
| ``` |
| |
| ## 2. Task node fields |
| |
| | Field | Meaning | |
| | ------------- | ------------------------------------------------------------------------ | |
| | `name` | Task name | |
| | `status` | Status value (see table below) | |
| | `hint` | Human-readable explanation (present on READY and FAIL) | |
| | `in_progress` | `true` if task is currently executing | |
| | `has_pass` | `true` if the task has a terminal pass/fail condition | |
| | `exported` | Custom key-value metadata from the task definition | |
| | `change` | Change number — only on tasks generated by a `change`-type tasks-factory | |
| | `sub_tasks` | Child task nodes (recursive, arbitrary depth) | |
| |
| ## 3. Status meanings |
| |
| | Status | Actionable? | Meaning | |
| | ----------- | ---------------- | -------------------------------------------------------- | |
| | `READY` | **Yes** | All prerequisites met; task is waiting to be executed | |
| | `FAIL` | **Yes** | Task executed and failed; workflow is blocked | |
| | `WAITING` | No — look inside | Blocked by subtasks not yet passing; dig into `subTasks` | |
| | `PASS` | No | Completed successfully | |
| | `DUPLICATE` | No | Same key seen in an ancestor; skipped to prevent loops | |
| | `SKIPPED` | No | Evaluation skipped (too expensive) | |
| | `UNKNOWN` | No | Insufficient permissions to evaluate | |
| | `INVALID` | No — config bug | Bad task definition | |
| |
| **Actionable = status is `READY` or `FAIL`.** |
| |
| ## 4. Finding actionable tasks |
| |
| Use `get_actionable_tasks` — it walks the tree for you. |
| |
| If walking manually: go depth-first. Collect every node with `status == "READY"` |
| or `status == "FAIL"`. Continue descending into `WAITING` nodes. Stop at `PASS`, |
| `DUPLICATE`, `SKIPPED`, `UNKNOWN`. |
| |
| ``` |
| def find_actionable(node): |
| if node.status in (READY, FAIL): |
| yield node |
| elif node.status == WAITING: |
| for child in node.subTasks: |
| yield from find_actionable(child) |
| # PASS, DUPLICATE, SKIPPED, UNKNOWN → stop |
| ``` |
| |
| ## 5. Acting on actionable tasks |
| |
| The task plugin does not prescribe what action to take — that is determined by |
| the `hint` field written by the task config author. |
| |
| **General approach:** |
| |
| 1. Read `hint` — this is the authoritative instruction from the config author |
| 2. Check `exported` — may carry metadata like CI system name, ticket ID, |
| priority |
| 3. Check `inProgress` — if `true`, the task is already being handled; skip it |
| 4. Check `change` — if present, this task represents a blocking dependent change |
| |
| **Common patterns:** |
| |
| | Pattern | How to identify | What to do | |
| | ------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| | CI verification needed | `READY`, hint mentions a CI system name | Trigger the CI system (comment, API call, or re-push — method depends on the system) | |
| | Label vote missing | hint mentions `label:X=+1` or a vote count | Use `post_review_comment` with `labels` (e.g. `{"Code-Review": 1}`) | |
| | Dependent change blocking | `FAIL` + task has a `change` field | The blocking change is in `.change`; resolve or unblock it before this one can pass | |
| | External/Depends-on issue | hint mentions "Depends-on" or "external dependencies" | Fix the issues with the `Depends-on` change dependencies (use the depends-on plugin tools and skills if available) or wait for the referenced change to merge | |
| | Code review needed | hint mentions code review or approval count | Cast a Code-Review vote or request a reviewer | |
| |
| Use `post_review_comment` to post comments or cast label votes, and |
| `list_change_comments` to read existing ones. |
| |
| ## 6. Reporting to the user |
| |
| For each actionable task, report: |
| |
| - Task name and status (`READY` or `FAIL`) |
| - `hint` — primary actionable signal |
| - `exported` properties if present |
| - `change` number if present (means this task represents a blocking change) |
| - Whether `inProgress` is `true` (already being handled) |