feat(repo_update): tool for archiving + metadata patches
All checks were successful
CD / Lint / Test / Vet (pull_request) Successful in 7s
CD / Build & Import (pull_request) Has been skipped
CD / Deploy via GitOps (pull_request) Has been skipped

Adds a repo_update tool exposing PATCH /api/v1/repos/{owner}/{name}
with optional pointer fields (archived, description, private,
website, template). Only fields set by the caller are sent on the
wire, so the server patches exactly what was asked for.

Originally needed to archive ingestion-svc cleanly instead of
leaving a README tombstone, and to flip template-go-{agent,web}
to template=true so create_project_from_template stops failing
the "is not marked as template" guard.

Wire-level enforcement of "at least one field" returns ErrValidation
before any network call, preventing no-op PATCHes.

private=false (making a repo public) is allowed but flagged in the
tool description with a "verify intent before calling" warning.
The earlier issue draft suggested an ntfy confirmation hook for
that path — out of scope for this PR; the warning string is the
minimum that fits inside the tool surface today.

Wires NewRepoUpdate into cmd/gitea-mcp/main.go alongside the rest
of the repo_* family.

Closes #12
This commit is contained in:
Mathias
2026-05-16 23:01:33 +02:00
parent 103194a11a
commit d74b196db1
4 changed files with 252 additions and 0 deletions

View File

@@ -86,3 +86,34 @@ func (c *Client) GetRepo(ctx context.Context, owner, name string) (*Repo, error)
}
return &r, nil
}
// EditRepoArgs carries optional fields for PATCH /api/v1/repos/{owner}/{name}.
// Pointer fields let the caller omit unset values from the wire payload, so the
// server only patches what was explicitly requested.
type EditRepoArgs struct {
Archived *bool `json:"archived,omitempty"`
Description *string `json:"description,omitempty"`
Private *bool `json:"private,omitempty"`
Website *string `json:"website,omitempty"`
Template *bool `json:"template,omitempty"`
}
func (c *Client) EditRepo(ctx context.Context, owner, name string, args EditRepoArgs) (*Repo, error) {
body, err := json.Marshal(args)
if err != nil {
return nil, fmt.Errorf("marshal edit args: %w", err)
}
path := fmt.Sprintf("/api/v1/repos/%s/%s", owner, name)
resp, status, err := c.PatchJSON(ctx, path, body)
if err != nil {
return nil, err
}
if err := MapStatus(status, resp); err != nil {
return nil, err
}
var r Repo
if err := json.Unmarshal(resp, &r); err != nil {
return nil, err
}
return &r, nil
}