Adds a comprehensive opencode skill under .opencode/skills/forgejo-api/
covering all 473 Forgejo REST API endpoints across 25 reference categories.
- 78 files, 23,000+ lines, 149 distinct path parameter types
- Every curl command parameterised ({owner}/{repo}/{index}/etc) and
tested against the live git.cleverthis.com server
- SKILL.md: 917-line entry point with quick-answer curl commands (35),
jq cheat sheet for chaining API calls, 14 decision trees, 12 critical
concepts (exclusive labels, lazy mergeability, SHA locking, auto-close
keywords, search envelope differences, 412 stale-edit protection), full
HTTP status code table, and environment variable reference
- references/pull-requests/: CRUD, 6 merge styles, automerge, server-side
rebase without local clone, inline review comments, diff/patch
- references/issues/: comments, reactions, attachments, dependencies,
time tracking, stopwatches, pinning
- references/labels/: repo + org labels, exclusive label groups,
GET/POST/PUT/DELETE on issues and PRs
- references/ci-actions/ + references/commit-statuses/: workflow runs,
dispatch, secrets, variables, quality gate verification
- references/web-interface/ci-logs.md: step-by-step CI log access via
CSRF web session (not available through REST API)
- references/complex-workflows/: 10 multi-step recipes including
PR review cycle, issue lifecycle, CI status check, server-side rebase,
automerge, release workflow, org setup, fork contribution
Commit Statuses
Commit statuses allow external services (CI systems, linters, security scanners) to mark commits with a state. They are the primary mechanism for checking whether CI has passed on a branch or pull request.
Endpoints
Get Combined Status
GET /repos/{owner}/{repo}/commits/{ref}/status
Returns a single combined status that aggregates all individual statuses for the given ref. The ref can be a branch name, tag name, or commit SHA.
The combined state follows these rules:
successif all statuses aresuccess(or no statuses exist)pendingif any status ispendingfailureif any status isfailureerrorif any status iserrorwarningif any status iswarning(and no failure/error)
List Individual Statuses
GET /repos/{owner}/{repo}/commits/{ref}/statuses
Query parameters:
sort(string) - Sort by:oldest,recentupdate,leastupdate,leastindex,highestindexstate(string) - Filter by state:pending,success,error,failure,warningpage(int) - Page number (1-based)limit(int) - Page size
Create Commit Status
POST /repos/{owner}/{repo}/statuses/{sha}
Note: This endpoint uses /statuses/{sha} (not /commits/{ref}/statuses).
Combined Status Response
{
"state": "success",
"statuses": [
{
"id": 1,
"context": "CI / build",
"status": "success",
"description": "Build passed",
"target_url": "https://ci.example.com/builds/123",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:35:00Z",
"creator": { "login": "{username}" }
},
{
"id": 2,
"context": "CI / test",
"status": "success",
"description": "All tests passed",
"target_url": "https://ci.example.com/builds/124",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:36:00Z",
"creator": { "login": "{username}" }
}
],
"total_count": 2,
"sha": "abc123def456",
"commit_url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/commits/{sha}",
"repository": { "id": 1, "full_name": "owner/repo" },
"url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/commits/{sha}/status"
}
Alternative Status Endpoints (by SHA directly)
In addition to the /commits/{ref}/... endpoints above, there are equivalent endpoints under /statuses/{sha}:
GET /repos/{owner}/{repo}/statuses/{sha}
Lists commit statuses by SHA directly (same as GET /commits/{sha}/statuses but uses a different URL path). Parameters are the same: sort, state, page, limit.
POST /repos/{owner}/{repo}/statuses/{sha}
Creates a commit status (same as using the /commits/ path). Body is CreateStatusOption.
# List statuses via /statuses/{sha}
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/statuses/${SHA}?limit=10" \
-H "Authorization: token ${FORGEJO_PAT}"
# Create status via /statuses/{sha}
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/statuses/${SHA}" \
-H "Authorization: token ${FORGEJO_PAT}" \
-H "Content-Type: application/json" \
-d '{"state": "success", "context": "my-check", "description": "Check passed"}'
Note: Both URL patterns (
/commits/{ref}/statusesand/statuses/{sha}) work identically. The/commits/{ref}version additionally accepts branch names and tag names as{ref}, while/statuses/{sha}requires the full commit SHA.
Individual Status Fields
| Field | Type | Description |
|---|---|---|
id |
int | Unique status identifier |
context |
string | Status name (e.g., "CI / build", "security/scan") |
status / state |
string | pending, success, error, failure, warning |
description |
string | Human-readable description |
target_url |
string | URL linking to the CI job or details page |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |
creator |
object | User who created the status |
CreateStatusOption (POST Body)
{
"state": "success",
"context": "CI / build",
"description": "Build completed successfully",
"target_url": "https://ci.example.com/builds/123"
}
| Field | Type | Required | Description |
|---|---|---|---|
state |
string | Yes | pending, success, error, failure, warning |
context |
string | No | Name for the status check (e.g., "CI / build"). Defaults to "default" |
description |
string | No | Short description of the status |
target_url |
string | No | URL to link to (usually the CI job page) |
If you POST a status with the same context as an existing status, it updates that context rather than creating a duplicate.
Use Cases
Check CI Quality Gates
Get the combined status for a PR's head SHA to determine if CI has passed:
# Get the PR to find the head SHA
HEAD_SHA=$(curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}" | jq -r '.head.sha')
# Check combined status
curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/${HEAD_SHA}/status" | jq '.state'
Create Custom Status Checks
Mark custom quality gates (linting, security scans, deploy previews, etc.):
# Post a custom status
curl -s -X POST \
-H "Authorization: token ${FORGEJO_PAT}" \
-H "Content-Type: application/json" \
-d '{
"state": "success",
"context": "security/trivy-scan",
"description": "No vulnerabilities found",
"target_url": "https://security.example.com/scan/456"
}' \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/statuses/{sha}"
Integration with Branch Protection
Branch protection rules can require specific status checks to pass before merging. The status_check_contexts field in branch protection references the context names from commit statuses.
Curl Examples
1. Get Combined Status for a Branch
curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/{branch}/status" | jq '{state, total_count}'
2. Get Combined Status for a PR's Head Commit
# First get the PR
HEAD_SHA=$(curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}" | jq -r '.head.sha')
# Then get the status
curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/${HEAD_SHA}/status"
3. List All Individual Statuses
# List all statuses for a commit
curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/{sha}/statuses"
# Filter by state
curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/{sha}/statuses?state=failure"
# With pagination
curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/{sha}/statuses?page=1&limit=20"
4. Create a Pending Status
curl -s -X POST \
-H "Authorization: token ${FORGEJO_PAT}" \
-H "Content-Type: application/json" \
-d '{
"state": "pending",
"context": "CI / build",
"description": "Build is running...",
"target_url": "https://ci.example.com/builds/789"
}' \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/statuses/{sha}"
5. Update to Success or Failure
# Mark as success (same context updates the existing status)
curl -s -X POST \
-H "Authorization: token ${FORGEJO_PAT}" \
-H "Content-Type: application/json" \
-d '{
"state": "success",
"context": "CI / build",
"description": "Build passed in 2m 34s",
"target_url": "https://ci.example.com/builds/789"
}' \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/statuses/{sha}"
# Or mark as failure
curl -s -X POST \
-H "Authorization: token ${FORGEJO_PAT}" \
-H "Content-Type: application/json" \
-d '{
"state": "failure",
"context": "CI / build",
"description": "Build failed: test suite errors",
"target_url": "https://ci.example.com/builds/789"
}' \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/statuses/{sha}"
6. Using Status Checks with Branch Protection
# First, create status checks on commits (as shown above)
# Then reference those context names in branch protection settings.
#
# When creating/updating branch protection, include:
# "status_check_contexts": ["CI / build", "CI / test", "security/trivy-scan"]
#
# This ensures PRs cannot be merged until all listed contexts report success.
#
# Check current branch protection:
curl -s -H "Authorization: token ${FORGEJO_PAT}" \
"${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/branch_protections" | \
jq '.[].status_check_contexts'