Support adding / removing reaction from comments in GitHub different servers

This commit is contained in:
Ori Kotek
2023-08-07 16:18:08 +03:00
parent 8f751f7371
commit 886139c6b5
7 changed files with 57 additions and 3 deletions

View File

@ -89,6 +89,12 @@ class BitbucketProvider:
def get_issue_comments(self): def get_issue_comments(self):
raise NotImplementedError("Bitbucket provider does not support issue comments yet") 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 @staticmethod
def _parse_pr_url(pr_url: str) -> Tuple[str, int]: def _parse_pr_url(pr_url: str) -> Tuple[str, int]:
parsed_url = urlparse(pr_url) parsed_url = urlparse(pr_url)

View File

@ -3,6 +3,7 @@ from dataclasses import dataclass
# enum EDIT_TYPE (ADDED, DELETED, MODIFIED, RENAMED) # enum EDIT_TYPE (ADDED, DELETED, MODIFIED, RENAMED)
from enum import Enum from enum import Enum
from typing import Optional
class EDIT_TYPE(Enum): class EDIT_TYPE(Enum):
@ -88,6 +89,13 @@ class GitProvider(ABC):
def get_issue_comments(self): def get_issue_comments(self):
pass 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: def get_main_pr_language(languages, files) -> str:
""" """

View File

@ -2,10 +2,10 @@ import logging
import hashlib import hashlib
from datetime import datetime from datetime import datetime
from typing import Optional, Tuple from typing import Optional, Tuple, Any
from urllib.parse import urlparse 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 retry import retry
from starlette_context import context from starlette_context import context
@ -263,6 +263,23 @@ class GithubProvider(GitProvider):
except Exception: except Exception:
return "" 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 @staticmethod
def _parse_pr_url(pr_url: str) -> Tuple[str, int]: def _parse_pr_url(pr_url: str) -> Tuple[str, int]:
parsed_url = urlparse(pr_url) parsed_url = urlparse(pr_url)

View File

@ -287,6 +287,12 @@ class GitLabProvider(GitProvider):
except Exception: except Exception:
return "" 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]: def _parse_merge_request_url(self, merge_request_url: str) -> Tuple[str, int]:
parsed_url = urlparse(merge_request_url) parsed_url = urlparse(merge_request_url)

View File

@ -4,6 +4,7 @@ import os
from pr_agent.agent.pr_agent import PRAgent from pr_agent.agent.pr_agent import PRAgent
from pr_agent.config_loader import get_settings 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 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") pr_url = event_payload.get("issue", {}).get("pull_request", {}).get("url")
if pr_url: if pr_url:
body = comment_body.strip().lower() 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) await PRAgent().handle_request(pr_url, body)
if added_reaction:
provider.remove_reaction(comment_id, added_reaction)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -11,6 +11,7 @@ from starlette_context.middleware import RawContextMiddleware
from pr_agent.agent.pr_agent import PRAgent from pr_agent.agent.pr_agent import PRAgent
from pr_agent.config_loader import get_settings, global_settings 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 from pr_agent.servers.utils import verify_signature
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
@ -80,7 +81,13 @@ async def handle_request(body: Dict[str, Any]):
return {} return {}
pull_request = body["issue"]["pull_request"] pull_request = body["issue"]["pull_request"]
api_url = pull_request.get("url") 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) 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: elif action == "opened" or 'reopened' in action:
pull_request = body.get("pull_request") pull_request = body.get("pull_request")

View File

@ -98,8 +98,12 @@ async def polling_loop():
if user_tag not in comment_body: if user_tag not in comment_body:
continue continue
rest_of_comment = comment_body.split(user_tag)[1].strip() 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) success = await agent.handle_request(pr_url, rest_of_comment)
if added_reaction:
git_provider.remove_reaction(comment_id, added_reaction)
if not success: if not success:
git_provider.set_pr(pr_url) git_provider.set_pr(pr_url)
git_provider.publish_comment("### How to use PR-Agent\n" + git_provider.publish_comment("### How to use PR-Agent\n" +