feat(actions): add list_workflow_run_jobs and get_workflow_run_job_logs #126

Closed
dmikushin wants to merge 0 commits from refs/pull/126/head into main
dmikushin commented 2026-05-10 14:01:03 +00:00 (Migrated from codeberg.org)

Problem

forgejo-mcp exposes 51 tools today but nothing for "show me what a CI job actually printed". The actions group covers run listing (list_workflow_runs), single-run details (get_workflow_run), and dispatching (dispatch_workflow), but to debug a failing run an LLM (or any caller) has to either render the run-page HTML and parse it or SSH to the Forgejo host and decompress *.log.zst by hand. Both are awkward and the second one is impossible for cloud-hosted instances.

Change

Two new tools in operation/actions/:

  • list_workflow_run_jobs wraps GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs. That endpoint landed upstream in forgejo#11915 but isn't yet covered by the SDK we vendor (codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2).
  • get_workflow_run_job_logs wraps GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs/{job_index}/logs. That endpoint is proposed upstream in forgejo#12508. The tool accepts an optional tail parameter trimming output to the last N characters — Qt/Chromium-class logs can run to tens of MB and the diagnostic line is almost always at the end, so this keeps responses well below MCP's message size limit without needing a streaming protocol.

Both tools bypass the SDK and issue plain HTTP against flag.URL with the same flag.Token the SDK uses, so they work on any Forgejo instance that exposes those routes (current dev branch / v16+ for jobs, fork-or-v16+-with-#12508 for logs). When the SDK gains coverage we should switch to the typed methods — see the comment at the top of operation/actions/jobs.go.

Test plan

Manual against a Forgejo dev-branch instance carrying both endpoints:

$ forgejo-mcp ... 2>/dev/null &
$ # via the MCP host:
list_workflow_run_jobs(owner=eyetracking, repo=cameraview, run_id=824)
# → JSON array of {id, name, status, task_id, runs_on, …} for each job
get_workflow_run_job_logs(owner=eyetracking, repo=cameraview, run_id=824, job_index=1, tail=4000)
# → last 4 KB of release-linux's plain-text log, with a "[truncated…]" marker

Edge cases observed manually: nonexistent run_id and out-of-range job_index both surface the upstream Forgejo 404 verbatim through to.ErrorResult, which is what the LLM needs.

Files touched

  • operation/actions/actions.go — register the two tools in RegisterTool.
  • operation/actions/jobs.go — new file with both tool definitions, handlers, and a small rawAPIRequest helper for the SDK-bypass.

No SDK bump, no other tool changes.

## Problem `forgejo-mcp` exposes 51 tools today but nothing for "show me what a CI job actually printed". The `actions` group covers run listing (`list_workflow_runs`), single-run details (`get_workflow_run`), and dispatching (`dispatch_workflow`), but to debug a failing run an LLM (or any caller) has to either render the run-page HTML and parse it or SSH to the Forgejo host and decompress `*.log.zst` by hand. Both are awkward and the second one is impossible for cloud-hosted instances. ## Change Two new tools in `operation/actions/`: - **`list_workflow_run_jobs`** wraps `GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs`. That endpoint landed upstream in [forgejo#11915](https://codeberg.org/forgejo/forgejo/pulls/11915) but isn't yet covered by the SDK we vendor (`codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2`). - **`get_workflow_run_job_logs`** wraps `GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs/{job_index}/logs`. That endpoint is proposed upstream in [forgejo#12508](https://codeberg.org/forgejo/forgejo/pulls/12508). The tool accepts an optional `tail` parameter trimming output to the last N characters — Qt/Chromium-class logs can run to tens of MB and the diagnostic line is almost always at the end, so this keeps responses well below MCP's message size limit without needing a streaming protocol. Both tools bypass the SDK and issue plain HTTP against `flag.URL` with the same `flag.Token` the SDK uses, so they work on any Forgejo instance that exposes those routes (current dev branch / v16+ for jobs, fork-or-v16+-with-#12508 for logs). When the SDK gains coverage we should switch to the typed methods — see the comment at the top of `operation/actions/jobs.go`. ## Test plan Manual against a Forgejo dev-branch instance carrying both endpoints: ```bash $ forgejo-mcp ... 2>/dev/null & $ # via the MCP host: list_workflow_run_jobs(owner=eyetracking, repo=cameraview, run_id=824) # → JSON array of {id, name, status, task_id, runs_on, …} for each job get_workflow_run_job_logs(owner=eyetracking, repo=cameraview, run_id=824, job_index=1, tail=4000) # → last 4 KB of release-linux's plain-text log, with a "[truncated…]" marker ``` Edge cases observed manually: nonexistent `run_id` and out-of-range `job_index` both surface the upstream Forgejo 404 verbatim through `to.ErrorResult`, which is what the LLM needs. ## Files touched - `operation/actions/actions.go` — register the two tools in `RegisterTool`. - `operation/actions/jobs.go` — new file with both tool definitions, handlers, and a small `rawAPIRequest` helper for the SDK-bypass. No SDK bump, no other tool changes.
goern commented 2026-05-10 14:06:35 +00:00 (Migrated from codeberg.org)

Assessment

Direction is right — debugging CI without log access is exactly the gap. list_workflow_run_jobs targets the merged upstream endpoint (forgejo#11915, v16+) and is mergeable. get_workflow_run_job_logs targets the proposed endpoint (forgejo#12508, not yet merged); shipping a tool against unstable upstream surface risks rework or removal. PR also lacks automated tests despite the project's httptest.Server patterns in pkg/forgejo/*_test.go, the new rawAPIRequest helper duplicates pkg/forgejo.DoJSONList, and the README tool table is not updated. The tail parameter overlaps with the uniform output-bounding policy tracked in #124 and should align with whatever naming lands there.

Requested changes before merge

  1. Split the PR. Land list_workflow_run_jobs now. Defer get_workflow_run_job_logs until forgejo#12508 merges — don't ship against speculative upstream API surface.
  2. Reuse pkg/forgejo.DoJSONList instead of the new rawAPIRequest helper. Avoids two raw-HTTP code paths drifting (auth/UA/logging).
  3. Add tests in the pkg/forgejo/*_test.go httptest.Server style: happy path, 404, tail truncation marker, out-of-range job_index.
  4. Update README tool table for both tools (cf. #124 — same gap noted there).
  5. Align tail with #124 policy. That issue is the umbrella for uniform output-bounding (line range, byte range, paging). Coordinate naming with whatever convention lands there (e.g. tail_bytes/max_bytes + truncation marker rather than ambiguous tail).
  6. When the SDK gains typed coverage for these endpoints, switch off raw HTTP. Replace the free-text note with a TODO referencing the SDK issue.

Verdict

Valid feature, accept after revisions. Splitting is mandatory; the rest is polish + alignment with the bounding policy in #124.

## Assessment Direction is right — debugging CI without log access is exactly the gap. `list_workflow_run_jobs` targets the merged upstream endpoint (forgejo#11915, v16+) and is mergeable. `get_workflow_run_job_logs` targets the **proposed** endpoint (forgejo#12508, not yet merged); shipping a tool against unstable upstream surface risks rework or removal. PR also lacks automated tests despite the project's `httptest.Server` patterns in `pkg/forgejo/*_test.go`, the new `rawAPIRequest` helper duplicates `pkg/forgejo.DoJSONList`, and the README tool table is not updated. The `tail` parameter overlaps with the uniform output-bounding policy tracked in #124 and should align with whatever naming lands there. ## Requested changes before merge 1. **Split the PR.** Land `list_workflow_run_jobs` now. Defer `get_workflow_run_job_logs` until forgejo#12508 merges — don't ship against speculative upstream API surface. 2. **Reuse `pkg/forgejo.DoJSONList`** instead of the new `rawAPIRequest` helper. Avoids two raw-HTTP code paths drifting (auth/UA/logging). 3. **Add tests** in the `pkg/forgejo/*_test.go` `httptest.Server` style: happy path, 404, `tail` truncation marker, out-of-range `job_index`. 4. **Update README** tool table for both tools (cf. #124 — same gap noted there). 5. **Align `tail` with #124 policy.** That issue is the umbrella for uniform output-bounding (line range, byte range, paging). Coordinate naming with whatever convention lands there (e.g. `tail_bytes`/`max_bytes` + truncation marker rather than ambiguous `tail`). 6. When the SDK gains typed coverage for these endpoints, switch off raw HTTP. Replace the free-text note with a `TODO` referencing the SDK issue. ## Verdict Valid feature, accept after revisions. Splitting is mandatory; the rest is polish + alignment with the bounding policy in #124.
goern commented 2026-05-10 14:26:09 +00:00 (Migrated from codeberg.org)

Follow-up to my earlier review: the bounding policy is now codified at docs/design/output-bounding.md and referenced from AGENTS.md. Concrete asks for this PR using the checklist there:

  1. list_workflow_run_jobs — list-of-entities row in the parameter table: add page + limit parameters; surface total_count or has_next in the response so callers can resume.
  2. get_workflow_run_job_logs — log-stream row: rename tailtail_bytes per the parameter vocabulary; replace the existing free-text [truncated…] with a structured marker [truncated, N more bytes] so callers can tell exact tail position.
  3. PR description: please answer the checklist (item 5 of the new "Adding a New Tool" steps in AGENTS.md).

No new requests beyond what's already in the original review — this is just the canonical reference to point at.

Follow-up to my earlier review: the bounding policy is now codified at [`docs/design/output-bounding.md`](https://codeberg.org/goern/forgejo-mcp/src/branch/main/docs/design/output-bounding.md) and referenced from `AGENTS.md`. Concrete asks for this PR using the checklist there: 1. **`list_workflow_run_jobs`** — list-of-entities row in the parameter table: add `page` + `limit` parameters; surface `total_count` or `has_next` in the response so callers can resume. 2. **`get_workflow_run_job_logs`** — log-stream row: rename `tail` → `tail_bytes` per the parameter vocabulary; replace the existing free-text `[truncated…]` with a structured marker `[truncated, N more bytes]` so callers can tell exact tail position. 3. PR description: please answer the checklist (item 5 of the new "Adding a New Tool" steps in `AGENTS.md`). No new requests beyond what's already in the original review — this is just the canonical reference to point at.
goern commented 2026-06-04 09:56:11 +00:00 (Migrated from codeberg.org)

/test

/test
op1st-gitops commented 2026-07-25 21:27:49 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code is skipping this commit.
User dmikushin is not allowed to trigger CI via pull_request_closed in this repo.

op1st Pipelines as Code is skipping this commit. User dmikushin is not allowed to trigger CI via pull_request_closed in this repo.

Pull request closed

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!126
No description provided.