@@ -2125,6 +2125,9 @@ def merge_pull_request(
21252125
21262126 This method is idempotent - if the PR is already merged, it returns True.
21272127
2128+ If the requested merge method is not allowed by repository settings,
2129+ this will automatically try alternative methods in order: squash, rebase.
2130+
21282131 Args:
21292132 repo_full_name: Repository in "owner/repo" format
21302133 pr_number: PR number to merge
@@ -2149,24 +2152,56 @@ def merge_pull_request(
21492152 console .print (f"[yellow]Warning: PR #{ pr_number } is { pr .state } , cannot merge[/yellow]" )
21502153 return False
21512154
2152- # Merge the PR - only pass non-None parameters
2153- merge_kwargs = {"merge_method" : merge_method }
2154- if commit_title is not None :
2155- merge_kwargs ["commit_title" ] = commit_title
2156- if commit_message is not None :
2157- merge_kwargs ["commit_message" ] = commit_message
2155+ # Try to merge with fallback strategies
2156+ # Order: requested method first, then try alternatives if 405 (method not allowed)
2157+ methods_to_try = [merge_method ]
21582158
2159- result = pr .merge (** merge_kwargs )
2159+ # Add fallback methods if primary fails
2160+ for fallback in ["squash" , "rebase" , "merge" ]:
2161+ if fallback not in methods_to_try :
2162+ methods_to_try .append (fallback )
21602163
2161- if result .merged :
2162- console .print (f"[green]✓ Merged PR #{ pr_number } : { pr .title } [/green]" )
2163- return True
2164- else :
2165- console .print (f"[red]Failed to merge PR #{ pr_number } : { result .message } [/red]" )
2166- return False
2164+ last_error = None
2165+ for method in methods_to_try :
2166+ try :
2167+ # Merge the PR - only pass non-None parameters
2168+ merge_kwargs = {"merge_method" : method }
2169+ if commit_title is not None :
2170+ merge_kwargs ["commit_title" ] = commit_title
2171+ if commit_message is not None :
2172+ merge_kwargs ["commit_message" ] = commit_message
2173+
2174+ result = pr .merge (** merge_kwargs )
2175+
2176+ if result .merged :
2177+ if method != merge_method :
2178+ console .print (f"[yellow]Note: Used '{ method } ' merge method ('{ merge_method } ' not allowed by repository settings)[/yellow]" )
2179+ console .print (f"[green]✓ Merged PR #{ pr_number } : { pr .title } [/green]" )
2180+ return True
2181+ else :
2182+ console .print (f"[red]Failed to merge PR #{ pr_number } : { result .message } [/red]" )
2183+ return False
2184+
2185+ except GithubException as e :
2186+ # Check if this is a "method not allowed" error (405)
2187+ if e .status == 405 and "not allowed" in str (e ).lower ():
2188+ # Try next method
2189+ last_error = e
2190+ continue
2191+ else :
2192+ # Different error, don't retry
2193+ raise
2194+
2195+ # All methods failed
2196+ auth_user = self .get_authenticated_user ()
2197+ user_info = f" (authenticated as @{ auth_user } )" if auth_user else ""
2198+ console .print (f"[red]Error merging PR #{ pr_number } { user_info } : { last_error } [/red]" )
2199+ return False
21672200
21682201 except GithubException as e :
2169- console .print (f"[red]Error merging PR #{ pr_number } : { e } [/red]" )
2202+ auth_user = self .get_authenticated_user ()
2203+ user_info = f" (authenticated as @{ auth_user } )" if auth_user else ""
2204+ console .print (f"[red]Error merging PR #{ pr_number } { user_info } : { e } [/red]" )
21702205 return False
21712206
21722207 def close_issue (
@@ -2207,7 +2242,9 @@ def close_issue(
22072242 return True
22082243
22092244 except GithubException as e :
2210- console .print (f"[red]Error closing issue #{ issue_number } : { e } [/red]" )
2245+ auth_user = self .get_authenticated_user ()
2246+ user_info = f" (authenticated as @{ auth_user } )" if auth_user else ""
2247+ console .print (f"[red]Error closing issue #{ issue_number } { user_info } : { e } [/red]" )
22112248 return False
22122249
22132250 def close_pull_request (
@@ -2248,7 +2285,9 @@ def close_pull_request(
22482285 return True
22492286
22502287 except GithubException as e :
2251- console .print (f"[red]Error closing PR #{ pr_number } : { e } [/red]" )
2288+ auth_user = self .get_authenticated_user ()
2289+ user_info = f" (authenticated as @{ auth_user } )" if auth_user else ""
2290+ console .print (f"[red]Error closing PR #{ pr_number } { user_info } : { e } [/red]" )
22522291 return False
22532292
22542293 def delete_branch (
@@ -2284,7 +2323,9 @@ def delete_branch(
22842323 raise
22852324
22862325 except GithubException as e :
2287- console .print (f"[red]Error deleting branch '{ branch_name } ': { e } [/red]" )
2326+ auth_user = self .get_authenticated_user ()
2327+ user_info = f" (authenticated as @{ auth_user } )" if auth_user else ""
2328+ console .print (f"[red]Error deleting branch '{ branch_name } '{ user_info } : { e } [/red]" )
22882329 return False
22892330
22902331 def delete_tag (
@@ -2344,7 +2385,9 @@ def delete_tag(
23442385 raise
23452386
23462387 except GithubException as e :
2347- console .print (f"[red]Error deleting tag '{ tag_name } ': { e } [/red]" )
2388+ auth_user = self .get_authenticated_user ()
2389+ user_info = f" (authenticated as @{ auth_user } )" if auth_user else ""
2390+ console .print (f"[red]Error deleting tag '{ tag_name } '{ user_info } : { e } [/red]" )
23482391 return False
23492392
23502393 def delete_release (
@@ -2379,7 +2422,9 @@ def delete_release(
23792422 return True
23802423
23812424 except GithubException as e :
2382- console .print (f"[red]Error deleting release '{ tag_name } ': { e } [/red]" )
2425+ auth_user = self .get_authenticated_user ()
2426+ user_info = f" (authenticated as @{ auth_user } )" if auth_user else ""
2427+ console .print (f"[red]Error deleting release '{ tag_name } '{ user_info } : { e } [/red]" )
23832428 return False
23842429
23852430 def find_prs_referencing_issue (
0 commit comments