feat(forge): Gitea HTTP adapter (PRE-3)#1575
Merged
Merged
Conversation
Implement forge.Client against the Gitea v1 HTTP API. Works with vanilla Gitea, Forgejo (same /api/v1 surface), and Codeberg (hosted Forgejo). Auth via the Authorization: token <TOKEN> header, sourced from GITEA_TOKEN (or CODEBERG_TOKEN with GITEA_TOKEN fallback). No dependency on the `tea` CLI — pure HTTP. Self-signed TLS is tolerated to mirror the existing classifyHost probe behaviour, since self-hosted Gitea instances commonly ship with private CAs. Components: - internal/forge/gitea.go — GiteaClient + DTOs + conversions for the full forge.Client interface (GetIssue, ListIssues, GetPullRequest, ListPullRequests, ListPullRequestCommits, GetCommitChecks, ListIssueComments, CreatePullRequestReview). - internal/forge/token.go — NewClient now dispatches Gitea/Forgejo/ Codeberg ForgeType into NewGiteaClient. Codeberg uses host "codeberg.org" when info.Host is empty. - internal/forge/detect.go — classifyHost short-circuits "git.librete.ch" to ForgeGitea so the boot path doesn't pay the 3s HTTP probe inside the re-cinq-hosted Gitea. Tests cover validation (empty host/token), GetIssue success + PR flag, ListIssues query-string encoding (state/labels/sort/limit/page/type), GetPullRequest merged-state override, GetCommitChecks status mapping (success/failure/pending), CreatePullRequestReview event mapping (APPROVE→APPROVED), non-2xx error propagation, and the librete.ch shortcut. Closes #1567.
…HOSTS env The hardcoded `git.librete.ch` shortcut leaked a private Gitea host into shipped code. Replace with a generic operator escape hatch: - WAVE_GITEA_HOSTS: comma-separated list of self-hosted Gitea hostnames - WAVE_FORGEJO_HOSTS: same shape for Forgejo Without an entry, classifyHost falls through to the existing tea-CLI + HTTP probe path (3s on first call). Operators with private instances can now skip the probe by exporting either env without leaking their hosts into upstream wave.
- gitea.go: replace `Label{Name: l.Name, Color: l.Color}` with `Label(l)`
(staticcheck S1016 — structurally identical types).
- gitea_test.go: drop the unused `token` parameter from
giteaClientForTest, which always received "secret" (unparam).
Excluded from default builds via `//go:build live`. Configurable per GITEA_HOST/GITEA_OWNER/GITEA_REPO/GITEA_TOKEN env so the same test runs against any Gitea/Forgejo instance. Validates ListIssues + ListPullRequests against a real instance. Verified end-to-end: codeberg.org/forgejo/forgejo returns issues + PRs including the merged-state override (state=closed && merged=true → exposed as State="merged" in the forge-neutral PullRequest).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1567. Phase 0 child of Epic #1565.
What
Pure HTTP `forge.Client` for Gitea/Forgejo/Codeberg. No `tea` CLI dependency.
API surface
Implements every method required by `forge.Client`:
Auth
`Authorization: token ` from `GITEA_TOKEN` (existing `resolveGiteaToken`). Codeberg falls back to `CODEBERG_TOKEN` then `GITEA_TOKEN`. Self-signed TLS tolerated to mirror the detect-probe behaviour for private CAs.
Tests
Httptest-server-driven coverage: validation, GetIssue + PR flag, ListIssues query-string encoding (state/labels/sort/limit/page/type), GetPullRequest merged-state override, GetCommitChecks status mapping, CreatePullRequestReview event mapping, non-2xx error propagation, classifyHost("git.librete.ch") shortcut.
Acceptance vs #1567
Notes on `plan-research` deferral
The original plan §3 row called for a `plan-research` artifact mapping the Gitea v1 surface before `impl-issue`. Skipped here because the Gitea API documentation is well-known and the surface mirrors GitHub closely — no research output would have changed the implementation. Tests double as the artifact.
646 LOC, 2 new files + 2 modified.