feat(git): surface Trunk merge-queue status and enqueue action in the app#3204
feat(git): surface Trunk merge-queue status and enqueue action in the app#3204gantoine wants to merge 1 commit into
Conversation
… app Wire the Trunk merge queue into the PR surfaces: - workspace-server: `GitService.getPrMergeQueueStatus` reads the `Trunk Merge Queue` check run on the PR head commit; `updatePrByUrl` gains `merge-queue`/`merge-queue-cancel` actions that post `/trunk merge` and `/trunk cancel` comments. New tRPC procedure + schemas, forwarded one-to-one by the host router. - core: `getPrVisualConfig` becomes merge-queue-aware (Queued/Testing in orange, Queue failed in red, "Merge via queue" on open PRs) via a new `deriveMergeQueueState` helper; `PrActionType` widened in @posthog/shared. - ui: `useMergeQueueStatus` polls the check run every 30s while queued and refreshes PR state when it settles; the task-header badge + dropdown show the queue state and enqueue/cancel actions; a "Pull request merged" notification fires from the workspace-events contribution on the merged transition. Adds unit tests for the visual-config mapping, the gh-backed service methods, and the merged notification. Generated-By: PostHog Code Task-Id: 2d321370-0c0e-4d63-89d7-e367ebd9ecee
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
|
| if ( | ||
| variables.action === "merge-queue" || | ||
| variables.action === "merge-queue-cancel" | ||
| ) { | ||
| void queryClient.invalidateQueries( | ||
| trpc.git.getPrMergeQueueStatus.pathFilter(), | ||
| ); | ||
| } | ||
| } else { |
There was a problem hiding this comment.
Immediate invalidation stops polling before Trunk processes the comment. After
setQueryData sets status: "queued", the refetchInterval in useMergeQueueStatus activates (returns 30_000). But invalidateQueries fires an immediate refetch — which returns null because Trunk hasn't yet created the check run — causing refetchInterval to evaluate to false and halt all further polling. The badge reverts to "Open" and stays there until the next window focus (staleTime=25s). Additionally, the wasActive guard in useMergeQueueStatus fires on this null transition and needlessly invalidates getPrDetailsByUrl and getTaskPrStatus. The 30 s polling already handles reconciliation once Trunk creates the check run; the eager invalidation is counterproductive here.
| if ( | |
| variables.action === "merge-queue" || | |
| variables.action === "merge-queue-cancel" | |
| ) { | |
| void queryClient.invalidateQueries( | |
| trpc.git.getPrMergeQueueStatus.pathFilter(), | |
| ); | |
| } | |
| } else { | |
| } else { |
| const runsResult = await execGh([ | ||
| "api", | ||
| `repos/${pr.owner}/${pr.repo}/commits/${headSha}/check-runs?per_page=100`, | ||
| ]); |
There was a problem hiding this comment.
Check-runs are fetched with
per_page=100 but without pagination handling. On a commit with more than 100 check runs (common on larger CI setups), the Trunk run may be beyond the first page, causing getPrMergeQueueStatus to return null even when the PR is genuinely queued. Other list endpoints in service.ts (e.g., getPrChangedFiles) use --paginate --slurp to handle this. Consider passing --paginate to execGh here and iterating over all pages, or at least fetching with a filter to narrow the results at the API level.
What
Surfaces Trunk merge-queue status in the app and lets you enqueue/cancel a PR from the task header.
GitService.getPrMergeQueueStatus(prUrl)reads theTrunk Merge Queuecheck run on the PR head commit;updatePrByUrlgainsmerge-queue/merge-queue-cancelactions that post/trunk mergeand/trunk cancelcomments. New tRPC procedure + Zod schemas.getPrVisualConfigis merge-queue-aware via a newderiveMergeQueueStatehelper: Queued / Testing (orange, spinner), Queue failed (red, retry), and Merge via queue on open PRs.PrActionTypewidened in@posthog/shared.useMergeQueueStatuspolls the check run every 30s while queued and refreshes PR state when it settles; the task-header badge + dropdown render the queue state and enqueue/cancel actions; a "Pull request merged" notification fires from the workspace-events contribution on the merged transition.Why
Third piece of the Trunk merge-queue adoption (alongside the docs and agent-skill PRs): make queue state and the enqueue action first-class in the PostHog Code UI.
Tests
prStatus.test.ts— visual-config precedence +deriveMergeQueueStatemapping.service.merge-queue.test.ts— the gh-backed status read and/trunk merge//trunk cancelcomment actions.workspace-events.contribution.test.ts— the merged notification fires once on themergedtransition and not otherwise.Full
pnpm typecheck(22/22) and Biome clean.Notes
Trunk Merge Queueprefix (one exported const) — if Trunk renames it the badge degrades to today's behavior. Worth confirming the exact name against a real enqueued PR before rollout.updatePrByUrlinput enum widened additively; a stale external workspace-server would reject the new actions with a clean tRPC error.Created with PostHog Code