From 755165e90ccdfa390e22d615cfcfef3d204403ca Mon Sep 17 00:00:00 2001 From: FabrizioCafolla Date: Thu, 3 Jul 2025 15:47:30 +0200 Subject: [PATCH 1/4] feat: add eyes reacrtion to gitlab provider --- pr_agent/git_providers/gitlab_provider.py | 45 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index 8cfe05f6..9ea65004 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -560,11 +560,52 @@ class GitLabProvider(GitProvider): def get_workspace_name(self): return self.id_project.split('/')[0] + def add_eyes_reaction(self, issue_comment_id: int, disable_eyes: bool = False) -> Optional[int]: - return True + if disable_eyes: + return None + try: + if not self.id_mr: + get_logger().warning("Cannot add eyes reaction: merge request ID is not set.") + return None + + mr = self.gl.projects.get(self.id_project).mergerequests.get(self.id_mr) + comment = mr.notes.get(issue_comment_id) + + if not comment: + get_logger().warning(f"Comment with ID {issue_comment_id} not found in merge request {self.id_mr}.") + return None + + return comment.awardemojis.create({ + 'name': 'eyes' + }).get_id() + except Exception as e: + get_logger().warning(f"Failed to add eyes reaction, error: {e}") + return None def remove_reaction(self, issue_comment_id: int, reaction_id: int) -> bool: - return True + try: + if not self.id_mr: + get_logger().warning("Cannot remove reaction: merge request ID is not set.") + return False + + mr = self.gl.projects.get(self.id_project).mergerequests.get(self.id_mr) + comment = mr.notes.get(issue_comment_id) + + if not comment: + get_logger().warning(f"Comment with ID {issue_comment_id} not found in merge request {self.id_mr}.") + return False + + reaction = comment.awardemojis.get(reaction_id) + if reaction: + reaction.delete() + return True + else: + get_logger().warning(f"Reaction with ID {reaction_id} not found in comment {issue_comment_id}.") + return False + except Exception as e: + get_logger().warning(f"Failed to remove reaction, error: {e}") + return False def _parse_merge_request_url(self, merge_request_url: str) -> Tuple[str, int]: parsed_url = urlparse(merge_request_url) From 6f7d81b086025c49339d29250141bafed06acb0b Mon Sep 17 00:00:00 2001 From: FabrizioCafolla Date: Mon, 21 Jul 2025 16:24:17 +0200 Subject: [PATCH 2/4] update --- pr_agent/git_providers/gitlab_provider.py | 17 +++++++++-------- pr_agent/servers/gitlab_webhook.py | 10 ++++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index 9ea65004..bdcd0ab6 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -583,7 +583,7 @@ class GitLabProvider(GitProvider): get_logger().warning(f"Failed to add eyes reaction, error: {e}") return None - def remove_reaction(self, issue_comment_id: int, reaction_id: int) -> bool: + def remove_reaction(self, issue_comment_id: int, reaction_id: str) -> bool: try: if not self.id_mr: get_logger().warning("Cannot remove reaction: merge request ID is not set.") @@ -596,13 +596,14 @@ class GitLabProvider(GitProvider): get_logger().warning(f"Comment with ID {issue_comment_id} not found in merge request {self.id_mr}.") return False - reaction = comment.awardemojis.get(reaction_id) - if reaction: - reaction.delete() - return True - else: - get_logger().warning(f"Reaction with ID {reaction_id} not found in comment {issue_comment_id}.") - return False + reactions = comment.awardemojis.list() + for reaction in reactions: + if reaction.name == reaction_id: + reaction.delete() + return True + + get_logger().warning(f"Reaction '{reaction_id}' not found in comment {issue_comment_id}.") + return False except Exception as e: get_logger().warning(f"Failed to remove reaction, error: {e}") return False diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index 69187530..37e95f66 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -18,6 +18,7 @@ from pr_agent.config_loader import get_settings, global_settings from pr_agent.git_providers.utils import apply_repo_settings from pr_agent.log import LoggingFormat, get_logger, setup_logger from pr_agent.secret_providers import get_secret_provider +from pr_agent.git_providers import get_git_provider_with_context setup_logger(fmt=LoggingFormat.JSON, level=get_settings().get("CONFIG.LOG_LEVEL", "DEBUG")) router = APIRouter() @@ -25,15 +26,14 @@ router = APIRouter() secret_provider = get_secret_provider() if get_settings().get("CONFIG.SECRET_PROVIDER") else None -async def handle_request(api_url: str, body: str, log_context: dict, sender_id: str): +async def handle_request(api_url: str, body: str, log_context: dict, sender_id: str, notify=None): log_context["action"] = body log_context["event"] = "pull_request" if body == "/review" else "comment" log_context["api_url"] = api_url log_context["app_name"] = get_settings().get("CONFIG.APP_NAME", "Unknown") with get_logger().contextualize(**log_context): - await PRAgent().handle_request(api_url, body) - + await PRAgent().handle_request(api_url, body, notify) async def _perform_commands_gitlab(commands_conf: str, agent: PRAgent, api_url: str, log_context: dict, data: dict): @@ -259,13 +259,15 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): if 'merge_request' in data: mr = data['merge_request'] url = mr.get('url') + comment_id = data.get('object_attributes', {}).get('id') + provider = get_git_provider_with_context(pr_url=url) get_logger().info(f"A comment has been added to a merge request: {url}") body = data.get('object_attributes', {}).get('note') if data.get('object_attributes', {}).get('type') == 'DiffNote' and '/ask' in body: # /ask_line body = handle_ask_line(body, data) - await handle_request(url, body, log_context, sender_id) + await handle_request(url, body, log_context, sender_id, notify=lambda: provider.add_eyes_reaction(comment_id)) background_tasks.add_task(inner, request_json) end_time = datetime.now() From 3efe091bc8fb92fadc1d8e06d41dba492ea08c52 Mon Sep 17 00:00:00 2001 From: FabrizioCafolla Date: Tue, 22 Jul 2025 15:18:02 +0200 Subject: [PATCH 3/4] update --- pr_agent/git_providers/gitlab_provider.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index bdcd0ab6..c8d5ab22 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -576,9 +576,10 @@ class GitLabProvider(GitProvider): get_logger().warning(f"Comment with ID {issue_comment_id} not found in merge request {self.id_mr}.") return None - return comment.awardemojis.create({ + award_emoji = comment.awardemojis.create({ 'name': 'eyes' - }).get_id() + }) + return award_emoji.id except Exception as e: get_logger().warning(f"Failed to add eyes reaction, error: {e}") return None From 6aa26d8c56ced909892976f732b88387470b0514 Mon Sep 17 00:00:00 2001 From: ofir-frd Date: Sun, 3 Aug 2025 17:43:18 +0300 Subject: [PATCH 4/4] fix: remove extra blank line in gitlab provider --- pr_agent/git_providers/gitlab_provider.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index c8d5ab22..e8eb2c97 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -560,7 +560,6 @@ class GitLabProvider(GitProvider): def get_workspace_name(self): return self.id_project.split('/')[0] - def add_eyes_reaction(self, issue_comment_id: int, disable_eyes: bool = False) -> Optional[int]: if disable_eyes: return None