fix(desktop): merge buttons follow the repository's merge settings

Merged
KI
5h ago
+453-120

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 local viewerGithub, the cloud integration.github, and host-service github) also asks GraphQL for repository.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. allowedMergeMethods keeps 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.mergeMethods drives the main button, the method list, and Force merge.
  • v2 workspace PR badge menu and activity menu: the new MergeMethodMenuItems reads mergeMethods from 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:

reposquashmergerebaseviewerDefaultMergeMethod
facebook/react✓✗✗SQUASH
cli/cli✓✓✓MERGE
our repo✓✓✓SQUASH

Merge surfaces

SurfaceCovered
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
CLIn/a, there is no merge command

Testing

  • Failing before, passing after: toPullRequestDetail.test.ts, "offers only the merge methods the repository allows…". On main the detail carries no merge choices (undefined), so the UI hardcoded squash and all three methods.
  • bun test in packages/shared (new mergeMethodChoices suite + detail read asserts defaultMergeMethod): all pass except the pre-existing rrule.test.ts BYHOUR failure, which also fails on main and is untouched here
  • bun test desktop pull-requests, v2-workspace, viewer-github: 1300 pass
  • bun test mobile workspace: 63 pass
  • bun 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 in apps/mobile, 12 pre-existing Node-timer typings in port-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: defaultMergeMethod is undefined → squash stays primary where allowed (today's behaviour), and the menu is still filtered by allowedMergeMethods. The local viewerGithub path 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. toPullRequestDetail drops GitHub's mergeStateStatus (BLOCKED = required checks or reviews outstanding). The fix is to carry mergeStateStatus into PullRequestDetail, add a "blocked" status ("Waiting on required checks/reviews"), and gate the main Merge button on it unless viewerCanMergeAsAdmin (GitHub's bypass). That means new strings and a product call on admin bypass, so it is kept out of this PR.
  • v1 PRButton could use gh 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 viewerDefaultMergeMethod in the query it already makes, exposed as a new additive mergeability.defaultMergeMethod field.
  • A shared mergeMethodChoices helper 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.