From 8eb291f918afffef2c579aa8ff4b0fa313d1099d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Sat, 11 May 2024 10:44:52 +0800 Subject: [PATCH] feat: create_pull_url --- metagpt/tools/libs/git.py | 7 ++-- metagpt/utils/git_repository.py | 52 +++++++++++++++++++++------- tests/metagpt/tools/libs/test_git.py | 34 ++++++++++++++++++ 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/metagpt/tools/libs/git.py b/metagpt/tools/libs/git.py index aa701e49b..74d427e24 100644 --- a/metagpt/tools/libs/git.py +++ b/metagpt/tools/libs/git.py @@ -175,9 +175,12 @@ async def git_create_pull( >>> body=body, >>> access_token=access_token, >>> ) - >>> print(pr) + >>> if isinstance(pr, PullRequest): + >>> print(pr) PullRequest("feat: modify http lib") - + >>> elif isinstance(pr, str) + >>> print(f"Visit this url to create a new pull request: {pr}") + Visit this url to create a new pull request: https://github.com/geekan/MetaGPT/compare/master...iorisa:MetaGPT:dev Returns: PullRequest: The created pull request. diff --git a/metagpt/utils/git_repository.py b/metagpt/utils/git_repository.py index 3c45c4085..808ad3737 100644 --- a/metagpt/utils/git_repository.py +++ b/metagpt/utils/git_repository.py @@ -14,7 +14,7 @@ import uuid from enum import Enum from pathlib import Path from subprocess import TimeoutExpired -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Union from git.repo import Repo from git.repo.fun import is_git_dir @@ -456,7 +456,7 @@ class GitRepository: issue: Optional[Issue] = None, access_token: Optional[str] = None, auth: Optional[Auth] = None, - ) -> PullRequest: + ) -> Union[PullRequest, str]: """ Creates a pull request in the specified repository. @@ -505,17 +505,26 @@ class GitRepository: issue=issue, ) else: - head_branch = base_repo.get_branch(base) - base_branch = head_repo.get_branch(head) - pr = base_repo.create_pull( - base=base_branch.name, - head=head_branch.commit.sha, - title=title, - body=body, - maintainer_can_modify=maintainer_can_modify, - draft=draft, - issue=issue, - ) + base_branch = base_repo.get_branch(base) + head_branch = head_repo.get_branch(head) + try: + pr = base_repo.create_pull( + base=base_branch.name, + head=f"{head_repo.full_name}:{head_branch.name}", + title=title, + body=body, + maintainer_can_modify=maintainer_can_modify, + draft=draft, + issue=issue, + ) + except Exception as e: + logger.warning(f"Pull Request Error: {e}") + return GitRepository.create_pull_url( + clone_url=base_repo.clone_url, + base=base_branch.name, + head=head_branch.name, + head_repo_name=head_repo.full_name, + ) return pr @staticmethod @@ -594,3 +603,20 @@ class GitRepository: user = git.get_user() v = user.get_repos(visibility="public") return [i.full_name for i in v] + + @staticmethod + def create_pull_url(clone_url: str, base: str, head: str, head_repo_name: str = None) -> str: + """ + Create a URL for comparing changes between branches or repositories on GitHub. + + Args: + clone_url (str): The URL used for cloning the repository, ending with '.git'. + base (str): The base branch or commit. + head (str): The head branch or commit. + head_repo_name (str): The name of the repository for the head branch. If not provided, assumes the same repository. + + Returns: + str: The URL for comparing changes between the specified branches or commits. + """ + url = clone_url.removesuffix(".git") + f"/compare/{base}..." + head_repo_name.replace("/", ":") + ":" + head + return url diff --git a/tests/metagpt/tools/libs/test_git.py b/tests/metagpt/tools/libs/test_git.py index c96a3eb46..27ac3c234 100644 --- a/tests/metagpt/tools/libs/test_git.py +++ b/tests/metagpt/tools/libs/test_git.py @@ -91,6 +91,39 @@ async def test_new_pr(): assert pr +# @pytest.mark.skip +@pytest.mark.asyncio +async def test_new_pr1(): + body = """ + >>> SUMMARY + >>> Change HTTP library used to send requests + >>> + >>> TESTS + >>> - [x] Send 'GET' request + >>> - [x] Send 'POST' request with/without body + """ + pr = await GitRepository.create_pull( + base_repo_name="iorisa/MetaGPT", + base="fixbug/vscode", + head_repo_name="send18/MetaGPT", + head="dev", + title="Test pr", + body=body, + access_token=await get_env(key="access_token", app_name="github"), + ) + # pr = await GitRepository.create_pull( + # head_repo_name="iorisa/MetaGPT", + # head="fixbug/vscode", + # base_repo_name="send18/MetaGPT", + # base="dev", + # title="Test pr", + # body=body, + # access_token=await get_env(key="access_token", app_name="github"), + # ) + print(pr) + assert pr + + @pytest.mark.skip @pytest.mark.asyncio async def test_auth(): @@ -124,6 +157,7 @@ async def test_github(context): assert pr +@pytest.mark.skip @pytest.mark.asyncio @pytest.mark.parametrize( "content",