docs(merge-queue): document single-to-parallel cutover and Queued-stuck causes#259
docs(merge-queue): document single-to-parallel cutover and Queued-stuck causes#259samgutentag wants to merge 1 commit into
Conversation
…ck causes Adds guidance for the single -> parallel mode cutover, surfaced by a customer planning the switch. In parallel mode a PR stays Queued until impacted targets are uploaded for its head SHA, with no timeout fallback, so stale PRs that predate the impacted-targets job hang indefinitely. - parallel-queues: new "Cutting over from single to parallel mode" section (land the job early, backfill open PRs, require a recent merge base) - troubleshooting: split the stuck-Queued accordion into status-check vs missing-impacted-targets causes with unstick steps - pr-states reference: spell out the two parallel-mode gating conditions Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Verification status (2026-06-17): Could not determine rollout state from available signals. Chaining to
Next: see the |
|
Code verification (2026-06-17): 5 confirmed / 0 contradicted / 0 ambiguous / 2 unverifiable
All five code-verifiable backend claims confirm cleanly against Source #1 — Parallel (GRAPH) mode requires impacted targets; single mode does not (confirmed)File: return {
requiresImpactedTargets: mode === "GRAPH",
doesBaseBranchMatch: prBaseBranch === mergeBranch,Reasoning: Impacted targets are required only when the merge instance Source #2 — A PR stays Queued until impacted targets are uploaded for the head SHA (confirmed)File: async hasImpactedTargetsIfRequired(
mergeInstance: prismaTypes.MergeInstance,
sha: string,
): Promise<boolean> {
if (mergeInstance.mode !== prismaTypes.MergeInstanceMode.GRAPH) {
return true;
}
return this.impactedTargetsClient.has(mergeInstance.repoId, sha);
}Reasoning: In GRAPH mode the gate resolves to Source #3 — No timeout / auto-ALL fallback; the gate is presence-only (confirmed)File: const basePasses =
doesBaseBranchMatch === true &&
mergeItemInNotReady === true &&
(requiresImpactedTargets === false || hasImpactedTargets === true);Reasoning: Readiness is a pure boolean conjunction. The impacted-targets term is satisfied only by Source #4 — Uploading targets in single mode is stored but not used for scheduling (confirmed)File: async setImpactedTargets(...) {
const { repo, prSha, prNumber, targetBranch, impactedTargets } =
mapper.fromSetImpactedTargetsRequest(call.request);
...
await controller.putImpactedTargets(..., impactedTargets, ...);
...
// Caught readiness check error when putting impacted targets; ignoring
}Reasoning: Source #5 — /setImpactedTargets endpoint exists (confirmed)File: async setImpactedTargets(
call: grpc.ServerUnaryCall<
servicePb.SetImpactedTargetsRequest,
servicePb.SetImpactedTargetsResponse
>,Reasoning: The |
What
Documents the single → parallel mode cutover for Merge Queue, plus the most common reason a PR gets stuck in
Queuedafter switching. Surfaced by a customer planning this exact migration.In parallel mode a PR doesn't leave
Queueduntil both branch protection passes and impacted targets are uploaded for its head SHA. There's no timeout fallback, so a stale PR whose impacted-targets job never ran hangs inQueuedindefinitely — with no signal to the author that they need to rebase. None of the migration story was documented.Changes
parallel-queues/index.mdx— new "Cutting over from single to parallel mode" section: land the impacted-targets job early (uploads are stored but unused in single mode, so it's safe), backfill open PRs so they don't hang, and raise the merge-base staleness requirement so new PRs always run the job. Plus a warning that a target-less PR staysQueuedforever.reference/troubleshooting.mdx— split the "stuck as Queued" accordion into Cause 1 (status checks) and Cause 2 (missing impacted targets), each with unstick steps.using-the-queue/reference.mdx— lifecycle prose and theQueuedtable row now spell out the two parallel-mode gating conditions.Source
Originated from a customer Slack thread on planning a single → parallel cutover: original conversation.
Behavior confirmed by Robert in that thread: no
Queuedtimeout, posting targets before cutover is safe, re-uploading overrides (last-upload-wins), and auto-ALLis intentionally not done because it would collapse every lane.Needs a check before merge
The claim that the PR detail page "shows which condition it's waiting on" rests on the timeline screenshot from the thread, not verified against the live app. Worth a glance before this ships.
🤖 Generated with Claude Code