You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature]: add forgejo support - minor modifications needed #1777
I searched existing issues and docs before opening this.
This proposal is grounded in a real Roomote use case, not a broad generated feature list.
Problem
The docs list Gitea as a supported source control provider, but I couldn't find anything about Forgejo. Since Forgejo is a hard fork and the API has diverged in places, I'd rather ask than assume.
Has anyone got this working against Forgejo, or is the connector tested against Gitea only?
Current workaround
None — currently not using Roomote for this reason.
I've analyzed this issue and here's my proposed implementation plan:
Treat Forgejo as a tested compatibility target of the existing Gitea provider rather than adding a separate persisted provider ID. Roomote already routes self-hosted instances through GITEA_BASE_URL, /api/v1, and the shared Gitea repository/credential/webhook paths, so retaining sourceControlProvider: "gitea" avoids duplicating the provider stack.
Add Forgejo contract fixtures and tests around packages/gitea/src/api.ts, packages/gitea/src/oauth.ts, and packages/gitea/src/ci.ts for OAuth authorization/refresh, repository pagination, issue/PR comments, webhook list/create/update, and Actions APIs. Use a currently supported Forgejo release as the initial compatibility floor and add narrow response normalization or endpoint fallbacks only where those tests identify an actual divergence.
Add representative Forgejo webhook coverage in apps/api/src/handlers/gitea/__tests__/ for signature/event headers and PR, issue/comment, and workflow payloads. Preserve the existing Gitea behavior while accepting any Forgejo-specific header or payload differences found during verification.
Exercise the shared pull-request operations in packages/sdk/src/server/lib/pull-requests/ against Forgejo contracts: listing/reading PRs, creating or updating a PR, posting top-level and inline review comments, and reporting unsupported capabilities honestly.
Update setup copy in apps/web/src/app/(onboarding)/setup/ and the public guide at apps/docs/providers/source-control/gitea.mdx to label the connector as Gitea/Forgejo-compatible, document Forgejo OAuth application setup and permissions, state the tested Forgejo version range, and include a verification checklist covering connect, sync, clone, webhook delivery, PR/issue mentions, review automation, and optional Actions triage.
This approach gives Forgejo explicit, test-backed support without introducing a second provider whose storage, routing, and API implementation would largely duplicate Gitea. It also keeps any future fork-specific behavior isolated behind compatibility handling in the existing adapter.
Please tag @roomote if you'd like me to implement this, or reply with feedback on the plan.
This was verified end-to-end with AI (Claude), by standing up a real self-hosted Roomote instance against a real, locally-run Forgejo instance and driving the actual OAuth2 flow through a real browser — not simulated calls.
Setup: self-hosted Roomote app (ghcr.io/roocodeinc/roomote-app, built from main commit 614cc125), Forgejo 16.0.3 with Actions enabled and a registered act_runner (13.1.0) executing real workflow runs (success and failure), full browser-driven OAuth2 authorization-code flow (including refresh token) against Forgejo's /login/oauth/* endpoints.
What works: repo listing/sync, PR and issue API calls (create PR, create review), the OAuth2 flow itself, webhook signature verification, and the push/issue/PR events in GITEA_WEBHOOK_EVENTS all work against Forgejo out of the box — Forgejo's Gitea-compatible /api/v1 surface matches what the gitea provider expects.
Two concrete, verified incompatibilities (checked against current main, commit 614cc125):
Forgejo does have Actions-completion webhooks since v12.0 (forgejo/forgejo#7508, merged 2025-06-03) — but under different names and a different hook type than what Roomote requests. Forgejo's events are action_run_failure, action_run_success, and action_run_recover (payload field run, not workflow_run), delivered only when the hook is created with "type": "forgejo". Roomote's Gitea provider hard-codes workflow_run in GITEA_WEBHOOK_EVENTS and type: 'gitea' (packages/gitea/src/api.ts:913), so it matches neither the event name nor the hook type Forgejo actually uses. Note that action_run_recover specifically is a bad target to map to anyway: its underlying "run recovered" detection has been broken since v12.0.0 (compares unrelated workflow runs across the whole repo, forgejo/forgejo#8373) and Forgejo is removing it entirely in v17.0.0 (forgejo/forgejo#13883) for lack of use/well-defined semantics. Roomote doesn't need it either — its model expects a single completion event carrying a conclusion (success/failure/etc.), not a separate "recovered" state — so a fix only needs to target action_run_failure and action_run_success, which is what was actually confirmed delivered with a real payload; action_run_recover was only confirmed to be accepted as a hook event name, not to fire.
GET /repos/{owner}/{repo}/actions/runs/{id}/jobs returns a bare array on Forgejo instead of { jobs: [...] }. Running the real response through Roomote's own giteaActionWorkflowJobListSchema (same zod version) throws Expected object, received array, and that error is silently swallowed — so CI job logs/failure evidence are never retrievable for Forgejo. Separately, GET /repos/{owner}/{repo}/actions/runs/{id} doesn't return head_sha on Forgejo (it's called commit_sha there), so ciFailureTriageJob falls back to the literal string "unknown" and can't identify the failing commit.
Mitigating factor: the daily ciFailureTriageJob poll (packages/sdk/src/server/automations/ci-failure-triage.ts) works independently of webhooks via REST polling, so the missing CI webhook by itself would only mean delayed (not missing) CI triage — except issue 2 above breaks that path too for Forgejo specifically.
Happy to share the exact repro steps/commands if useful.
changed the title [-]Does the Gitea source control integration work with Forgejo?[/-][+][Feature]: add forgejo support - minor modifications needed[/+]on Sep 1, 2026
Follow-up: I found and fixed one additional Forgejo compatibility bug in our fork.
Forgejo can return "assignees": null for an existing unassigned pull request. Roomote validates the existing PR before updating it and required an array, so PR creation/update failed with HTTP 400 before the write request. The fix accepts the nullable response and normalizes it through the existing empty-assignee path; it is covered by a regression test.
Activity
roomote-community commentedon Aug 28, 2026
I've analyzed this issue and here's my proposed implementation plan:
GITEA_BASE_URL,/api/v1, and the shared Gitea repository/credential/webhook paths, so retainingsourceControlProvider: "gitea"avoids duplicating the provider stack.packages/gitea/src/api.ts,packages/gitea/src/oauth.ts, andpackages/gitea/src/ci.tsfor OAuth authorization/refresh, repository pagination, issue/PR comments, webhook list/create/update, and Actions APIs. Use a currently supported Forgejo release as the initial compatibility floor and add narrow response normalization or endpoint fallbacks only where those tests identify an actual divergence.apps/api/src/handlers/gitea/__tests__/for signature/event headers and PR, issue/comment, and workflow payloads. Preserve the existing Gitea behavior while accepting any Forgejo-specific header or payload differences found during verification.packages/sdk/src/server/lib/pull-requests/against Forgejo contracts: listing/reading PRs, creating or updating a PR, posting top-level and inline review comments, and reporting unsupported capabilities honestly.apps/web/src/app/(onboarding)/setup/and the public guide atapps/docs/providers/source-control/gitea.mdxto label the connector as Gitea/Forgejo-compatible, document Forgejo OAuth application setup and permissions, state the tested Forgejo version range, and include a verification checklist covering connect, sync, clone, webhook delivery, PR/issue mentions, review automation, and optional Actions triage.This approach gives Forgejo explicit, test-backed support without introducing a second provider whose storage, routing, and API implementation would largely duplicate Gitea. It also keeps any future fork-specific behavior isolated behind compatibility handling in the existing adapter.
Please tag @roomote if you'd like me to implement this, or reply with feedback on the plan.
MrGeorgen commentedon Sep 1, 2026
This was verified end-to-end with AI (Claude), by standing up a real self-hosted Roomote instance against a real, locally-run Forgejo instance and driving the actual OAuth2 flow through a real browser — not simulated calls.
Setup: self-hosted Roomote app (
ghcr.io/roocodeinc/roomote-app, built frommaincommit614cc125), Forgejo 16.0.3 with Actions enabled and a registeredact_runner(13.1.0) executing real workflow runs (success and failure), full browser-driven OAuth2 authorization-code flow (including refresh token) against Forgejo's/login/oauth/*endpoints.What works: repo listing/sync, PR and issue API calls (create PR, create review), the OAuth2 flow itself, webhook signature verification, and the
push/issue/PR events inGITEA_WEBHOOK_EVENTSall work against Forgejo out of the box — Forgejo's Gitea-compatible/api/v1surface matches what thegiteaprovider expects.Two concrete, verified incompatibilities (checked against current
main, commit614cc125):Forgejo does have Actions-completion webhooks since v12.0 (forgejo/forgejo#7508, merged 2025-06-03) — but under different names and a different hook type than what Roomote requests. Forgejo's events are
action_run_failure,action_run_success, andaction_run_recover(payload fieldrun, notworkflow_run), delivered only when the hook is created with"type": "forgejo". Roomote's Gitea provider hard-codesworkflow_runinGITEA_WEBHOOK_EVENTSandtype: 'gitea'(packages/gitea/src/api.ts:913), so it matches neither the event name nor the hook type Forgejo actually uses. Note thataction_run_recoverspecifically is a bad target to map to anyway: its underlying "run recovered" detection has been broken since v12.0.0 (compares unrelated workflow runs across the whole repo, forgejo/forgejo#8373) and Forgejo is removing it entirely in v17.0.0 (forgejo/forgejo#13883) for lack of use/well-defined semantics. Roomote doesn't need it either — its model expects a single completion event carrying aconclusion(success/failure/etc.), not a separate "recovered" state — so a fix only needs to targetaction_run_failureandaction_run_success, which is what was actually confirmed delivered with a real payload;action_run_recoverwas only confirmed to be accepted as a hook event name, not to fire.GET /repos/{owner}/{repo}/actions/runs/{id}/jobsreturns a bare array on Forgejo instead of{ jobs: [...] }. Running the real response through Roomote's owngiteaActionWorkflowJobListSchema(same zod version) throwsExpected object, received array, and that error is silently swallowed — so CI job logs/failure evidence are never retrievable for Forgejo. Separately,GET /repos/{owner}/{repo}/actions/runs/{id}doesn't returnhead_shaon Forgejo (it's calledcommit_shathere), sociFailureTriageJobfalls back to the literal string"unknown"and can't identify the failing commit.Mitigating factor: the daily
ciFailureTriageJobpoll (packages/sdk/src/server/automations/ci-failure-triage.ts) works independently of webhooks via REST polling, so the missing CI webhook by itself would only mean delayed (not missing) CI triage — except issue 2 above breaks that path too for Forgejo specifically.Happy to share the exact repro steps/commands if useful.
[-]Does the Gitea source control integration work with Forgejo?[/-][+][Feature]: add forgejo support - minor modifications needed[/+]MrGeorgen commentedon Sep 8, 2026
@roomote implement it using the observation above
roomote-community commentedon Sep 8, 2026
I saw the mention, but I need your GitHub account linked to Roomote before issue and PR comments can start work here. Link it from Settings -> Linked Accounts and then mention me again. If you'd like an invite to join the community Roomote, please send MrUbens a message on Discord: http://discord.gg/roomote
MrGeorgen commentedon Sep 21, 2026
Follow-up: I found and fixed one additional Forgejo compatibility bug in our fork.
Forgejo can return
"assignees": nullfor an existing unassigned pull request. Roomote validates the existing PR before updating it and required an array, so PR creation/update failed with HTTP 400 before the write request. The fix accepts the nullable response and normalizes it through the existing empty-assignee path; it is covered by a regression test.