refactor(server): migrate webhook-ci to ForgePort #278

Merged
charles merged 1 commit from refactor/migrate-webhook-ci-to-forgeport into main 2026-04-23 21:47:19 +00:00
Collaborator

Fourth per-consumer Forgejo migration after pipeline (#275), board (#276), and deps (#277 parallel).

Scope

http/webhook-ci.ts — post-CI dispatch decisions (decidePostCiAction, prMergeable, findOpenPRForHead, fetchAggregateState, fetchFailingRunLogs).

What changed

  • Every outbound Forgejo API call now goes through new ForgejoAdapter(token).<method>(parseRepo(repo), ...)
  • decidePostCiAction iterates reviews with port shapes: r.reviewer / r.state === "approved" | "changes_requested" | "request_review" / r.commitSha / r.stale
  • PR detail reads requestedReviewers (string[]) and labels (string[]) directly — no mapping
  • requestReviewers (returns status-code) → forge.requestReview (returns boolean); callers that checked >= 200 && < 300 now check the boolean
  • deleteReviewRequest single-reviewer → forge.removeReviewRequest([reviewer]) array form
  • fetchFailingRunLogs reuses one adapter instance across the probe loop

What stays raw

  • Webhook payload types (handleStatusEvent / handleActionRunEvent inputs, PrForCi, PrForFallback) — the port is only for outbound API calls, not for webhook event bodies Forgejo sends us
  • findOpenPRForHead still returns the legacy OpenPRForHead shape internally to keep webhook-handlers.ts consumers stable (maps the ForgePullRequest back to OpenPRForHead at the call site)
  • repoHasWorkflows — not used in this file; migration deferred to webhook-handlers.ts

No port extensions needed

Pipeline (#275) already shipped ForgeReview.stale, ReviewState: "request_review", ForgeWorkflowRun.htmlUrl. Every call here maps cleanly.

Tests

  • 16/16 webhook-ci.test.ts pass untouched — fetch-spy feeds raw Forgejo JSON that the adapter maps transparently
  • 190/190 apps/server/src/http/ tests pass
  • Full server suite: 1007 pass / 4 pre-existing fails

Independence

Disjoint from the sibling parallel migrations (deps #277, janitor #278). No shared files, no port extensions to reconcile.

Fourth per-consumer Forgejo migration after pipeline (#275), board (#276), and deps (#277 parallel). ## Scope `http/webhook-ci.ts` — post-CI dispatch decisions (`decidePostCiAction`, `prMergeable`, `findOpenPRForHead`, `fetchAggregateState`, `fetchFailingRunLogs`). ## What changed - Every outbound Forgejo API call now goes through `new ForgejoAdapter(token).<method>(parseRepo(repo), ...)` - `decidePostCiAction` iterates reviews with port shapes: `r.reviewer` / `r.state === "approved" | "changes_requested" | "request_review"` / `r.commitSha` / `r.stale` - PR detail reads `requestedReviewers` (string[]) and `labels` (string[]) directly — no mapping - `requestReviewers` (returns status-code) → `forge.requestReview` (returns boolean); callers that checked `>= 200 && < 300` now check the boolean - `deleteReviewRequest` single-reviewer → `forge.removeReviewRequest([reviewer])` array form - `fetchFailingRunLogs` reuses one adapter instance across the probe loop ## What stays raw - Webhook **payload** types (`handleStatusEvent` / `handleActionRunEvent` inputs, `PrForCi`, `PrForFallback`) — the port is only for outbound API calls, not for webhook event bodies Forgejo sends us - `findOpenPRForHead` still returns the legacy `OpenPRForHead` shape internally to keep `webhook-handlers.ts` consumers stable (maps the `ForgePullRequest` back to `OpenPRForHead` at the call site) - `repoHasWorkflows` — not used in this file; migration deferred to `webhook-handlers.ts` ## No port extensions needed Pipeline (#275) already shipped `ForgeReview.stale`, `ReviewState: "request_review"`, `ForgeWorkflowRun.htmlUrl`. Every call here maps cleanly. ## Tests - 16/16 `webhook-ci.test.ts` pass untouched — fetch-spy feeds raw Forgejo JSON that the adapter maps transparently - 190/190 `apps/server/src/http/` tests pass - Full server suite: 1007 pass / 4 pre-existing fails ## Independence Disjoint from the sibling parallel migrations (deps #277, janitor #278). No shared files, no port extensions to reconcile.
refactor(server): migrate webhook-ci to ForgePort
All checks were successful
qa / qa (pull_request) Successful in 4m19s
qa / dockerfile (pull_request) Successful in 8s
1bf2cd6032
Replaces raw `forgejo-api.ts` imports in `webhook-ci.ts` with
`ForgejoAdapter` instances, keeping the module aligned with the pipeline
(#275) and board (#276) migrations already on main.

Every outbound Forgejo call (`getPullRequest`, `listOpenPullRequests`,
`listPullReviews`, `getAggregateStatus`, `getWorkflowJobLogs`,
`deleteReviewRequest`, `requestReviewers`) now goes through the port;
`decidePostCiAction` consumes `ForgeReview` + `ForgePullRequest` shapes
(`r.reviewer`, `r.state === "approved"`, `r.commitSha`,
`pr.requestedReviewers`, `pr.mergeable`).

The legacy `OpenPRForHead` shape is preserved and built from the
adapter's `ForgePullRequest`, because `webhook-handlers.ts` still passes
the object straight through to `dispatchFixCi` / `decidePostCiAction`
(both of which accept the `PrForCi` `{user: {login}, head: {ref}}`
contract). Flipping that outward shape is a follow-up refactor.

Webhook payload types (`handleStatusEvent` / `handleActionRunEvent`
inputs) stay raw Forgejo shapes — the port is only for outbound calls.

Tests: the fetch-spy harness returns raw Forgejo JSON that the adapter
maps, so no test shape updates were needed. Full server suite: 1007
pass / 4 fail (pre-existing: 3 sweeper JSONL + 1 foreman).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
charles deleted branch refactor/migrate-webhook-ci-to-forgeport 2026-04-23 21:47:19 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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
charles/claude-hooks!278
No description provided.