fix(gitea): correct which pull_request_write params apply on create #106

Merged
Defame1297 merged 2 commits from fix/gitea-prs-create-drops-params into main 2026-08-17 20:33:57 +00:00
Collaborator

Fixes #104.

What was wrong

references/pull-requests.md documented milestone as "settable on both "create" and "update"". It is not. pull_request_write method: "create" accepts the parameter, returns no error and no warning, and discards it.

Scope is wider than the issue supposed

#104 was filed from observed behaviour and flagged assignees/reviewers as untested but suspect. I verified against the gitea-mcp v1.6.0 source rather than by observation alone — get_gitea_mcp_server_version confirms that is the running server. createPullRequestFn (operation/pull/pull.go:430) builds its option struct from a fixed, short list:

opt := gitea_sdk.CreatePullRequestOption{Title: title, Body: body, Head: head, Base: base}
if labelIDs, err := params.GetInt64Slice(args, "labels"); err == nil { opt.Labels = labelIDs }
opt.Deadline = params.GetOptionalTime(args, "deadline")

So the suspicion was correct, and the drop is not limited to milestone:

Parameter "create" "update" Actually honoured by
labels, deadline applies applies both
assignee, assignees, milestone dropped applies "update" only
reviewers, team_reviewers dropped dropped "add_reviewers" / "remove_reviewers" only

The old text claimed create-time settability for reviewers/team_reviewers too, so that line was wrong in the same way and is corrected here.

Why it was easy to get wrong

Both properties are now written down next to the correction, because neither is discoverable from a create response:

  • labels sits beside milestone, reads identically, and does apply on create. A caller who confirms the labels landed will reasonably assume the milestone did too.
  • issue_write method: "create" does honour assignees and milestone — I checked createIssueFn to be sure. The asymmetry is specific to pull requests, so experience with the issue write actively misleads you here.

Nothing in the create response distinguishes a dropped parameter from one never passed — the key is simply absent.

Adjacent correction, beyond the issue's ask

The neighbouring draft gotcha prescribed reconstructing the un-prefixed title by hand to un-draft a PR. applyDraftPrefix shows "update" with draft: false and no title fetches the stored title and strips the prefix server-side. Same class of defect, same file, one sentence — called out separately so it can be dropped if you'd rather keep this PR to the issue's scope.

Verification

  • bash tests/run-tests.sh --strict — 24 passed, 0 skipped, 0 failed
  • pre-commit run --hook-stage pre-push --all-files — all 16 pass
  • The issue's ADR-0020 analysis held: hooks on the changed file report skill-size-check ... Skipped, so gitea-prs needed no #99 retrofit first
  • Flat mirror regenerated via scripts/sync-plugin-content.sh plugins/gitea, not hand-edited

Documentation only; no behaviour change. Callers following the old text silently opened PRs with no milestone, assignee or reviewer.

Refs #99.

Fixes #104. ## What was wrong `references/pull-requests.md` documented `milestone` as *"settable on both `"create"` and `"update"`"*. It is not. `pull_request_write method: "create"` accepts the parameter, returns no error and no warning, and discards it. ## Scope is wider than the issue supposed #104 was filed from observed behaviour and flagged `assignees`/`reviewers` as untested but suspect. I verified against the `gitea-mcp` **v1.6.0** source rather than by observation alone — `get_gitea_mcp_server_version` confirms that is the running server. `createPullRequestFn` (`operation/pull/pull.go:430`) builds its option struct from a fixed, short list: ```go opt := gitea_sdk.CreatePullRequestOption{Title: title, Body: body, Head: head, Base: base} if labelIDs, err := params.GetInt64Slice(args, "labels"); err == nil { opt.Labels = labelIDs } opt.Deadline = params.GetOptionalTime(args, "deadline") ``` So the suspicion was correct, and the drop is not limited to `milestone`: | Parameter | `"create"` | `"update"` | Actually honoured by | |---|---|---|---| | `labels`, `deadline` | applies | applies | both | | `assignee`, `assignees`, `milestone` | **dropped** | applies | `"update"` only | | `reviewers`, `team_reviewers` | **dropped** | **dropped** | `"add_reviewers"` / `"remove_reviewers"` only | The old text claimed create-time settability for `reviewers`/`team_reviewers` too, so that line was wrong in the same way and is corrected here. ## Why it was easy to get wrong Both properties are now written down next to the correction, because neither is discoverable from a create response: - **`labels` sits beside `milestone`, reads identically, and does apply on create.** A caller who confirms the labels landed will reasonably assume the milestone did too. - **`issue_write method: "create"` *does* honour `assignees` and `milestone`** — I checked `createIssueFn` to be sure. The asymmetry is specific to pull requests, so experience with the issue write actively misleads you here. Nothing in the create response distinguishes a dropped parameter from one never passed — the key is simply absent. ## Adjacent correction, beyond the issue's ask The neighbouring draft gotcha prescribed reconstructing the un-prefixed title by hand to un-draft a PR. `applyDraftPrefix` shows `"update"` with `draft: false` and no `title` fetches the stored title and strips the prefix server-side. Same class of defect, same file, one sentence — called out separately so it can be dropped if you'd rather keep this PR to the issue's scope. ## Verification - `bash tests/run-tests.sh --strict` — 24 passed, 0 skipped, 0 failed - `pre-commit run --hook-stage pre-push --all-files` — all 16 pass - The issue's ADR-0020 analysis held: hooks on the changed file report `skill-size-check ... Skipped`, so `gitea-prs` needed no #99 retrofit first - Flat mirror regenerated via `scripts/sync-plugin-content.sh plugins/gitea`, not hand-edited Documentation only; no behaviour change. Callers following the old text silently opened PRs with no milestone, assignee or reviewer. Refs #99.
Claude added the Kind/BugKind/Documentation
Priority
Medium
3
labels 2026-08-17 17:04:04 +00:00
Claude added 1 commit 2026-08-17 17:04:04 +00:00
The gitea-prs reference documented `milestone` as "settable on both
"create" and "update"". It is not: `pull_request_write method: "create"`
accepts the parameter, returns no error or warning, and discards it.

