refactor(gitea-prs): retrofit to the ADR-0020 context contract

Description 709 -> 161 chars, body 683 -> 353 words, Gotchas 8 entries/56% of
body -> 2/24.9%. Clears the description FAIL and both Vale CompositionNote
errors.

Fixes the three stale claims recorded on issue #99, all re-verified against the
deployed gitea-mcp schema during review:

- The description no longer advertises 'reviewers' as an update capability.
  editPullRequestFn never reads reviewers or team_reviewers; only
  add_reviewers/remove_reviewers do.
- milestone is now marked honoured on "update" only, in the Gotcha, the body
  and the dispatch table's create row. On "create" the server discards it and
  omits the key from the response, so the drop is indistinguishable from never
  passing it -- and labels DOES apply on create, so labels landing is no
  evidence the milestone did. The old text told callers to resolve a milestone
  before any write, wasting the lookup on create.
- The superseded un-draft workaround is gone. "update" with draft:false and no
  title makes the server strip the prefix itself, including [WIP],
  case-insensitively -- carried by references/pull-requests.md, corrected in
  PR #106.

The 22-row tool/method table becomes a 5-row dispatch table; all 20 operations
it named remain reachable, including update_branch and the reviewer methods.

Refs #99
This commit is contained in:
2026-08-30 12:10:21 +00:00
parent d5954d3d99
commit d578d6b2f2
3 changed files with 26 additions and 47 deletions

View File

@@ -4,7 +4,7 @@ List, read, create, update, merge, and review Gitea pull requests.
## What it does
This skill handles the pull request lifecycle within the Gitea integration suite — listing and reading PRs (details, diff, changed files, CI status, reviews), creating them (title, body, labels), updating them (title, body, assignees, labels, milestone), managing reviewers, closing/reopening, merging with a chosen strategy and post-merge branch cleanup, and the full code-review flow (create a review with inline comments, submit it, dismiss or delete it). It composes `gitea-labels-milestones` for label/milestone ID resolution rather than duplicating that logic, and defers to `gitea-issues` for anything that turns out to be an issue rather than a PR (they share one number space) and to `gitea-branches`/`gitea-files` for the underlying branch/file operations behind a PR.
This skill handles the pull request lifecycle within the Gitea integration suite — listing and reading PRs (details, diff, changed files, CI status, reviews), creating them (title, body, labels), updating them (title, body, assignees, labels, milestone), adding and removing reviewers, closing/reopening, merging with a chosen strategy and post-merge branch cleanup, and the full code-review flow (create a review with inline comments, submit it, dismiss or delete it). It composes `gitea-labels-milestones` for label/milestone ID resolution rather than duplicating that logic — `milestone` applies on an update only, never on create — and defers to `gitea-issues` for anything that turns out to be an issue rather than a PR (they share one number space) and to `gitea-branches`/`gitea-files` for the underlying branch/file operations behind a PR.
## Usage
@@ -18,7 +18,7 @@ Describe the PR or review task: list PRs, get a PR's status/diff/reviews, create
| File | Purpose |
|------|---------|
| `SKILL.md` | Skill instructions for agents — Gotchas, composition with `gitea-labels-milestones`, and the dispatch table |
| `SKILL.md` | Skill instructions for agents — Gotchas, the dispatch table, and label/milestone ID resolution via `gitea-labels-milestones` |
| `references/pull-requests.md` | Execution detail for `list_pull_requests`, `pull_request_read` (get/get_diff/get_files/get_status), and `pull_request_write` (create/update/close/reopen/update_branch/add_reviewers/remove_reviewers) |
| `references/reviews.md` | Execution detail for `pull_request_review_write` (create/submit/delete/dismiss) and the review-related `pull_request_read` methods |
| `references/merging.md` | The merge workflow — CI vs. review/branch-protection gates, merge styles, branch cleanup, and the post-merge issue-close check |

View File

