mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-03 04:10:49 +08:00
Support adding / removing reaction from comments in GitHub different servers
This commit is contained in:
@ -89,6 +89,12 @@ class BitbucketProvider:
|
||||
def get_issue_comments(self):
|
||||
raise NotImplementedError("Bitbucket provider does not support issue comments yet")
|
||||
|
||||
def add_eyes_reaction(self, issue_comment_id: int) -> Optional[int]:
|
||||
return True
|
||||
|
||||
def remove_reaction(self, issue_comment_id: int, reaction_id: int) -> bool:
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def _parse_pr_url(pr_url: str) -> Tuple[str, int]:
|
||||
parsed_url = urlparse(pr_url)
|
||||
|
@ -3,6 +3,7 @@ from dataclasses import dataclass
|
||||
|
||||
# enum EDIT_TYPE (ADDED, DELETED, MODIFIED, RENAMED)
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class EDIT_TYPE(Enum):
|
||||
@ -88,6 +89,13 @@ class GitProvider(ABC):
|
||||
def get_issue_comments(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_eyes_reaction(self, issue_comment_id: int) -> Optional[int]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def remove_reaction(self, issue_comment_id: int, reaction_id: int) -> bool:
|
||||
pass
|
||||
|
||||
def get_main_pr_language(languages, files) -> str:
|
||||
"""
|
||||
|
@ -2,10 +2,10 @@ import logging
|
||||
import hashlib
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional, Tuple
|
||||
from typing import Optional, Tuple, Any
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from github import AppAuthentication, Auth, Github, GithubException
|
||||
from github import AppAuthentication, Auth, Github, GithubException, Reaction
|
||||
from retry import retry
|
||||
from starlette_context import context
|
||||
|
||||
@ -263,6 +263,23 @@ class GithubProvider(GitProvider):
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
def add_eyes_reaction(self, issue_comment_id: int) -> Optional[int]:
|
||||
try:
|
||||
reaction = self.pr.get_issue_comment(issue_comment_id).create_reaction("eyes")
|
||||
return reaction.id
|
||||
except Exception as e:
|
||||
logging.exception(f"Failed to add eyes reaction, error: {e}")
|
||||
return None
|
||||
|
||||
def remove_reaction(self, issue_comment_id: int, reaction_id: int) -> bool:
|
||||
try:
|
||||
self.pr.get_issue_comment(issue_comment_id).delete_reaction(reaction_id)
|
||||
return True
|
||||
except Exception as e:
|
||||
logging.exception(f"Failed to remove eyes reaction, error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _parse_pr_url(pr_url: str) -> Tuple[str, int]:
|
||||
parsed_url = urlparse(pr_url)
|
||||
|
@ -287,6 +287,12 @@ class GitLabProvider(GitProvider):
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
def add_eyes_reaction(self, issue_comment_id: int) -> Optional[int]:
|
||||
return True
|
||||
|
||||
def remove_reaction(self, issue_comment_id: int, reaction_id: int) -> bool:
|
||||
return True
|
||||
|
||||
def _parse_merge_request_url(self, merge_request_url: str) -> Tuple[str, int]:
|
||||
parsed_url = urlparse(merge_request_url)
|
||||
|
||||
|
@ -4,6 +4,7 @@ import os
|
||||
|
||||
from pr_agent.agent.pr_agent import PRAgent
|
||||
from pr_agent.config_loader import get_settings
|
||||
from pr_agent.git_providers import get_git_provider
|
||||
from pr_agent.tools.pr_reviewer import PRReviewer
|
||||
|
||||
|
||||
@ -61,7 +62,12 @@ async def run_action():
|
||||
pr_url = event_payload.get("issue", {}).get("pull_request", {}).get("url")
|
||||
if pr_url:
|
||||
body = comment_body.strip().lower()
|
||||
comment_id = event_payload.get("comment", {}).get("id")
|
||||
provider = get_git_provider()(pr_url=pr_url)
|
||||
added_reaction = provider.add_eyes_reaction(comment_id)
|
||||
await PRAgent().handle_request(pr_url, body)
|
||||
if added_reaction:
|
||||
provider.remove_reaction(comment_id, added_reaction)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -11,6 +11,7 @@ from starlette_context.middleware import RawContextMiddleware
|
||||
|
||||
from pr_agent.agent.pr_agent import PRAgent
|
||||
from pr_agent.config_loader import get_settings, global_settings
|
||||
from pr_agent.git_providers import get_git_provider
|
||||
from pr_agent.servers.utils import verify_signature
|
||||
|
||||
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
|
||||
@ -80,7 +81,13 @@ async def handle_request(body: Dict[str, Any]):
|
||||
return {}
|
||||
pull_request = body["issue"]["pull_request"]
|
||||
api_url = pull_request.get("url")
|
||||
comment_id = body.get("comment", {}).get("id")
|
||||
provider = get_git_provider()(pr_url=api_url)
|
||||
added_reaction = provider.add_eyes_reaction(comment_id)
|
||||
await agent.handle_request(api_url, comment_body)
|
||||
if added_reaction:
|
||||
provider.remove_reaction(comment_id, added_reaction)
|
||||
|
||||
|
||||
elif action == "opened" or 'reopened' in action:
|
||||
pull_request = body.get("pull_request")
|
||||
|
@ -98,8 +98,12 @@ async def polling_loop():
|
||||
if user_tag not in comment_body:
|
||||
continue
|
||||
rest_of_comment = comment_body.split(user_tag)[1].strip()
|
||||
|
||||
comment_id = comment['id']
|
||||
git_provider.set_pr(pr_url)
|
||||
added_reaction = git_provider.add_eyes_reaction(comment_id)
|
||||
success = await agent.handle_request(pr_url, rest_of_comment)
|
||||
if added_reaction:
|
||||
git_provider.remove_reaction(comment_id, added_reaction)
|
||||
if not success:
|
||||
git_provider.set_pr(pr_url)
|
||||
git_provider.publish_comment("### How to use PR-Agent\n" +
|
||||
|
Reference in New Issue
Block a user