Skip to content

Actions Extensions

Forgejo does not expose Actions run logs or detailed run metadata via its REST API. The proxy fills this gap by scraping the Forgejo web UI using an admin session and returning the data as JSON or plain text. The enriched jobs payload now includes job_index, attempt, log_url, html_url, and steps[] with human-readable durations.

MethodEndpointDescription
GET/api/v1/repos/{owner}/{repo}/actions/runs/latestGet info about the latest run
GET/api/v1/repos/{owner}/{repo}/actions/runs/latest/logsDownload logs for the latest run
GET/api/v1/repos/{owner}/{repo}/actions/runs/latest/jobsList jobs in the latest run
GET/api/v1/repos/{owner}/{repo}/actions/runs/latest/summarySummary of the latest run
POST/api/v1/repos/{owner}/{repo}/actions/runs/latest/rerunTrigger a rerun of the latest run
MethodEndpointDescription
GET/api/v1/repos/{owner}/{repo}/actions/runs/{run_number}/logsDownload logs for a specific run
GET/api/v1/repos/{owner}/{repo}/actions/runs/{run_number}/jobsList jobs in a specific run
GET/api/v1/repos/{owner}/{repo}/actions/runs/{run_number}/summarySummary of a specific run
POST/api/v1/repos/{owner}/{repo}/actions/runs/{run_number}/rerunTrigger a rerun of a specific run
ParameterDescription
ownerRepository owner (user or organisation name)
repoRepository name
run_numberThe sequential run counter visible in the Forgejo web UI URL (e.g., /actions/runs/42)
ParameterTypeDescription
jobstring | integerJob name (string) or 0-based job index (integer) within the run (default: 0)
attemptinteger1-based attempt number for the job (default: 1)
workflow_idstringFilter runs by workflow file name (e.g., ci.yml)
statusstringFilter runs by status — e.g., success, failure, running, waiting

The GET .../actions/runs endpoint supports workflow_id and status query parameters to narrow results:

Terminal window
# List all runs for a specific workflow
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs?workflow_id=ci.yml'
# List only failed runs
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs?status=failure'
# Combine filters
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs?workflow_id=ci.yml&status=failure'

Use workflow_id with the latest endpoint to get the most recent run of a specific workflow:

Terminal window
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs/latest?workflow_id=ci.yml'
Terminal window
# Download logs for the latest run
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs/latest/logs'
# Download logs for run #42 by job name
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs/42/logs?job=build'
# Download logs for run #42 by job index (second job)
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs/42/logs?job=1'
# List jobs in the latest run filtered by workflow
curl -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs/latest/jobs?workflow_id=ci.yml'
# Rerun the latest failed run
curl -X POST -H 'Authorization: token $TOKEN' \
'https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs/latest/rerun'

Each item from .../jobs is enriched beyond the native Forgejo REST payload:

FieldMeaning
job_index0-based position of the job within the run
attemptretry attempt number for the job (1 = first attempt)
log_urlproxy URL for the raw job logs
html_urlupstream Forgejo job-attempt page used to extract step data
steps[]ordered UI step summaries with summary, status, and optional duration

Example:

[
{
"id": 91,
"name": "build",
"status": "failure",
"job_index": 1,
"attempt": 2,
"log_url": "https://forgejo-proxy.hochguertel.work/api/v1/repos/myorg/myrepo/actions/runs/42/logs?job=1&attempt=2",
"html_url": "https://pastoral-oyster.pikapod.net/myorg/myrepo/actions/runs/42/jobs/91?attempt=2",
"steps": [
{ "summary": "Set up job", "status": "success", "duration": "2s" },
{ "summary": "Run tests", "status": "failure", "duration": "26s" }
]
}
]

The job query parameter used by the logs endpoint accepts the same job_index value or the job name, so you can jump straight from the jobs payload to the matching log stream. The CLI’s thfg run performance command uses this same enriched payload.

The proxy authenticates to the Forgejo web UI using an admin session cookie. When a request comes in:

  1. The user token is validated against Forgejo’s standard API to confirm read access to the repo
  2. The proxy uses its admin session to fetch the run page or log file from the web UI
  3. The scraped data is normalized and returned as JSON (or plain text for logs)
  4. For jobs, the proxy reads the job-attempt page payload to attach per-step status and duration data