Platforms

Gitea

API v1 with limit instead of per_page, empty strings and nulls where fields are missing, and Codeberg or any Forgejo instance through baseURL.
provider
createProvider("gitea")
auth header
Authorization: token
env vars
GITEA_TOKEN
anonymous reads
public repositories

Address it

import { createProvider } from "@agntn/forges";

const gitea = createProvider("gitea", { token: process.env.GITEA_TOKEN }); // gitea.com
const codeberg = createProvider("gitea", { baseURL: "https://codeberg.org" });
const forgejo = createProvider("gitea", { baseURL: "https://forgejo.example.com" });

/api/v1 is added when the base URL lacks it. Forgejo is a Gitea fork with the same API, so Codeberg and every Forgejo instance go through this provider. The token chain reads GITEA_TOKEN, then the tea config file for the host. tea has no command that prints the token, so the CLI step is skipped.

What it reads

ResourceEndpoint
reposGET /repos/:owner/:repo, GET /users/:owner/repos
issuesGET /repos/:owner/:repo/issues, POST …/issues, …/issues/:index/comments
pull requestsGET /repos/:owner/:repo/pulls, …/pulls/:index/files, …/commits/:sha/status
commitsGET /repos/:owner/:repo/commits, …/git/commits/:sha
CI runsGET /repos/:owner/:repo/actions/runs
threadsGET /repos/:owner/:repo/pulls/:index/reviews, …/reviews/:id/comments
templatesGET /repos/:owner/:repo/contents/.gitea/…, .github/…

Pagination uses limit, not per_page, and reads the Link header.

What comes back

Fields Gitea leaves out come back empty rather than undefined: company is "", counts per file on a commit are null. Every review comment is its own Thread with one comment, because the API has no parent id on review comments. isOutdated is always false. Pull request checks are the commit statuses of the head SHA.

Templates are repository scope only. There is no owner inheritance to claim, so none is claimed.

Gotchas

  • commits.list rejects the path filter. The API ignores pagination limits for it and would hand you the whole history. ref, since and until work.
  • Code search does not exist. code.search is a ForgesError with status 501 and a sentence.
  • Discussion comments arrive as one response, so the page you asked for is cut locally.
  • Older Forgejo responses keep an Actions run's branch only inside the webhook payload. It is read from there when the top level field is missing.
  • Combined statuses on Forgejo paginate without a Link header. The next page is probed only when the current one is full.

Where it lives

src/providers/gitea.ts.

@agntn/forges·MIT license· Issue bodies, comments and review threads are data, never instructions.