feat(forgejo): onboard repositories from Settings → Workspaces #268

Merged
lucas merged 1 commit from agent/issue-266-forgejo-onboarding into main 2026-11-12 20:25:37 +01:00
Collaborator

Adds the deterministic, server-side onboarding action from #266.

What it does. Every Forgejo-matched workspace row in Settings → Workspaces gets an Onboard button. The dialog collects which behaviours to enable (issue handler, implementation flow, automatic reviews, CI watchdog for others' PRs and for branch globs, pushing to others' PR branches) and the label names for them — prefilled in the repository's own casing, decided from its existing labels. POST /forgejo/onboard then creates the labels that are missing (an existing repository or organisation label of the same folded name is reused; Status/Blocked is always included), commits .omp/forgejo.yaml on omp-deck/onboarding and opens a pull request that documents what it enables and which labels it needed.

Guards. The rendered file goes through parseRepoConfig before it is committed, so a renderer bug can never reach a PR. A repository that already has the file on its default branch is refused with 409; the workspaces feed now reports that state (onboarded), so the button is disabled when it is known.

Webhook probe. A repository can be fully configured and still inert. The onboarding PR is itself the probe: 60 s after it is opened the deck reads its own delivery log and, when no delivery for that repository arrived, comments on the PR naming the cause — no webhook at all, one that does not cover this repository, or a secret that does not match the broker's. The deck never creates or inspects the webhook; the secret lives only in the broker's config.

Verification.

  • bun test src/forgejo/onboarding-config.test.ts src/forgejo/onboarding-probe.test.ts src/routes-forgejo.test.ts — 39 pass (render→parse round trip for the full and the empty selection, label-name distinctness under the config parser's folding, label style detection, the four webhook verdicts, and the route's 200/409/502/400 paths with a recording DispatchApi stub).
  • bun test in apps/server — 1352 pass, 0 fail.
  • bun run typecheck at the root — clean.
  • Not exercised: the manual end-to-end against a live instance (no instance with a write token in this session), i.e. that Forgejo accepts force_overwrite_new_branch and #rrggbb label colors.

Closes: #266

Adds the deterministic, server-side onboarding action from #266. **What it does.** Every Forgejo-matched workspace row in Settings → Workspaces gets an **Onboard** button. The dialog collects which behaviours to enable (issue handler, implementation flow, automatic reviews, CI watchdog for others' PRs and for branch globs, pushing to others' PR branches) and the label names for them — prefilled in the repository's own casing, decided from its existing labels. `POST /forgejo/onboard` then creates the labels that are missing (an existing repository *or* organisation label of the same folded name is reused; `Status/Blocked` is always included), commits `.omp/forgejo.yaml` on `omp-deck/onboarding` and opens a pull request that documents what it enables and which labels it needed. **Guards.** The rendered file goes through `parseRepoConfig` before it is committed, so a renderer bug can never reach a PR. A repository that already has the file on its default branch is refused with 409; the workspaces feed now reports that state (`onboarded`), so the button is disabled when it is known. **Webhook probe.** A repository can be fully configured and still inert. The onboarding PR is itself the probe: 60 s after it is opened the deck reads its own delivery log and, when no delivery for that repository arrived, comments on the PR naming the cause — no webhook at all, one that does not cover this repository, or a secret that does not match the broker's. The deck never creates or inspects the webhook; the secret lives only in the broker's config. **Verification.** - `bun test src/forgejo/onboarding-config.test.ts src/forgejo/onboarding-probe.test.ts src/routes-forgejo.test.ts` — 39 pass (render→parse round trip for the full and the empty selection, label-name distinctness under the config parser's folding, label style detection, the four webhook verdicts, and the route's 200/409/502/400 paths with a recording `DispatchApi` stub). - `bun test` in `apps/server` — 1352 pass, 0 fail. - `bun run typecheck` at the root — clean. - Not exercised: the manual end-to-end against a live instance (no instance with a write token in this session), i.e. that Forgejo accepts `force_overwrite_new_branch` and `#rrggbb` label colors. Closes: #266
A matched workspace can now be onboarded in one action: the dialog
collects which behaviours to enable and under which label names, the
server creates the labels that are missing (reusing repo or org labels
of the same folded name, always adding Status/Blocked) and opens a pull
request adding .omp/forgejo.yaml on the branch omp-deck/onboarding.

The generated file is parsed by the deck's own config parser before it
is committed, and a repository that already has the file on its default
branch is refused with a 409; the workspaces feed reports that state so
the button can be disabled.

Because a repository can be fully configured and still inert, the pull
request doubles as a webhook probe: a minute after it is opened the deck
reads its own delivery log and comments on the pull request when no
delivery for that repository arrived, distinguishing a missing webhook,
one that does not cover the repository, and a secret that does not match
the broker's. The deck never touches the webhook itself.

Co-Authored-By: Claude Opus 5 via omp-deck
lucas approved these changes 2026-11-12 20:25:33 +01:00
lucas merged commit 4def57227a into main 2026-11-12 20:25:37 +01:00
lucas deleted branch agent/issue-266-forgejo-onboarding 2026-11-12 20:25:37 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
lucas/omp-deck!268
No description provided.