blob: aa81f7b7cb39a08564e344b4edc401311f12f588 [file] [view]
---
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)