fix(desktop): merge buttons follow the repository's merge settings
Merged
KI
5h ago+453+453+012345678901234567890123456789-120-120-012345678901234567890123456789
Links
- Closes #6185
- Plain: T-1179 (main button ignores the default), T-1178 (pending checks, see Follow-ups)
- Linear: SUPER-1771, SUPER-3205
Summary
- The PR page's main Merge button now uses the repository's default method instead of always squashing.
- Every merge menu offers only the methods the repository allows, in GitHub's order (merge commit, squash, rebase), and checks the default.
- Mobile's merge action uses the same default.
Why / Context
Two reports of the same problem. A squash-only repo still offered "merge commit" and "rebase", which failed with a 405 after the click. A merge-commit repo had squash as the one-click action. The detail read already fetched squashMergeAllowed / mergeCommitAllowed / rebaseMergeAllowed, but desktop ignored them.
How It Works
readPullRequestDetail(shared by the localviewerGithub, the cloudintegration.github, and host-servicegithub) also asks GraphQL forrepository.viewerDefaultMergeMethod, in the query it already makes. No extra request. This is what GitHub's own button preselects: the viewer's last method, else the first allowed one. It is returned as a new additive output field,mergeability.defaultMergeMethod.allowedMergeMethodskeeps its order (trpc-compat rule 6).- New
@superset/shared/pull-request-merge-methods→mergeMethodChoices({ allowedMergeMethods, defaultMergeMethod })returns{ methods, primary }:- no or unknown settings → today's behaviour (all three, squash primary)
- no default (older API/host-service build) → squash if allowed, else the first allowed
- Desktop PR page:
PullRequestDetail.mergeMethodsdrives the main button, the method list, and Force merge. - v2 workspace PR badge menu and activity menu: the new
MergeMethodMenuItemsreadsmergeMethodsfrom the same cached PR-detail query (pullRequestDetailQueryOptions). It mounts only while its menu is open, so the read happens on open, not per render. It falls back to today's list until the read lands or if it fails.
Real values via gh api graphql:
| repo | squash | merge | rebase | viewerDefaultMergeMethod |
|---|---|---|---|---|
| facebook/react | ✓ | ✗ | ✗ | SQUASH |
| cli/cli | ✓ | ✓ | ✓ | MERGE |
| our repo | ✓ | ✓ | ✓ | SQUASH |
Merge surfaces
| Surface | Covered |
|---|---|
Desktop PR page (PullRequestActions) button + menu + force merge | ✅ |
v2 workspace PR badge (PRStatusGroup) | ✅ |
v2 workspace activity menu (ShipActionsMenu) | ✅ |
| Mobile PR card + merge confirm | ✅ (already filtered by allowed; now uses the default) |
v1 Changes header (PRButton, gh pr merge) | ❌ v1 is sunsetting; still hardcoded |
| CLI | n/a, there is no merge command |
Testing
- Failing before, passing after:
toPullRequestDetail.test.ts, "offers only the merge methods the repository allows…". Onmainthe detail carries no merge choices (undefined), so the UI hardcoded squash and all three methods. bun testinpackages/shared(newmergeMethodChoicessuite + detail read assertsdefaultMergeMethod): all pass except the pre-existingrrule.test.tsBYHOUR failure, which also fails onmainand is untouched herebun testdesktoppull-requests,v2-workspace,viewer-github: 1300 passbun testmobileworkspace: 63 passbun run typecheck: shared clean. Desktop: only pre-existing TS1149 path-casing errors from this worktree's alias path, none in touched files. Mobile: 0 errors inapps/mobile, 12 pre-existing Node-timer typings inport-scanner/workspace-fs.bun run lint:fix,bun run check:i18n(0 missing; only existing strings reused)- Not done: CDP screenshot. This worktree has no provisioned dev stack (no
.env/ signed-in desktop).
Manual QA Checklist
- Squash-only repo (e.g. a fork of facebook/react): PR page menu shows only "Squash and merge", checked; main button confirm says Squash and merge
- Merge-commit-only repo: main button merges with a merge commit; menu shows only that
- All-allowed repo where you last used rebase on github.com: rebase is checked and primary
- v2 workspace badge chevron and activity "…" menu: list matches the repo after open
- Offline or failed detail read: menus still show all three methods
Compatibility
- Additive output field only. Released clients ignore it.
- New desktop/mobile against an older API or host-service:
defaultMergeMethodisundefined→ squash stays primary where allowed (today's behaviour), and the menu is still filtered byallowedMergeMethods. The localviewerGithubpath is in-process, so it is correct right away.
Follow-ups
- T-1178 (pending required checks):
MergeStatusSection(PullRequestInfo.tsx) only knows conflicting / mergeable / unknown, so it shows "Can merge without conflicts" while required checks run.toPullRequestDetaildrops GitHub'smergeStateStatus(BLOCKED= required checks or reviews outstanding). The fix is to carrymergeStateStatusintoPullRequestDetail, add a "blocked" status ("Waiting on required checks/reviews"), and gate the main Merge button on it unlessviewerCanMergeAsAdmin(GitHub's bypass). That means new strings and a product call on admin bypass, so it is kept out of this PR. - v1
PRButtoncould usegh repo view --json viewerDefaultMergeMethod,...if v1 outlives the sunset.
Summary by cubic
Makes the desktop and mobile merge buttons follow the repository's merge settings instead of always squashing or offering every method. A squash-only repo no longer offers merge commit and rebase (which failed with a 405 after the click), and a merge-commit-only repo no longer squashes from the main button.
- The PR detail read now asks GitHub for
viewerDefaultMergeMethodin the query it already makes, exposed as a new additivemergeability.defaultMergeMethodfield. - A shared
mergeMethodChoiceshelper converts the allowed methods and default into the menu list (GitHub's order: merge commit, squash, rebase) and the main button's action. - Older API or host-service builds without the field keep today's behavior: all three methods offered, squash primary when allowed.
- Cached PR-detail entries from earlier builds are filled with the same defaults so menus never throw, and v2 menus stay disabled while settings load.
- Applies to the desktop PR page (button, method menu, force merge), v2 workspace PR badge and activity menus, and mobile's PR card and merge confirm.
Summary by CodeRabbit
- New Features
- Merge menus now show the methods allowed by the repository and identify the configured default.
- Desktop and mobile merge actions use the repository’s configured default method when available.
- When repository settings are unavailable, menus offer squash, merge, and rebase, with squash as the default.