Skip to content

fix(desktop): respect repository merge settings in PR merge menus - #6228

Open
abcdlsj wants to merge 4 commits into
ParadevAI:mainfrom
abcdlsj:fix/issue-6185-merge-settings
Open

abcdlsj wants to merge 4 commits into
ParadevAI:mainfrom
abcdlsj:fix/issue-6185-merge-settings

Conversation

@abcdlsj

@abcdlsj abcdlsj commented Aug 6, 2026 •

Copy link
Copy Markdown

Design

Both pull request merge menus use the same pure merge-method selection logic and the same capability mapping.

  • @superset/shared/github-merge-methods owns the supported method set, REST-to-canonical capability normalization, and explicit-disabled check.
  • The renderer uses that capability check while filtering methods and keeps the viewer default first when it is enabled.
  • v2 reads repository capabilities through github.getRepo; v1 reads the equivalent fields through gh repo view, resolving fork worktrees to their upstream repository.
  • Both merge mutations reject a method only when GitHub explicitly reports it as disabled. Missing, incomplete, or failed settings lookups remain fail-open, preserving the existing merge behavior.
  • No database schema changes are required.

Validation

  • Shared capability tests: 2 passing
  • Merge menu tests: 4 passing
  • v1 merge router tests: 3 passing
  • GitHub router integration tests: 10 passing
  • Existing v1 merge utility tests: 3 passing
  • Biome lint and format checks: passing
  • Shared and host-service typechecks: passing
  • Desktop typecheck remains blocked by the workspace's missing @sentry/electron/main and @sentry/electron/renderer modules.

Closes #6185

Summary by CodeRabbit

  • New Features

    • Pull request merge menus now reflect the repository’s enabled merge methods.
    • The viewer’s preferred merge method is prioritized when available.
    • Merge method labels and selections are consistent across pull request interfaces.
    • Unavailable repository settings fall back to standard merge options.
  • Bug Fixes

    • Disabled merge methods are no longer displayed or accepted for merging.
  • Tests

    • Added coverage for repository-specific methods, defaults, fallbacks, and disabled options.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR retrieves repository merge capabilities, normalizes merge methods, updates both pull request merge menus, and rejects explicitly disabled methods before merging. It preserves merge behavior when capability retrieval fails.

Changes

Repository merge settings

