feat: add list_org_labels + merge org labels in list_repo_labels (closes #125) #130

Merged
goern merged 0 commits from refs/pull/130/head into main 2026-05-12 08:40:55 +00:00
goern commented 2026-05-11 14:48:20 +00:00 (Migrated from codeberg.org)

Summary

Implements the add-org-label-support OpenSpec change (already authored on issues/125, cherry-picked into this branch as commit 7b73057).

Closes #125 — reporter wanted org-level labels visible to the MCP server so the model doesn't need to make two requests to discover usable label IDs.

What

  • New tool list_org_labels(org, page, limit) — fetches /orgs/{org}/labels via pkg/forgejo.DoJSONList. No SDK upgrade required.
  • list_repo_labels augmented — new optional include_org_labels boolean (default true). When the owner is an org, the handler merges /orgs/{owner}/labels into the response.
  • ScopedLabel wrapper embeds *forgejo_sdk.Label and adds a scope field ("repo" | "org") so callers can disambiguate ID spaces in merged responses.

Behavior

Call Behavior
list_org_labels on existing org array of org labels, each scope: "org"
list_org_labels on missing org empty array (404 mapped by DoJSONList)
list_org_labels with 401/403 error wrapping forgejo.ErrUnauthorized
list_repo_labels on org-owned repo repo + org labels merged, each with scope
list_repo_labels on user-owned repo repo labels only (org endpoint 404 silently dropped)
list_repo_labels with include_org_labels=false repo labels only, no org request issued

Tests

operation/issue/issue_test.go adds 6 tests via newLabelsBackend helper:

  • TestListOrgLabels_Success
  • TestListOrgLabels_404IsEmpty
  • TestListOrgLabels_UnauthorizedSurfaces
  • TestListRepoLabels_MergeWithOrgLabels
  • TestListRepoLabels_IncludeOrgFalseSkipsOrgCall
  • TestListRepoLabels_UserOwnerOrgEndpoint404

go test ./... all green. make build green.

Test plan

  • go test ./... passes locally
  • make build passes locally
  • openspec validate add-org-label-support --strict passes
  • Manual smoke against an org-owned Codeberg repo: list_org_labels returns expected labels; list_repo_labels includes them with scope: "org"
  • Manual smoke against a user-owned repo: list_repo_labels returns repo labels only (no error from 404 on org endpoint)

Closes #125.

## Summary Implements the `add-org-label-support` OpenSpec change (already authored on `issues/125`, cherry-picked into this branch as commit `7b73057`). Closes [#125](https://codeberg.org/goern/forgejo-mcp/issues/125) — reporter wanted org-level labels visible to the MCP server so the model doesn't need to make two requests to discover usable label IDs. ## What - **New tool `list_org_labels(org, page, limit)`** — fetches `/orgs/{org}/labels` via `pkg/forgejo.DoJSONList`. No SDK upgrade required. - **`list_repo_labels` augmented** — new optional `include_org_labels` boolean (default `true`). When the owner is an org, the handler merges `/orgs/{owner}/labels` into the response. - **`ScopedLabel` wrapper** embeds `*forgejo_sdk.Label` and adds a `scope` field (`"repo"` | `"org"`) so callers can disambiguate ID spaces in merged responses. ## Behavior | Call | Behavior | |---|---| | `list_org_labels` on existing org | array of org labels, each `scope: "org"` | | `list_org_labels` on missing org | empty array (404 mapped by `DoJSONList`) | | `list_org_labels` with 401/403 | error wrapping `forgejo.ErrUnauthorized` | | `list_repo_labels` on org-owned repo | repo + org labels merged, each with `scope` | | `list_repo_labels` on user-owned repo | repo labels only (org endpoint 404 silently dropped) | | `list_repo_labels` with `include_org_labels=false` | repo labels only, no org request issued | ## Tests `operation/issue/issue_test.go` adds 6 tests via `newLabelsBackend` helper: - `TestListOrgLabels_Success` - `TestListOrgLabels_404IsEmpty` - `TestListOrgLabels_UnauthorizedSurfaces` - `TestListRepoLabels_MergeWithOrgLabels` - `TestListRepoLabels_IncludeOrgFalseSkipsOrgCall` - `TestListRepoLabels_UserOwnerOrgEndpoint404` `go test ./...` all green. `make build` green. ## Test plan - [x] `go test ./...` passes locally - [x] `make build` passes locally - [x] `openspec validate add-org-label-support --strict` passes - [ ] Manual smoke against an org-owned Codeberg repo: `list_org_labels` returns expected labels; `list_repo_labels` includes them with `scope: "org"` - [ ] Manual smoke against a user-owned repo: `list_repo_labels` returns repo labels only (no error from 404 on org endpoint) Closes #125.
op1st-gitops commented 2026-05-12 07:59:06 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/on-pull-request-ql465 is running.

Starting Pipelinerun on-pull-request-ql465 in namespace op1st-pipelines

You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:

tkn pr logs -n op1st-pipelines on-pull-request-ql465 -f

op1st Pipelines as Code/on-pull-request-ql465 is running. Starting Pipelinerun <b>[on-pull-request-ql465](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/on-pull-request-ql465)</b> in namespace <b>op1st-pipelines</b> You can monitor the execution using the [op1st Pipelines as Code](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/on-pull-request-ql465) PipelineRun viewer or through the command line by using the [tkn](https://tekton.dev/docs/cli/#installation) CLI with the following command: <code>tkn pr logs -n op1st-pipelines on-pull-request-ql465 -f</code>
op1st-gitops commented 2026-05-12 07:59:06 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/openspec-validate-pr-kjjqd is running.

Starting Pipelinerun openspec-validate-pr-kjjqd in namespace op1st-pipelines

You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:

tkn pr logs -n op1st-pipelines openspec-validate-pr-kjjqd -f

op1st Pipelines as Code/openspec-validate-pr-kjjqd is running. Starting Pipelinerun <b>[openspec-validate-pr-kjjqd](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/openspec-validate-pr-kjjqd)</b> in namespace <b>op1st-pipelines</b> You can monitor the execution using the [op1st Pipelines as Code](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/openspec-validate-pr-kjjqd) PipelineRun viewer or through the command line by using the [tkn](https://tekton.dev/docs/cli/#installation) CLI with the following command: <code>tkn pr logs -n op1st-pipelines openspec-validate-pr-kjjqd -f</code>
op1st-gitops commented 2026-05-12 07:59:38 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/openspec-validate-pr-kjjqd has successfully validated your commit.


Task Statuses:

StatusDurationName
Succeeded 12 seconds

fetch-source

Succeeded 20 seconds

validate

op1st Pipelines as Code/openspec-validate-pr-kjjqd has <b>successfully</b> validated your commit. <ul> <li><b>Namespace</b>: <a href="https://detailurl.setting.custom-console-url-namespace.is.not.configured">op1st-pipelines</a></li> <li><b>PipelineRun:</b> <a href="https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/openspec-validate-pr-kjjqd">openspec-validate-pr-kjjqd</a></li> </ul> <hr> <h4>Task Statuses:</h4> <table> <tr><th>Status</th><th>Duration</th><th>Name</th></tr> <tr> <td>Succeeded</td> <td>12 seconds</td><td> [fetch-source](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/openspec-validate-pr-kjjqd/logs/fetch-source) </td></tr> <tr> <td>Succeeded</td> <td>20 seconds</td><td> [validate](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/openspec-validate-pr-kjjqd/logs/validate) </td></tr> </table>
op1st-gitops commented 2026-05-12 08:00:09 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/on-pull-request-ql465 has successfully validated your commit.


Task Statuses:

StatusDurationName
Succeeded 11 seconds

fetch-source

Succeeded 50 seconds

build-and-test

op1st Pipelines as Code/on-pull-request-ql465 has <b>successfully</b> validated your commit. <ul> <li><b>Namespace</b>: <a href="https://detailurl.setting.custom-console-url-namespace.is.not.configured">op1st-pipelines</a></li> <li><b>PipelineRun:</b> <a href="https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/on-pull-request-ql465">on-pull-request-ql465</a></li> </ul> <hr> <h4>Task Statuses:</h4> <table> <tr><th>Status</th><th>Duration</th><th>Name</th></tr> <tr> <td>Succeeded</td> <td>11 seconds</td><td> [fetch-source](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/on-pull-request-ql465/logs/fetch-source) </td></tr> <tr> <td>Succeeded</td> <td>50 seconds</td><td> [build-and-test](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1beta1~PipelineRun/on-pull-request-ql465/logs/build-and-test) </td></tr> </table>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
agentic-forges/forgejo-mcp!130
No description provided.