Verified against the gitea-mcp v1.6.0 source rather than by observation
alone. `createPullRequestFn` builds its `CreatePullRequestOption` from
owner, repo, title, body, head, base, draft, labels and deadline only —
so the drop is not limited to `milestone` as issue #104 supposed.
`assignee`, `assignees`, `reviewers` and `team_reviewers` are discarded
on create too, and `reviewers`/`team_reviewers` are discarded on
"update" as well; they are only ever read by "add_reviewers" and
"remove_reviewers".

Two properties made the original error easy to make and hard to catch,
so both are now written down next to the correction: `labels` sits
beside `milestone`, reads identically, and does apply on create; and
`issue_write method: "create"` honours `assignees` and `milestone`, so
the asymmetry is specific to pull requests.

While in the file, corrected the adjacent draft gotcha. It prescribed
reconstructing the un-prefixed title by hand to un-draft a PR;
`applyDraftPrefix` shows "update" with `draft: false` and no `title`
fetches the stored title and strips the prefix server-side.

Impact: documentation only, no behaviour change. Callers following the
old text silently created PRs with no milestone, assignee or reviewer.
Confined to references/pull-requests.md, so the ADR-0020 skill gates do
not apply and gitea-prs needs no #99 retrofit first.

Fixes: #104
Refs: #99

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ETxbGFetkbJQBHsx442Brt
Claude added this to the Skills & Agents milestone 2026-08-17 17:04:10 +00:00
Defame1297 added 1 commit 2026-08-17 20:20:38 +00:00
Follow-up to the review of #106, which found four parameter claims the
first pass left wrong or missing. All four verified against gitea-mcp
v1.6.0 source before changing anything.

`remove_deadline` is dropped on "create" like the others, but the new
Gotcha enumerated a closed list that omitted it — so the paragraph
contradicted its own opening sentence. The list is now open ("including")
and the parameter carries the same "update" only marker as its neighbours.

`base` is settable on "update": editPullRequestFn reads it and retargets
the PR onto a different base branch. The file documented it as required
for "create" and said nothing else, hiding a real capability. This one is
under-claiming rather than over-claiming, but a file whose subject is
which parameter applies to which method is the place to fix it.

applyDraftPrefix strips two prefixes, `WIP:` and `[WIP]`, matched with
strings.EqualFold, while only "WIP: " is ever added. The un-draft
correction said "the prefix" singular, which understates what a caller
can hand it.

README.md bundled `reviewers` and `milestone` into "creating and
updating". Capability prose rather than a parameter contract, so not
strictly false, but it is the same conflation that produced the original
bug and it is not behind any gate.

Not addressed here: SKILL.md's description still advertises updating
reviewers, its draft guidance still prescribes the manual workaround, and
its milestone-resolution instruction carries no method qualifier — so an
agent working from SKILL.md alone can still reach the failure mode. Those
edits trip skill-size-check and the Vale prefilter, pulling in the
ADR-0020 retrofit; tracked on #99 rather than done silently here.

Refs: #104
Refs: #99

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ETxbGFetkbJQBHsx442Brt
Defame1297 approved these changes 2026-08-17 20:33:53 +00:00
Defame1297 merged commit 0e91a3ae66 into main 2026-08-17 20:33:57 +00:00
Defame1297 deleted branch fix/gitea-prs-create-drops-params 2026-08-17 20:33:57 +00:00
Sign in to join this conversation.