Layer / File(s) Summary
Merge settings retrieval
apps/desktop/src/lib/trpc/routers/changes/git-operations.ts, apps/desktop/src/lib/trpc/routers/workspaces/utils/github/*, packages/host-service/src/trpc/router/github/github.ts, packages/host-service/test/integration/github-mocked.integration.test.ts
GitHub merge capabilities are validated and exposed through getMergeSettings. Repository data includes the viewer default merge method. Integration tests cover retrieval and fallback behavior.
Merge method normalization
packages/shared/src/github-merge-methods.ts, packages/shared/src/github-merge-methods.test.ts, packages/shared/package.json, apps/desktop/src/renderer/lib/githubMergeMethods/*
Shared definitions normalize REST capabilities, detect explicitly disabled methods, filter available methods, and prioritize a valid default. Unit tests cover these rules.
Pull request merge menus
apps/desktop/src/renderer/routes/.../PRStatusGroup/PRStatusGroup.tsx, apps/desktop/src/renderer/screens/.../PRButton/PRButton.tsx
Both merge menus query repository settings and render available methods with shared types, labels, and ordering.
Merge method validation
apps/desktop/src/lib/trpc/routers/changes/git-operations.ts, apps/desktop/src/lib/trpc/routers/changes/git-operations.merge.test.ts, packages/host-service/src/trpc/router/github/github.ts, packages/host-service/test/integration/github-mocked.integration.test.ts
Merge operations reject explicitly disabled methods before invoking GitHub. Tests verify rejection and continued merging when settings are unavailable or unknown.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant PRMergeMenu
  participant GitOperationsRouter
  participant RepoContext
  participant GitHub
  User->>PRMergeMenu: Open merge menu
  PRMergeMenu->>GitOperationsRouter: Request repository merge settings
  GitOperationsRouter->>RepoContext: Resolve and validate settings
  RepoContext->>GitHub: Query repository capabilities
  GitHub-->>RepoContext: Allowed methods and viewer default
  RepoContext-->>GitOperationsRouter: Return settings
  GitOperationsRouter-->>PRMergeMenu: Return settings
  PRMergeMenu-->>User: Show ordered available methods
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement the linked issue objectives by filtering disabled methods and prioritizing the configured repository default.
Out of Scope Changes check ✅ Passed The changes remain focused on repository merge settings, merge menus, merge validation, shared helpers, and related tests.
Title check ✅ Passed The title uses conventional commit format and clearly describes the main change: respecting repository merge settings in desktop PR merge menus.
Description check ✅ Passed The description explains the change, rationale, testing results, issue link, and known desktop typecheck limitation; only the template checklist is omitted.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR centralizes GitHub merge-method selection and adds repository capability and default lookups for both desktop merge menus.

  • Adds a shared helper that filters allowed merge methods and prioritizes the viewer default.
  • Adds v1 settings discovery through gh repo view, including upstream resolution for forks.
  • Extends the host-service repository query with the GraphQL viewer default for v2.
  • Updates both merge menus and adds helper and router coverage.

Confidence Score: 4/5

The PR should not merge until the menus stop offering repository-disabled methods while capability settings are loading or unavailable.

Both newly updated menus remain interactive before their settings queries resolve, and the shared fallback presents all merge methods, allowing users to submit requests that GitHub predictably rejects.

Files Needing Attention: apps/desktop/src/renderer/lib/githubMergeMethods/githubMergeMethods.ts and both changed merge-menu components

Important Files Changed

Filename Overview
apps/desktop/src/renderer/lib/githubMergeMethods/githubMergeMethods.ts Centralizes filtering and default ordering, but missing settings are treated as allowing every method.
apps/desktop/src/lib/trpc/routers/workspaces/utils/github/repo-context.ts Adds CLI-backed merge-settings discovery and resolves known fork contexts against the upstream repository.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/components/PRActionHeader/components/PRStatusGroup/PRStatusGroup.tsx Fetches v2 repository capabilities but keeps the merge menu actionable before the query resolves.
apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ChangesHeader/components/PRButton/PRButton.tsx Applies shared merge-method selection to v1 while exposing the same unresolved-query fallback.
packages/host-service/src/trpc/router/github/github.ts Preserves REST repository data and supplements it with a failure-tolerant GraphQL viewer default.
packages/host-service/test/integration/github-mocked.integration.test.ts Updates mocked Octokit coverage for the added GraphQL request and returned default.

Sequence Diagram

sequenceDiagram
  participant User
  participant Menu as Desktop merge menu
  participant Settings as Repository settings query
  participant GitHub
  User->>Menu: Open merge options
  Menu->>Settings: Fetch capabilities/default
  alt Settings resolved
    Settings-->>Menu: Allowed methods
    Menu-->>User: Filtered methods
  else Loading or failed
    Menu-->>User: All three methods
    User->>Menu: Select disabled method
    Menu->>GitHub: Submit merge
    GitHub-->>Menu: Reject method
  end
Loading
Prompt To Fix All With AI
### Issue 1
apps/desktop/src/renderer/lib/githubMergeMethods/githubMergeMethods.ts:50-53
**Unresolved settings enable disabled methods**

When either repository-settings query is loading or has failed, this fallback exposes all three merge methods while both menus remain interactive, allowing users to submit repository-disabled methods that GitHub rejects.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(desktop): respect repository merge s..." | Re-trigger Greptile

Comment on lines +50 to +53
): MergeMethod[] {
if (!hasCompleteMergeSettings(settings)) {
return [...MERGE_METHODS];
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Unresolved settings enable disabled methods

When either repository-settings query is loading or has failed, this fallback exposes all three merge methods while both menus remain interactive, allowing users to submit repository-disabled methods that GitHub rejects.

Knowledge Base Used: Desktop App (Electron main + renderer)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/lib/githubMergeMethods/githubMergeMethods.ts
Line: 50-53

Comment:
**Unresolved settings enable disabled methods**

When either repository-settings query is loading or has failed, this fallback exposes all three merge methods while both menus remain interactive, allowing users to submit repository-disabled methods that GitHub rejects.

**Knowledge Base Used:** [Desktop App (Electron main + renderer)](https://app.greptile.com/personal-org-6810/-/custom-context/knowledge-base/superset-sh/superset/-/docs/desktop-app.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 11 files

Architecture diagram
sequenceDiagram
    participant V2 as "Workspace Sidebar (v2 PR merge menu)"
    participant V1 as "Changes View (v1 PR merge menu)"
    participant Shared as "Shared merge-method helper"
    participant HostRouter as "Host-service githubRouter"
    participant DesktopRouter as "Desktop changes router"
    participant SettingsSvc as "getRepoMergeSettings util"
    participant RepoCtx as "GitHub repo context helper"
    participant GhCLI as "gh CLI"
    participant GH as "GitHub REST/GraphQL APIs"
    participant MergeAPI as "PR merge mutation"

    Note over V2,GH: v2 flow: REST repo settings plus GraphQL viewer default
    V2->>HostRouter: getRepo(owner, repo)
    HostRouter->>GH: octokit.repos.get(owner, repo)
    GH-->>HostRouter: allow_merge_commit / allow_rebase_merge / allow_squash_merge
    HostRouter->>GH: octokit.graphql(viewerDefaultMergeMethod)
    alt GraphQL default available
        GH-->>HostRouter: viewerDefaultMergeMethod
    else GraphQL unavailable/error
        HostRouter->>HostRouter: Keep null default, warn
    end
    HostRouter-->>V2: Repo settings + viewerDefaultMergeMethod

    Note over V1,GhCLI: v1 flow: gh repo view merge settings
    V1->>DesktopRouter: getMergeSettings(worktreePath)
    DesktopRouter->>SettingsSvc: getRepoMergeSettings(worktreePath)
    SettingsSvc->>RepoCtx: getRepoContext(worktreePath)
    RepoCtx-->>SettingsSvc: Repo context with fork upstream resolved
    SettingsSvc->>GhCLI: gh repo view (origin/upstream args) --json merge,squash,rebase,viewerDefault
    GhCLI-->>SettingsSvc: Merge settings JSON

    alt Valid settings response
        SettingsSvc->>SettingsSvc: Validate with Zod schema
        SettingsSvc-->>DesktopRouter: Normalized merge settings
    else Missing or invalid response
        SettingsSvc-->>DesktopRouter: null
    end
    DesktopRouter-->>V1: Merge settings or null

    Note over V1,Shared: Shared filtering and ordering
    V2->>Shared: getAvailableMergeMethods(settings)
    V1->>Shared: getAvailableMergeMethods(settings)

    alt Complete settings
        Shared->>Shared: Keep only allowed methods, move viewer default first if allowed
    else Incomplete or null settings
        Shared->>Shared: Keep squash, merge, rebase fallback order
    end

    Shared-->>V2: Allowed merge methods ordered
    Shared-->>V1: Allowed merge methods ordered

    Note over V2,MergeAPI: Menus render and submit only returned methods
    V2->>MergeAPI: mergePR mutation with selected mergeMethod
    V1->>MergeAPI: mergePR mutation with selected strategy
    MergeAPI-->>V2: Merge result/toast
    MergeAPI-->>V1: Merge result/toast
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/desktop/src/lib/trpc/routers/changes/git-operations.ts">

<violation number="1" location="apps/desktop/src/lib/trpc/routers/changes/git-operations.ts:322">
P3: Disabled-method enforcement has no desktop router test, so a future change could let a blocked strategy reach `mergePullRequest` or stop the intended fail-open behavior without detection. A focused test mocking `getRepoMergeSettings` for `false` and `null` responses would lock down both contracts.</violation>
</file>

<file name="packages/host-service/src/trpc/router/github/github.ts">

<violation number="1" location="packages/host-service/src/trpc/router/github/github.ts:14">
P3: This PR frames v1 and v2 around one shared method-selection helper, yet the "is this method disabled" enforcement is now implemented twice with independent field mappings: `isMergeMethodDisabled` in the host-service github router (snake_case REST fields: `allow_merge_commit`/`allow_squash_merge`/`allow_rebase_merge`) and the inline `methodDisabled` boolean chain in apps/desktop `git-operations.ts` mergePR (camelCase fields: `allowMergeCommit`/`allowSquashMerge`/`allowRebaseMerge`). Because the two copies live in separate packages and use differently-cased field names, a future change (e.g. a renamed capability or a new method) can easily make one merge menu show a method the other path rejects, or vice versa. Consider centralizing the method->capability mapping in one shared module so both routers resolve the same fields, keeping behavior consistent even though the two packages can't literally import the tRPC router.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

.mutation(
async ({ input }): Promise<{ success: boolean; mergedAt?: string }> => {
assertRegisteredWorktree(input.worktreePath);
const mergeSettings = await getRepoMergeSettings(input.worktreePath);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Disabled-method enforcement has no desktop router test, so a future change could let a blocked strategy reach mergePullRequest or stop the intended fail-open behavior without detection. A focused test mocking getRepoMergeSettings for false and null responses would lock down both contracts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/lib/trpc/routers/changes/git-operations.ts, line 322:

<comment>Disabled-method enforcement has no desktop router test, so a future change could let a blocked strategy reach `mergePullRequest` or stop the intended fail-open behavior without detection. A focused test mocking `getRepoMergeSettings` for `false` and `null` responses would lock down both contracts.</comment>

<file context>
@@ -319,6 +319,21 @@ export const createGitOperationsRouter = () => {
 			.mutation(
 				async ({ input }): Promise<{ success: boolean; mergedAt?: string }> => {
 					assertRegisteredWorktree(input.worktreePath);
+					const mergeSettings = await getRepoMergeSettings(input.worktreePath);
+					const methodDisabled =
+						(input.strategy === "merge" &&
</file context>

allow_squash_merge?: boolean | null;
}

function isMergeMethodDisabled(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This PR frames v1 and v2 around one shared method-selection helper, yet the "is this method disabled" enforcement is now implemented twice with independent field mappings: isMergeMethodDisabled in the host-service github router (snake_case REST fields: allow_merge_commit/allow_squash_merge/allow_rebase_merge) and the inline methodDisabled boolean chain in apps/desktop git-operations.ts mergePR (camelCase fields: allowMergeCommit/allowSquashMerge/allowRebaseMerge). Because the two copies live in separate packages and use differently-cased field names, a future change (e.g. a renamed capability or a new method) can easily make one merge menu show a method the other path rejects, or vice versa. Consider centralizing the method->capability mapping in one shared module so both routers resolve the same fields, keeping behavior consistent even though the two packages can't literally import the tRPC router.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/github/github.ts, line 14:

<comment>This PR frames v1 and v2 around one shared method-selection helper, yet the "is this method disabled" enforcement is now implemented twice with independent field mappings: `isMergeMethodDisabled` in the host-service github router (snake_case REST fields: `allow_merge_commit`/`allow_squash_merge`/`allow_rebase_merge`) and the inline `methodDisabled` boolean chain in apps/desktop `git-operations.ts` mergePR (camelCase fields: `allowMergeCommit`/`allowSquashMerge`/`allowRebaseMerge`). Because the two copies live in separate packages and use differently-cased field names, a future change (e.g. a renamed capability or a new method) can easily make one merge menu show a method the other path rejects, or vice versa. Consider centralizing the method->capability mapping in one shared module so both routers resolve the same fields, keeping behavior consistent even though the two packages can't literally import the tRPC router.</comment>

<file context>
@@ -1,6 +1,30 @@
+	allow_squash_merge?: boolean | null;
+}
+
+function isMergeMethodDisabled(
+	repository: RepositoryMergeCapabilities | null,
+	mergeMethod: MergeMethod,
</file context>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/lib/trpc/routers/changes/git-operations.merge.test.ts`:
- Around line 93-108: Add a test alongside “keeps the existing merge behavior
when settings are unavailable” that configures repository settings with
allowRebaseMerge set to null or omitted, then verifies caller.mergePR still
resolves successfully and mergePullRequestMock is called with the supplied
worktreePath and strategy. Ensure unknown capability values are treated as
enabled rather than blocking the merge.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3d5fba-3518-457a-a330-fe482871738f

📥 Commits

Reviewing files that changed from the base of the PR and between 6d0ff35 and 424f8e5.

📒 Files selected for processing (7)
  • apps/desktop/src/lib/trpc/routers/changes/git-operations.merge.test.ts
  • apps/desktop/src/lib/trpc/routers/changes/git-operations.ts
  • apps/desktop/src/renderer/lib/githubMergeMethods/githubMergeMethods.ts
  • packages/host-service/src/trpc/router/github/github.ts
  • packages/shared/package.json
  • packages/shared/src/github-merge-methods.test.ts
  • packages/shared/src/github-merge-methods.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/desktop/src/lib/trpc/routers/changes/git-operations.ts
  • packages/host-service/src/trpc/router/github/github.ts

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] Merge menu should respect the repository's merge settings

1 participant