Skip to content

feat(git): surface Trunk merge-queue status and enqueue action in the app#3204

Draft
gantoine wants to merge 1 commit into
mainfrom
posthog-code/merge-queue-ui
Draft

feat(git): surface Trunk merge-queue status and enqueue action in the app#3204
gantoine wants to merge 1 commit into
mainfrom
posthog-code/merge-queue-ui

Conversation

@gantoine

@gantoine gantoine commented Jul 6, 2026

Copy link
Copy Markdown
Member

What

Surfaces Trunk merge-queue status in the app and lets you enqueue/cancel a PR from the task header.

  • workspace-serverGitService.getPrMergeQueueStatus(prUrl) 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 + Zod schemas.
  • coregetPrVisualConfig is merge-queue-aware via a new deriveMergeQueueState helper: Queued / Testing (orange, spinner), Queue failed (red, retry), and Merge via queue on open PRs. PrActionType widened in @posthog/shared.
  • host-router — one-line forward for the new procedure.
  • uiuseMergeQueueStatus polls 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 + deriveMergeQueueState mapping.
  • service.merge-queue.test.ts — the gh-backed status read and /trunk merge / /trunk cancel comment actions.
  • workspace-events.contribution.test.ts — the merged notification fires once on the merged transition and not otherwise.

Full pnpm typecheck (22/22) and Biome clean.

Notes

  • Check-run name is matched by the Trunk Merge Queue prefix (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.
  • updatePrByUrl input enum widened additively; a stale external workspace-server would reject the new actions with a clean tRPC error.

Created with PostHog Code

… 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
@trunk-io

trunk-io Bot commented Jul 6, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

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

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit cc70f07.

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Comments Outside Diff (1)

  1. packages/workspace-server/src/services/git/schemas.ts, line 761-781 (link)

    P2 prMergeQueueStatusSchema is defined identically here and in packages/core/src/git/router-schemas.ts (same structure, same field names, same enum values). The comment in router-schemas.ts acknowledges this with "Mirrors…". If a new conclusion type is added on one side (e.g., a future GitHub check-run value), the other silently diverges and tRPC's output validation will either strip or reject the new value depending on which layer sees it first. Sharing the type via the @posthog/shared package (similar to how prActionTypeSchema already lives there) would eliminate the duplication.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "feat(git): surface Trunk merge-queue sta..." | Re-trigger Greptile

Comment on lines +60 to 68
if (
variables.action === "merge-queue" ||
variables.action === "merge-queue-cancel"
) {
void queryClient.invalidateQueries(
trpc.git.getPrMergeQueueStatus.pathFilter(),
);
}
} else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Suggested change
if (
variables.action === "merge-queue" ||
variables.action === "merge-queue-cancel"
) {
void queryClient.invalidateQueries(
trpc.git.getPrMergeQueueStatus.pathFilter(),
);
}
} else {
} else {

Comment on lines +1000 to +1003
const runsResult = await execGh([
"api",
`repos/${pr.owner}/${pr.repo}/commits/${headSha}/check-runs?per_page=100`,
]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant