fix(gitea): make gitea-releases executable and correct misleading domain claims
gitea-releases was the weakest skill in the plugin: no allowed-tools, no owner/repo resolution, and a checkbox list where a dispatch table belongs, so an agent reaching it had to guess both its permissions and its inputs. The id-vs-tag_name trap — deleting by tag name where the API wants the numeric id — is restored as an explicit Gotcha because it destroys the wrong release silently. Elsewhere the `exclusive` flag was documented on the wrong side of the read/write split, and label data from one instance was presented as though it were universal, which invites an agent to assume a taxonomy that does not exist on the target repo. rename_branch was missing from the branch surface. Reference prose and fences are cleaned up in passing.
This commit is contained in:
@@ -6,22 +6,40 @@ description: >
|
||||
create, or delete either — even when the user does not say "release" or
|
||||
"Gitea". Not branches or commit history -> `gitea-branches`.
|
||||
|
||||
compatibility: Requires Gitea MCP server configured with a token with write:repository scope, which
|
||||
gates every release and tag tool here. Requires git remote "origin" pointing to the Gitea instance
|
||||
for owner/repo resolution, unless an orchestrating caller passes them already resolved.
|
||||
|
||||
metadata:
|
||||
category: gitea
|
||||
category: integration
|
||||
version: "0.1.0"
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
- context7-websites-gitea
|
||||
- context7-gitea-tea-cli
|
||||
|
||||
allowed-tools: Bash mcp__gitea__list_releases mcp__gitea__get_release mcp__gitea__get_latest_release mcp__gitea__create_release mcp__gitea__delete_release mcp__gitea__list_tags mcp__gitea__get_tag mcp__gitea__create_tag mcp__gitea__delete_tag
|
||||
---
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Deleting a release never deletes its tag.** A release is a metadata wrapper around a tag, so removing both takes two independent destructive calls. The reverse — whether deleting a tag deletes its release — is *unconfirmed*; verify with `list_releases`/`get_release` after `delete_tag` rather than assume it survives.
|
||||
- **Set `is_draft`/`is_pre_release` explicitly on every `create_release` — Gitea never infers a prerelease from a `-beta`/`-rc` tag name.** A tag named `v2.0.0-beta.1` publishes as a full release, and becomes the repo's latest, unless `is_pre_release: true` is passed in the same call. The response object names them `draft`/`prerelease`; passing `draft` as an input key is silently ignored, not rejected.
|
||||
- **`list_releases`/`list_tags` default `per_page` to 20**, where most other gitea-mcp list tools default to 30 — a caller assuming 30 under-counts the pages a full sweep needs.
|
||||
- **`delete_release` takes the numeric `id`, never a `tag_name`; `delete_tag` takes the tag name, never an id.** Holding only a tag name, resolve the release id through `list_releases` or `get_release` first — a tag name passed to `delete_release` fails, and that failure is not evidence the release is already gone.
|
||||
- **Deleting a release never deletes its tag**, and the reverse direction is *unconfirmed* — verify with `list_releases`/`get_release` after `delete_tag`. Removing both takes two independent destructive calls.
|
||||
- **Set `is_draft`/`is_pre_release` explicitly on every `create_release`** — Gitea infers neither from a `-beta`/`-rc` tag name, so `v2.0.0-beta.1` publishes as a full release and becomes the repo's latest. `draft`/`prerelease` are output field names only; passing `draft` as an input key is silently ignored.
|
||||
- **`list_releases`/`list_tags` default `per_page` to 20**, where most other gitea-mcp list tools default to 30 — a caller assuming 30 under-counts pages.
|
||||
|
||||
## Dispatch table
|
||||
## Step 1 — Resolve owner and repo
|
||||
|
||||
`owner` and `repo` are required on every tool below. Extract them from the git remote, unless an orchestrating caller passed them in already:
|
||||
|
||||
```bash
|
||||
git remote get-url origin
|
||||
```
|
||||
|
||||
If origin is not set or the URL is not a Gitea URL, stop and report: "No Gitea remote found — set origin to your Gitea instance URL."
|
||||
|
||||
## Step 2 — Dispatch
|
||||
|
||||
| Action | Tool | Required params | Optional params |
|
||||
|---|---|---|---|
|
||||
@@ -37,13 +55,17 @@ metadata:
|
||||
|
||||
`target` (on `create_release`/`create_tag`) is a commitish — a branch name, existing tag, or commit SHA — the point the new tag is cut from.
|
||||
|
||||
Pass a caller-supplied `tag_name` through verbatim. Semver with a `v` prefix is a tooling convention, not a Gitea constraint — the API accepts any string — so never validate or rewrite it.
|
||||
Pass a caller-supplied `tag_name` through verbatim — the API accepts any string, and semver with a `v` prefix is a tooling convention rather than a Gitea constraint.
|
||||
|
||||
## Workflow
|
||||
## Step 3 — Procedure for the scenario in hand
|
||||
|
||||
- [ ] **Creating a release:** Call `create_release` with `tag_name`, `target`, `title`, and `is_draft`/`is_pre_release` set explicitly — never left to default. **There is no update or edit tool on this surface**: `create_release`, `get_release`, `get_latest_release`, `list_releases` and `delete_release` are the whole set. A release published with the wrong flag therefore has no non-destructive repair — the only fix is `delete_release` plus a fresh `create_release`. Gitea is assumed to create the tag from `target` when `tag_name` does not yet exist — plausible from the API shape, not confirmed in the research docs — so a separate `create_tag` is only needed to tag a commit without wrapping it in a release. Verify with `get_tag` afterward if the caller depends on it.
|
||||
- [ ] **Deleting a release:** `delete_release` takes the numeric `id` and never a `tag_name`; `delete_tag` is the mirror opposite and never takes an id. With only a tag name in hand, resolve the id through `list_releases` (paginating if needed) or `get_release` first.
|
||||
- [ ] **Deleting a tag along with its release:** Delete the release first, then call `delete_tag` — confirm both are intended before proceeding, since each is irreversible on its own.
|
||||
- [ ] **Listing every page:** Loop `page: 1, 2, 3...` until a response returns fewer than `per_page` entries. Nothing here auto-paginates.
|
||||
These four are mutually exclusive — pick the one row the request lands on.
|
||||
|
||||
| Scenario | Procedure |
|
||||
|---|---|
|
||||
| Create a release | Call `create_release` with `tag_name`, `target`, `title`, and `is_draft`/`is_pre_release` set explicitly — never left to default. This surface carries no update or edit tool, so a wrong flag is repairable only by delete-and-recreate (`references/conventions.md`). A separate `create_tag` is only needed to tag a commit without wrapping it in a release. |
|
||||
| Delete a release | Resolve the numeric `id` per the first Gotcha, confirm intent, then call `delete_release`. The tag survives. |
|
||||
| Delete a tag along with its release | Delete the release first, then call `delete_tag` — confirm both are intended before proceeding, since each is irreversible on its own. |
|
||||
| List every page | Loop `page: 1, 2, 3...` until a response returns fewer than `per_page` entries. Nothing here auto-paginates. |
|
||||
|
||||
If exact input params or response field shapes are needed, read `references/call-signatures.md`. If the caller raises semver tag naming, draft/prerelease semantics, release-notes sourcing, or how a release relates to its tag, read `references/conventions.md`.
|
||||
|
||||
Reference in New Issue
Block a user