Skip to content

Commit 10e3efa

Browse files
authored
- feat: add merge_pr method and corresponding async tool for GitHub PR merging (#105)
- chore: update dependencies and version numbers in project files
1 parent 8b7ccd2 commit 10e3efa

File tree

5 files changed

+102
-39
lines changed

5 files changed

+102
-39
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "mcp-github-pr-issue-analyser"
3-
version = "2.7.0"
3+
version = "2.8.0"
44
description = "MCP GitHub Issues Create/Update and PR Analyse"
55
readme = "README.md"
66
requires-python = ">=3.12"
@@ -10,7 +10,7 @@ authors = [
1010
dependencies = [
1111
"mcp[cli]==1.13.1",
1212
"requests==2.32.5",
13-
"uv==0.8.15",
13+
"uv==0.8.17",
1414
]
1515

1616
[project.scripts]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
-i https://pypi.org/simple
22
mcp[cli]==1.13.1
33
requests==2.32.5
4-
uv==0.8.15
4+
uv==0.8.17

src/mcp_github/github_integration.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,43 @@ def create_issue(self, repo_owner: str, repo_name: str, title: str, body: str, l
367367
traceback.print_exc()
368368
return None
369369

370+
def merge_pr(self, repo_owner: str, repo_name: str, pr_number: int, commit_title: Optional[str] = None, commit_message: Optional[str] = None, merge_method: Literal['merge', 'squash', 'rebase'] = 'squash') -> Dict[str, Any]:
371+
"""
372+
Merges a pull request in the specified GitHub repository.
373+
Args:
374+
repo_owner (str): The owner of the repository.
375+
repo_name (str): The name of the repository.
376+
pr_number (int): The pull request number to merge.
377+
commit_title (str, optional): The title for the merge commit. Defaults to None.
378+
commit_message (str, optional): The message for the merge commit. Defaults to None.
379+
merge_method (Literal['merge', 'squash', 'rebase'], optional): The merge method to use ('merge', 'squash', or 'rebase'). Defaults to 'squash'.
380+
Returns:
381+
Dict[str, Any]: The JSON response from the GitHub API containing merge information if successful.
382+
Error Handling:
383+
Logs errors and prints the traceback if the merge fails, returning None.
384+
"""
385+
logging.info(f"Merging PR {repo_owner}/{repo_name}#{pr_number}")
386+
387+
# Construct the merge URL
388+
merge_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/pulls/{pr_number}/merge"
389+
390+
try:
391+
response = requests.put(merge_url, headers=self._get_headers(), json={
392+
'commit_title': commit_title,
393+
'commit_message': commit_message,
394+
'merge_method': merge_method
395+
})
396+
response.raise_for_status()
397+
merge_data = response.json()
398+
399+
logging.info(f"PR merged successfully")
400+
return merge_data
401+
402+
except Exception as e:
403+
logging.error({"status": "error", "message": str(e)})
404+
traceback.print_exc()
405+
return {"status": "error", "message": str(e)}
406+
370407
def update_issue(self, repo_owner: str, repo_name: str, issue_number: int, title: str, body: str, labels: list[str] = [], state: Literal['open', 'closed'] = 'open') -> Dict[str, Any]:
371408
"""
372409
Updates an existing GitHub issue with the specified parameters.

src/mcp_github/issues_pr_analyser.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,32 @@ async def create_github_issue(repo_owner: str, repo_name: str, title: str, body:
267267
traceback.print_exc(file=sys.stderr)
268268
return {"status": "error", "message": error_msg}
269269

270+
@self.mcp.tool()
271+
async def github_merge_pr(repo_owner: str, repo_name: str, pr_number: int, commit_title: str, commit_message: str, merge_method: Literal['merge', 'squash', 'rebase'] = 'squash') -> dict[str, Any]:
272+
"""
273+
Merges a pull request on GitHub using the specified merge method.
274+
Args:
275+
repo_owner (str): The owner of the GitHub repository.
276+
repo_name (str): The name of the GitHub repository.
277+
pr_number (int): The pull request number to merge.
278+
commit_title (str): The title for the merge commit.
279+
commit_message (str): The message for the merge commit.
280+
merge_method (Literal['merge', 'squash', 'rebase']): The method to use for merging the pull request. Defaults to 'squash'.
281+
Returns:
282+
dict[str, Any]: A dictionary containing the status and message of the merge operation.
283+
Returns a success message if the pull request is merged successfully, or an error message if an exception occurs.
284+
"""
285+
logging.info(f"Merging PR #{pr_number} using {merge_method} method")
286+
try:
287+
self.gi.merge_pr(repo_owner, repo_name, pr_number, commit_title, commit_message, merge_method)
288+
logging.info({"status": "success", "message": f"Successfully merged PR #{pr_number}"})
289+
return {"status": "success", "message": f"Successfully merged PR #{pr_number}"}
290+
except Exception as e:
291+
error_msg = f"Error merging PR: {str(e)}"
292+
logging.error(error_msg)
293+
traceback.print_exc(file=sys.stderr)
294+
return {"status": "error", "message": error_msg}
295+
270296
@self.mcp.tool()
271297
async def update_github_issue(repo_owner: str, repo_name: str, issue_number: int, title: str, body: str, labels: list[str], state: str) -> dict[str, Any]:
272298
"""

0 commit comments

Comments
 (0)