ad21460007
Co-authored-by: Kandev Agent <agent@kandev.dev>
6.3 KiB
6.3 KiB
spec, created, status
| spec | created | status |
|---|---|---|
| docs/specs/github-pr-merge-queue/spec.md | 2026-08-17 | complete |
Implementation Plan: GitHub PR Merge Queue
Overview
Extend the existing GitHub merge boundary to use GitHub's asynchronous, queue-aware merge request and return a typed merged-or-queued outcome. Then reuse that outcome in the existing PR merge button across the desktop detail, compact status, and mobile Review surfaces, with targeted unit and E2E proof.
Backend
Provider client contract
- Update
apps/backend/internal/github/client.goso the merge operation returns a typed outcome rather than only an error. - Update
apps/backend/internal/github/gh_client.goandapps/backend/internal/github/pat_client.goto callPUT /repos/:owner/:repo/pulls/:number/merge-asyncwithmerge_action=default, preserve the selectedmerge_method, and normalize GitHub's accepted, already-queued, and already-merged response shapes. - Update
apps/backend/internal/github/mock_client.goandapps/backend/internal/github/noop_client.gofor the same contract so local and E2E behavior remains deterministic.
Service and HTTP response
- Update
apps/backend/internal/github/service_pr.goto propagate the typed outcome while retaining workspace scope checks, personal-write credential routing, merge-method fallback, and cache invalidation. - Update
apps/backend/internal/github/controller.goto return{"status":"merged"}or{"status":"queued"}and retain the existing operational-auth and provider-error mapping.
Frontend
Queue-aware merge action
- Update
apps/web/lib/api/domains/github-pr-api.tsand the re-exporting API module to type the merged-or-queued response. - Update
apps/web/components/github/pr-task-icon.tsxwith a tested eligibility predicate that permits a queue-required branch only after explicit successful checks and satisfied reviews, while continuing to reject drafts, conflicts, behind branches, changes requested, and incomplete review/check gates. - Update
apps/web/components/github/pr-merge-button.tsxto render for direct or queued eligibility, show the outcome-specific notification, suppress repeat submission after acceptance, and refresh the PR state. - Add the new action and outcome copy to all locale catalogs under
apps/web/src/locales/*/github.json; generate the Traditional Chinese pair through the repository script rather than translating them independently.
Mobile design contract
- Desktop outcome: the existing PR detail header and compact status surface expose one merge action whose result says merged or queued.
- Mobile entry point: the task's existing Review bottom-navigation destination.
- Nearest shipped exemplar: the existing full-height mobile Review surface and
PRMergeButton; retain its single internal scroll owner and shared PR state. - Information hierarchy: PR status and blockers remain above the primary merge action; the action is the terminal operation for an eligible PR.
- Presentation: retain direct navigation to the full-height Review surface because PR review is dense primary content, not a temporary picker.
- Geometry: keep the existing dynamic-height/safe-area behavior, avoid document horizontal overflow, and preserve a touch target at least 44px high on phone.
- Shared logic: eligibility, mutation, result handling, and refresh remain shared; only the existing responsive composition differs.
Tests
- What: PAT and
ghclients sendmerge-async,merge_action=default, and the chosen merge method, and normalize direct, queued, and idempotent results. Files:apps/backend/internal/github/pat_client_writes_test.go,apps/backend/internal/github/gh_client_commands_test.go. How: focused HTTP/command capture tests with representative GitHub responses. - What: service preserves method resolution and cache invalidation while
returning the provider outcome. File:
apps/backend/internal/github/service_pr_test.go. How: table-driven unit tests with the stub client. - What: HTTP validation, outcome JSON, auth routing, and provider errors.
File:
apps/backend/internal/github/controller_test.go. How: handler tests for merged, queued, malformed method, and rejection paths. - What: frontend API response typing and queue eligibility boundaries.
Files:
apps/web/lib/api/domains/github-api.test.ts,apps/web/components/github/pr-task-icon.test.ts. How: request capture and table-driven predicate tests. - What: button notifications, accepted-state suppression, retry behavior,
and refresh callback. File:
apps/web/components/github/pr-merge-button.test.tsx. How: component tests with mocked API outcomes.
E2E Tests
- Scenario: eligible direct merge reports merged. File:
apps/web/e2e/tests/pr/pr-merge-queue.spec.ts. What to verify: the desktop PR surface exposes the action, submits it, and shows the merged notification. - Scenario: queue-required merge reports queued and does not resubmit.
File:
apps/web/e2e/tests/pr/pr-merge-queue.spec.ts. What to verify: the desktop action remains available for the queue-required state and the accepted queue notification is shown once. - Scenario: phone Review surface provides the same queued outcome. File:
apps/web/e2e/tests/pr/mobile-pr-merge-queue.spec.ts. What to verify: Review navigation, touch activation, queued notification, a touch-sized action, and no document horizontal overflow.
Verification Results
- Backend:
make -C apps/backend test ARGS='./internal/github/...'passed; the Make target executed the full backendgo test -tags fts5 ./...suite. - Frontend: 96 focused Vitest tests passed;
pnpm run i18n:checkandpnpm run typecheckpassed. - Desktop E2E:
pnpm e2e:run --no-build tests/pr/pr-merge-queue.spec.tspassed (1 test). - Mobile E2E:
pnpm e2e:run --no-build --project mobile-chrome tests/pr/mobile-pr-merge-queue.spec.tspassed (1 test).
Implementation Waves And Parallel Candidates
Wave 1:
Wave 2:
Wave 3:
Execution is sequential in the primary conversation unless the user explicitly authorizes subagents.