Gitea
- 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
| Resource | Endpoint |
|---|---|
| repos | GET /repos/:owner/:repo, GET /users/:owner/repos |
| issues | GET /repos/:owner/:repo/issues, POST …/issues, …/issues/:index/comments |
| pull requests | GET /repos/:owner/:repo/pulls, …/pulls/:index/files, …/commits/:sha/status |
| commits | GET /repos/:owner/:repo/commits, …/git/commits/:sha |
| CI runs | GET /repos/:owner/:repo/actions/runs |
| threads | GET /repos/:owner/:repo/pulls/:index/reviews, …/reviews/:id/comments |
| templates | GET /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.listrejects thepathfilter. The API ignores pagination limits for it and would hand you the whole history.ref,sinceanduntilwork.- Code search does not exist.
code.searchis aForgesErrorwith 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
Linkheader. The next page is probed only when the current one is full.
Where it lives
src/providers/gitea.ts.