Files
CleverAgents Build Agent 237e776951
CI / lint (push) Successful in 20s
CI / quality (push) Successful in 20s
CI / helm (push) Successful in 24s
CI / build (push) Successful in 24s
CI / push-validation (push) Successful in 39s
CI / security (push) Successful in 1m1s
CI / e2e_tests (push) Successful in 3m13s
CI / typecheck (push) Successful in 4m23s
CI / unit_tests (push) Successful in 6m44s
CI / integration_tests (push) Successful in 6m49s
CI / docker (push) Successful in 11s
CI / coverage (push) Successful in 6m56s
CI / status-check (push) Successful in 0s
feat(skills): add exhaustive Forgejo REST API agent skill
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
2026-04-15 00:45:24 -04:00
..

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:

  • success if all statuses are success (or no statuses exist)
  • pending if any status is pending
  • failure if any status is failure
  • error if any status is error
  • warning if any status is warning (and no failure/error)

List Individual Statuses

GET /repos/{owner}/{repo}/commits/{ref}/statuses

Query parameters:

  • sort (string) - Sort by: oldest, recentupdate, leastupdate, leastindex, highestindex
  • state (string) - Filter by state: pending, success, error, failure, warning
  • page (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}/statuses and /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'