Skip to content

[Feature]: add forgejo support - minor modifications needed #1777

Open

Description

@MrGeorgen

Preflight

  • 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.

Proposed behavior

support forgejo

Affected surfaces

Other

Self-hosting implications

setup forgejo token and permission

Alternatives considered

No response

Documentation impact

No response

Activity

  1. roomote-community commented on Aug 28, 2026

    @roomote-community
    Contributor

    I've analyzed this issue and here's my proposed implementation plan:

    1. 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.
    2. 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.
    3. 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.
    4. 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.
    5. 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.

  2. MrGeorgen commented on Sep 1, 2026

    @MrGeorgen
    Author

    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):

    1. 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.

    2. 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.

  3. changed the title [-]Does the Gitea source control integration work with Forgejo?[/-] [+][Feature]: add forgejo support - minor modifications needed[/+] on Sep 1, 2026
  4. MrGeorgen commented on Sep 8, 2026

    @MrGeorgen
    Author

    @roomote implement it using the observation above

  5. roomote-community commented on Sep 8, 2026

    @roomote-community
    Contributor

    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

  6. MrGeorgen commented on Sep 21, 2026

    @MrGeorgen
    Author

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions