Repository navigation
fix(github): enqueue a merge-queue PR when the repo disables auto-merge - #24327
Conversation
|
There was a problem hiding this comment.
ℹ️ No critical issues — one minor suggestion inline.
Reviewed changes
- Enqueue path for disabled auto-merge:
enablePRAutoMergenow calls theenqueuePullRequestGraphQL mutation when the base branch requires a merge queue and the repository disallows auto-merge, instead of the failinggh pr merge --auto. - Decision helper: new
mergeQueueDisallowsAutoMergereusesdetectRepositoryMergeMetadatato pick between the enqueue mutation and the existing--autopath; unknown metadata and queue-with-auto-merge still fall back to--auto. - Test: added coverage asserting the enqueue mutation is invoked and no
--automerge command runs.
I verified the enqueuePullRequest mutation against GitHub's public schema (EnqueuePullRequestInput with pullRequestId: ID! and optional expectedHeadOid: GitObjectID, returning mergeQueueEntry), and confirmed the control stays reachable for this case since canRequestWhenReady short-circuits on mergeQueueRequired === true.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the
Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough
Priority: Merge Risk:
|
8ddb974 to
2205315
Compare
Sync update (
|
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 10b64805-e4d6-4c22-b200-8dc2763b915c
📥 Commits
Reviewing files that changed from the base of the PR and between 8ddb974de3515bedb4b055746b3e01f0b3861d6b and 2205315506b6efc2c003f19e9f69aa0885faf167.
📒 Files selected for processing (25)
src/main/github/client-merge-queue-auto-merge.test.tssrc/main/github/client/fetch/work-item-fetch.tssrc/main/github/client/lookup/pr-branch-lookup.tssrc/main/github/client/lookup/pr-number-lookup.tssrc/main/github/client/lookup/pr-refresh-outcome-assembly.tssrc/main/github/client/lookup/pull-request-lookup-data.tssrc/main/github/client/lookup/pull-request-lookup-hydration.tssrc/main/github/client/lookup/pull-request-merge-queue-membership.tssrc/main/github/client/merge/pr-auto-merge.tssrc/preload/api/gh-bridge-mutations-and-projects.tssrc/preload/api/github-pull-request-api.tssrc/renderer/src/components/github-auto-merge-success-toast.tssrc/renderer/src/components/github-item-dialog/land-pull-request/pr-actions-panel.tsxsrc/renderer/src/components/github-pr-merge-state.test.tssrc/renderer/src/components/github-pr-merge-state.tssrc/renderer/src/components/pull-request-page/actions/merge-actions.tssrc/renderer/src/components/right-sidebar/HostedReviewActions.tsxsrc/renderer/src/components/task-page-linear-jira-list-model.tsxsrc/renderer/src/components/task-page-work-item-signatures.tssrc/renderer/src/components/task-page/github/MergeCell.tsxsrc/renderer/src/hooks/useTaskPageGitHubWorkItemMutation.tssrc/shared/github/pull-request-types.tssrc/shared/github/work-item-types.tssrc/shared/hosted-review-github.tssrc/shared/hosted-review.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.
There was a problem hiding this comment.
Caution
The new commit does not typecheck. pnpm tc:web (part of pnpm typecheck and pnpm build:desktop) reports three errors introduced by this delta, so the PR cannot build as-is. Per-line fixes below.
Reviewed changes
- Queue-membership read: added
readPullRequestInMergeQueue(GraphQLisInMergeQueue) and threadedinMergeQueuethrough PR lookup, work-item fetch, refresh assembly, and the sharedPRInfo/GitHubWorkItem/HostedReviewInfotypes. - Queued presentation:
presentGitHubPRMergeStatenow returns an "In merge queue" state and suppresses the auto-merge action wheninMergeQueue === true. - Enqueue-aware toast: new
githubAutoMergeSuccessToast, withsuccessToastFromResultplumbing, so an enqueue reports "Added to the merge queue" instead of "Auto-merge enabled". - Decision refactor:
shouldUseMergeQueueAutoMerge+mergeQueueDisallowsAutoMergecollapsed intomergeQueueEnqueueDecision('enqueue' | 'auto' | 'skip') over one metadata read.
🚨 The renderer does not typecheck
node node_modules/typescript/bin/tsc --noEmit -p config/tsconfig.tc.web.json reports exactly three errors, all in the new delta. The main-process project (config/tsconfig.node.json) is clean, so this is renderer-only.
Technical details
# Renderer typecheck fails
## Affected sites
- `src/renderer/src/components/github-pr-merge-state.test.ts:30` — `TS2353`: `{ ok: true }` has no property in common with `{ enqueued?: boolean } | void` (excess property check).
- `src/renderer/src/components/right-sidebar/HostedReviewActions.tsx:96` — `TS2339`: `Property 'inMergeQueue' does not exist on type 'HostedReviewActionInfo'`.
- `src/renderer/src/hooks/useTaskPageGitHubWorkItemMutation.ts:167` — `TS2345`: `typed` (`{ ok?: boolean; error?: string | { message?: string } } | void`) is not assignable to `{ enqueued?: boolean } | void`.
## Reproduction
- `pnpm tc:web` (or `node node_modules/typescript/bin/tsc --noEmit -p config/tsconfig.tc.web.json`).
## Required outcome
- `pnpm tc:web` passes, with the enqueue result still reaching the toast and `review.inMergeQueue` still contributing to the merge state.
## Suggested approach (optional)
- One fix per site; see the inline comments.ℹ️ Nitpicks
presentPullRequestInMergeQueueis a merge-state presentation but lives ingithub-auto-merge-success-toast.ts, sogithub-pr-merge-state.tsimports it back from the toast module. The reverse import is type-only (so still acyclic), but the file name now under-describes its contents; a small dedicated module would read better.readPullRequestInMergeQueueis uncached whiledetectRepositoryMergeMetadatacaches for 10 minutes, so each PR refresh on a merge-queue branch adds one GraphQL query per PR. Fine if membership must stay live, but a conscious call for large scans.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
2205315 to
194b88f
Compare
Sync update (
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Since the prior pullfrog review (2205315506), the branch was amended to fix the three renderer typecheck errors it flagged:
- Fixed the not-enqueued toast test:
github-pr-merge-state.test.tspasses{}instead of{ ok: true }, which the weak{ enqueued?: boolean } | voidparameter rejected asTS2353. - Dropped the
review.inMergeQueueoverride:HostedReviewActionsnow relies on the...githubPRspread (aPRInfothat already carriesinMergeQueue), clearingTS2339without changing behavior — the?? githubPR?.inMergeQueuefallback was the effective value anyway. - Kept
enqueuedin the mutation result type: bothmutatesignatures and thetypedcast inuseTaskPageGitHubWorkItemMutationincludeenqueued?: boolean, so the enqueue flag reachessuccessToastFromResult.
Verified at 194b88f:
tsc --noEmitfor the node, web, and cli projects all exit 0.github-pr-merge-state.test.tsandclient-merge-queue-auto-merge.test.tspass (31 tests).- oxlint clean on the three changed files.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
194b88f to
d06b7a5
Compare
Sync update (
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
🟠 Major · Add serverEntityFromResult to the shared runner… · task-page-linear-jira-list-model.tsx:173-189
src/renderer/src/components/task-page-linear-jira-list-model.tsx:173-189
🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd
serverEntityFromResultto the shared runner contract.
MergeCellpassesserverEntityFromResult, butTaskPageGitHubWorkItemMutationRunner.rundoes not declare it. The supported web typecheck therefore fails withTS2353, blocking that typecheck workflow.Suggested fix
successToast?: string successToastFromResult?: (result: { enqueued?: boolean } | void) => string + serverEntityFromResult?: (result: unknown) => Partial<GitHubWorkItem> | undefined errorToast: string
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 4b73b577-8d1c-450d-bb07-0d84b4ac8121
📥 Commits
Reviewing files that changed from the base of the PR and between 194b88f10330ab4568c750a934322587324dc263 and d06b7a598b3eb52fb7a08e9c027de689a47f814c.
📒 Files selected for processing (3)
src/renderer/src/components/task-page-github-work-item-mutation-lifecycle.tssrc/renderer/src/components/task-page-github-work-item-mutation-regressions.test.tssrc/renderer/src/components/task-page/github/MergeCell.tsx
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
There was a problem hiding this comment.
Caution
The new commit does not typecheck. MergeCell now passes serverEntityFromResult to a runner whose type never declared it, so pnpm tc:web fails with TS2353 and the renderer/desktop build cannot complete. One-line fix inline.
Reviewed changes
Since the prior pullfrog review (194b88f), the branch was force-pushed into new commits that:
- Confirm an enqueue as queued:
applyServerEntityIfPresentnow appliesinMergeQueuefrom the server entity, so a confirmed enqueue clears the optimistic auto-merge flag and the cell shows "In merge queue". - Regression test: added a test asserting an enqueue confirms as
{ autoMergeEnabled: false, inMergeQueue: true }and recordsautoMerge: false. - Pass the queued server entity from
MergeCell:handleAutoMergenow suppliesserverEntityFromResult, returning{ autoMergeEnabled: false, inMergeQueue: true }when the result isenqueued: true. This is the call that does not typecheck.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
d06b7a5 to
21bc876
Compare
Sync update (
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Since the prior pullfrog review (d06b7a5), the only delta is one line:
- Runner contract accepts the queued server entity:
TaskPageGitHubWorkItemMutationRunner.runnow declaresserverEntityFromResult, matching the hook's input, soMergeCell.tsx:170typechecks again and the queued{ autoMergeEnabled: false, inMergeQueue: true }entity still reachesconfirmTaskPageGitHubWorkItemMutation.
Verified at 21bc876e:
node node_modules/typescript/bin/tsc --noEmit -p config/tsconfig.tc.web.jsonexits 0.- 47 focused tests pass:
task-page-github-work-item-mutation-regressions(16),github-pr-merge-state(15),client-merge-queue-auto-merge(16).
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
🟡 Minor · Hydrate branch lookup fallbacks before exposing merge controls. · pr-branch-lookup.ts:68-70
src/main/github/client/lookup/pr-branch-lookup.ts:68-70
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHydrate branch lookup fallbacks before exposing merge controls.
getPRByNumber(..., { readQueueMembership: true })can returnnull, and the catch path also returnsbranchDatadirectly. Branch data from the REST/list lookup does not containinMergeQueue. The no-candidate branch path returns similarly unhydrated data.A supported non-stacked branch lookup can therefore return a queued PR without membership data. If its merge metadata is clean,
github-pr-merge-state.tssetsdirectMergeAvailabletotrue. Apply queue-aware hydration to the branch fallbacks before returning them. This requires a branch-specific correction; the number-lookup hydration does not cover these exits.
🟡 Minor · Retain queue membership when merge metadata is unknown. · work-item-fetch.ts:125-132
src/main/github/client/fetch/work-item-fetch.ts:125-132
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRetain queue membership when merge metadata is unknown.
When
detectRepositoryMergeMetadatafails, it returnsmergeQueueRequired: null. The current=== truecheck then skipsreadPullRequestInMergeQueue. The REST fallback skips that lookup entirely. An already-queued, mergeable PR can therefore reach the renderer withoutinMergeQueueand receive direct merge controls.Read membership when
mergeQueueRequiredis unknown, and add the same best-effort lookup to the known-repository REST fallback.readPullRequestInMergeQueuealready returnsundefinedon rate-limit, parse, or request failures, so preserve the existing result when membership is unavailable.Suggested fix
const mergeMetadata = await detectRepositoryMergeMetadata(ownerRepo, baseRefName, ghOptions) const inMergeQueue = - mergeMetadata.mergeQueueRequired === true + mergeMetadata.mergeQueueRequired !== false ? await readPullRequestInMergeQueue(ownerRepo, number, ghOptions) : undefined @@ ) const reviewFields = await fetchPullRequestReviewFields(number, ownerRepo, ghOptions) - return { ...mapped, ...reviewFields } + const inMergeQueue = await readPullRequestInMergeQueue(ownerRepo, number, ghOptions) + return { + ...mapped, + ...reviewFields, + ...(inMergeQueue !== undefined ? { inMergeQueue } : {}) + }
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 9ec3ee96-3784-4df8-b39a-9d62313c686e
📥 Commits
Reviewing files that changed from the base of the PR and between d06b7a598b3eb52fb7a08e9c027de689a47f814c and 21bc876eeb94613870e69b9e06a2dffdfb0d062f.
📒 Files selected for processing (1)
src/renderer/src/components/task-page-linear-jira-list-model.tsx
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.
cc4c574 to
3663516
Compare
3663516 to
cec1c20
Compare
On repos whose base branch requires a merge queue and that disable auto-merge, gh pr merge --auto always calls enablePullRequestAutoMerge, which GitHub rejects. Call the enqueuePullRequest mutation directly in that case and report enqueue failures as merge-queue errors. Fixes stablyai#19638 Co-authored-by: Neil <neil@stably.ai>
cec1c20 to
a4c44a6
Compare

ELI5
Some repositories make pull requests wait in a "merge queue", a line that merges PRs one at a time. If a repository also turns off GitHub's auto-merge setting, Orca's "Merge when ready" button always failed with "Auto merge is not allowed for this repository". Now Orca adds the PR to the merge queue directly in that case, so the button works.
What Changed
Before: on a base branch that requires a merge queue,
enablePRAutoMergealways rangh pr merge --auto. gh turns that into theenablePullRequestAutoMergemutation, and it has no path that callsenqueuePullRequest. GitHub rejects that mutation when the repo has auto-merge disabled, so the user gotFailed to enable auto-merge for pull request: GraphQL: Auto merge is not allowed for this repository (enablePullRequestAutoMerge).After:
src/main/github/client/merge/pr-auto-merge.tsresolveMergeQueueAutoMergePathreplacesshouldUseMergeQueueAutoMerge, which was only used in this file. It reads the existing cacheddetectRepositoryMergeMetadataresult and returns:'enqueue'when a merge queue is required andautoMergeAllowed === false'gh-auto'when a queue is required and auto-merge is allowed or unknown (same as before)nullwhen no queue is required (same as before: theenablePullRequestAutoMergemutation)enqueuePullRequestGraphQL call. It sendspullRequestId, plusexpectedHeadOidwhen known, and uses the same gh options andGH_PROMPT_DISABLEDas the existing mutation, so local, WSL, SSH and runtime hosts all work the same way.Failed to add pull request to the merge queue: ...(through the existingclassifyPullRequestUpdateError). It no longer looks like the original auto-merge error.Added one regression test in
src/main/github/client-merge-queue-auto-merge.test.ts.Why
This fixes the bug at its source, the code that picks which merge call to make, and uses repo metadata Orca already fetches. It adds no new requests and no IPC or protocol changes, so mixed client/server versions keep working. An earlier version of this PR also tracked whether a PR is in the queue and showed a queue-specific UI. That part is left for a follow-up. Today's
gh --autopath, which can also put a ready PR straight into the queue, has the same gap. The extra per-PR GraphQL read would also use up rate-limit budget for every merge-queue repo.Known tradeoffs:
gh --autopath.Linked Issue
Fixes #19638
Visual Proof
N/A. The only change is in the main-process GitHub call. No UI changed, and the visible result (the error toast no longer appears) needs a live repo with a required merge queue and auto-merge disabled. The fix was verified with gh mocks (see Testing).
Testing
Reproduced on
mainwith a mock where gh rejects--autobecause auto-merge is disabled: returnsFailed to enable auto-merge ... Auto merge is not allowed for this repository (enablePullRequestAutoMerge)and never callsenqueuePullRequest. The new regression test and the scratch probe cases (classic merge queue, ruleset-onlyMERGE_QUEUErule, enqueue rejection) fail on main.On this branch, all probe cases pass. Control cases behave the same as on main: queue with auto-merge allowed, queue with unknown metadata, and no queue with auto-merge disabled.
pnpm test src/main/github/client-merge-queue-auto-merge.test.ts: 19 passed. Neighboring GitHub suites (RPC methods, local runtime, SSH/WSL routing): passed.oxlint, oxfmt, ast-grep, and the changed-code quality gates are clean on the touched files.
Platforms: macOS (unit tests, platform-independent main-process code). Not tested against a live merge-queue repo.
I manually tested these changes locally
Automated tests added/updated, or explained why not below
Review
Reviewed by two agents plus a verify pass. All approved with no blockers. The blocking note from round one (enqueue failures were labeled as auto-merge errors) is fixed.
Agent skill upstream boundary
Notes
Security: no new inputs, and the GraphQL variables are passed as
-fargs. Cross-platform: the same gh exec wrapper on all OSes. Remote/SSH: this runs on whichever host serves the repo, with no RPC change. Mobile: uses the same server-side code path. Performance: no extra requests, because merge metadata is already fetched and cached.Original fix by @innocarpe. Narrowed to the core fix in this PR.
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)