@@ -2,14 +2,8 @@
name: gitea-prs
description: >
Use when listing, reading, creating, updating, merging, or reviewing Gitea pull requests —
getting PR status/diff/changed files/CI status, opening a PR, updating title/body/reviewers,
closing/reopening, merging with a chosen strategy, or submitting/dismissing a code review with
inline comments. Composes `gitea-labels-milestones` to resolve label names or milestone titles
to the numeric IDs `pull_request_write` requires, rather than duplicating that resolution logic.
Do not use for issues (`gitea-issues`) or branch/commit operations (`gitea-branches`) — a number
the user mentions may refer to either an issue or a PR since they share one number space, so
confirm which domain applies before dispatching.
Use when listing, reading, creating, updating, merging, or reviewing Gitea pull requests — even
when the user does not say "Gitea". Not issues -> `gitea-issues`.
compatibility: Requires Gitea MCP server configured with write:issue and write:repository token scopes.
@@ -20,49 +14,34 @@ metadata:
- gitea-mcp-slim-go
- context7-websites-gitea
- context7-gitea-tea-cli
version: "0.1.1"
version: "0.1.2"
allowed-tools: mcp__gitea__list_pull_requests mcp__gitea__pull_request_read mcp__gitea__pull_request_write mcp__gitea__pull_request_review_write
---
## Gotchas
- **Issues and PRs share one number space.** A number the user mentions (`#42`) might be an issue, not a PR — there is only one counter per repo. If you're not certain, call `pull_request_read method: "get"` and treat a 404 as "this number is an issue, not a PR" (or check `is_pull` on an `issue_read` response first if you already have one).
- **`pull_request_read method: "get"` returns `review_scomments`, not `review_comments`.** Source-level typo in gitea-mcp v1.3.0. Never reference `review_comments` — it will always be undefined.
- **`draft: true` on create prepends `"WIP:"` to the title.** Gitea has no first-class draft field — it implements draft PRs via title prefix. To un-draft, call `update` and pass the title without the `WIP:` prefix.
- **Cross-repo fork PRs require `head` as `"fork-owner:branch-name"`.** A bare branch name causes Gitea to search the base repo for it and return 422. Same-repo PRs use a bare branch name.
- **PR `milestone` is a bare title string, not `{id, title}`.** Unlike issues, you cannot recover a milestone's ID from a PR response. If you need the ID (e.g. to filter or to pass to another write), call into `gitea-labels-milestones` and match by title via `milestone_read method: "list"`.
- **CI status and review/approval state are independent merge gates.** `get_status` only reports CI. Branch-protection rules (required approvals, requested-reviewer coverage, stale-approval handling) are enforced server-side by the merge call itself and will error if unmet — passing CI does not mean the merge will succeed.
- **Reviews move through a state machine, not a single write.** `create` opens a review in `PENDING` state with inline comments attached; `submit` finalizes it with a terminal `state` (`APPROVED`/`REQUEST_CHANGES`/`COMMENT`). A submitted review can be `dismiss`ed afterward, but never deleted — `delete` only removes a review that was never submitted.
- **Merging a PR does not auto-close linked issues.** Unlike GitHub, Gitea has no merge-triggers-close event. It does parse closing keywords (`Fixes #N`, `Closes #N`) in commit messages landing on the default branch, so a non-squash merge that preserves those commit messages may auto-close the issue — but a squash merge rewrites history into one commit, so survival of the keyword depends on the squash commit's message. Always call `issue_read method: "get"` on any referenced issue after merging to check whether it already closed before deciding to close it explicitly.
## Composing `gitea-labels-milestones`
Before any `pull_request_write` call that includes a `labels` or `milestone` parameter, resolve names/titles to numeric IDs via `gitea-labels-milestones` — `label_read method: "list_repo_labels"` for label name → ID, `milestone_read method: "list"` for milestone title → ID. Never pass a label name string or milestone title string directly to `pull_request_write`; both parameters take numeric IDs only. This skill does not duplicate that lookup logic — it composes the shared skill.
- **Issues and PRs share one number space.** `#42` may be an issue rather than a PR. When unsure, call `pull_request_read method: "get"` and read a 404 as "that number is an issue" — hand it to `gitea-issues`.
- **`pull_request_write method: "create"` discards most optional parameters in silence.** `milestone`, `assignee`, `assignees`, `reviewers` and `team_reviewers` are accepted, dropped, and left out of the response, so a drop is indistinguishable from never passing them. `labels` *does* apply on `"create"`, so labels landing is no evidence the milestone did.
## Dispatch
| Task | Tool | method |
|---|---|---|
| List PRs | `list_pull_requests` | — |
| Get PR details | `pull_request_read` | `"get"` |
| Get PR diff | `pull_request_read` | `"get_diff"` |
| Get PR changed files | `pull_request_read` | `"get_files"` |
| Get PR CI status | `pull_request_read` | `"get_status"` |
| Get PR reviews | `pull_request_read` | `"get_reviews"` |
| Get one review | `pull_request_read` | `"get_review"` |
| Get review inline comments | `pull_request_read` | `"get_review_comments"` |
| Create a PR | `pull_request_write` | `"create"` |
| Update a PR | `pull_request_write` | `"update"` |
| Close a PR | `pull_request_write` | `"close"` |
| Reopen a PR | `pull_request_write` | `"reopen"` |
| Merge a PR | `pull_request_write` | `"merge"` |
| Update branch from base | `pull_request_write` | `"update_branch"` |
| Add reviewers | `pull_request_write` | `"add_reviewers"` |
| Remove reviewers | `pull_request_write` | `"remove_reviewers"` |
| Create a review | `pull_request_review_write` | `"create"` |
| Submit a review | `pull_request_review_write` | `"submit"` |
| Delete a review | `pull_request_review_write` | `"delete"` |
| Dismiss a review | `pull_request_review_write` | `"dismiss"` |
Resolve `owner` and `repo` from context first, and confirm the number names a PR before writing to it.
For full parameter detail on listing/reading/creating/updating/closing PRs, read `references/pull-requests.md`. For review-specific detail (create/submit/delete/dismiss, inline comment shape), read `references/reviews.md`. For the merge workflow specifically (CI gate, merge styles, branch cleanup, post-merge issue check), read `references/merging.md`.
| Task | Tool | Reference |
|---|---|---|
| List PRs; read a PR's details, diff, changed files or CI status | `list_pull_requests`, `pull_request_read` | `references/pull-requests.md` |
| Create a PR — subject to the silent-drop Gotcha above | `pull_request_write` | `references/pull-requests.md` |
| Update, close, reopen or retarget a PR, sync it with its base, or add/remove reviewers | `pull_request_write` | `references/pull-requests.md` |
| Merge a PR, or judge whether it can merge | `pull_request_write method: "merge"` | `references/merging.md` |
| Read, create, submit, dismiss or delete a code review | `pull_request_read`, `pull_request_review_write` | `references/reviews.md` |
Whatever `"create"` dropped takes a second call once the PR exists — `"update"` for milestone and assignees, `"add_reviewers"` for reviewers.
Read the reference for the row you land on before making the call. Each carries the parameter signatures, the per-method behaviour and the response-shape quirks the row cannot, and every write method has at least one parameter that behaves differently from its issue-side counterpart.
## Resolving labels and milestones
`labels` and `milestone` take numeric IDs, never name or title strings. Before a `pull_request_write` call carrying either, resolve them through `gitea-labels-milestones`: `label_read method: "list_repo_labels"` for a label name, `milestone_read method: "list"` for a milestone title.
Resolve a milestone only when the call is an `"update"` — on `"create"` the lookup is wasted, per the Gotcha above. Recovering an existing PR's milestone ID needs the same lookup, because `pull_request_read` returns `milestone` as a bare title string and never an ID.

View File

@@ -21,7 +21,7 @@
- **URL:** context7:/websites/gitea
- **Description:** Official Gitea docs mirror on Context7 — branch protection rules, PR review/merge gating behavior, and automatic issue/PR cross-reference linking. Backfills the external/best-practice gap left by the original docs.gitea.com fetch timeout.
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
- **Contributing files:** SKILL.md, references/merging.md
- **Contributing files:** references/merging.md
- **Status:** `extracted`
## context7-gitea-tea-cli