From 5e1cc12df4a77ff92872bc898dba1b8e648934ca Mon Sep 17 00:00:00 2001 From: GOOD21 <41340811@qq.com> Date: Thu, 20 Feb 2025 10:47:21 +0800 Subject: [PATCH 1/3] Enhanced webhook handling for push events without object_attributes --- pr_agent/servers/gitlab_webhook.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index 6a3d6bcb..d837dae4 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -24,7 +24,6 @@ router = APIRouter() secret_provider = get_secret_provider() if get_settings().get("CONFIG.SECRET_PROVIDER") else None - async def get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id): try: import requests @@ -64,7 +63,8 @@ async def _perform_commands_gitlab(commands_conf: str, agent: PRAgent, api_url: if commands_conf == "pr_commands" and get_settings().config.disable_auto_feedback: # auto commands for PR, and auto feedback is disabled get_logger().info(f"Auto feedback is disabled, skipping auto commands for PR {api_url=}", **log_context) return - if not should_process_pr_logic(data): # Here we already updated the configurations + if commands_conf != "push_commands" and not should_process_pr_logic(data): + get_logger().info(f"Skipping auto commands for PR {api_url=}", **log_context) return commands = get_settings().get(f"gitlab.{commands_conf}", {}) get_settings().set("config.is_auto_command", True) @@ -98,6 +98,7 @@ def is_bot_user(data) -> bool: def should_process_pr_logic(data) -> bool: try: if not data.get('object_attributes', {}): + get_logger().info("No object attributes found in the data") return False title = data['object_attributes'].get('title') sender = data.get("user", {}).get("username", "") @@ -190,8 +191,9 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): # ignore bot users if is_bot_user(data): return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) - if data.get('event_type') != 'note': # not a comment + if data.get('event_type') != 'note' and data.get('object_kind') != 'push': # not a comment # ignore MRs based on title, labels, source and target branches + get_logger().info(f"Processing {data.get('object_kind')} event") if not should_process_pr_logic(data): return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) @@ -246,7 +248,6 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): get_logger().info(f"Processing time: {end_time - start_time}", request=request_json) return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) - def handle_ask_line(body, data): try: line_range_ = data['object_attributes']['position']['line_range'] From 347af1dd99305149c8217dbba6daad41b405595a Mon Sep 17 00:00:00 2001 From: GOOD21 <41340811@qq.com> Date: Fri, 21 Feb 2025 13:24:20 +0800 Subject: [PATCH 2/3] use merge_request with oldrev instead of push --- pr_agent/servers/gitlab_webhook.py | 137 +++++++++++++++++------------ 1 file changed, 79 insertions(+), 58 deletions(-) diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index d837dae4..fee6710c 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -24,28 +24,29 @@ router = APIRouter() secret_provider = get_secret_provider() if get_settings().get("CONFIG.SECRET_PROVIDER") else None -async def get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id): - try: - import requests - headers = { - 'Private-Token': f'{gitlab_token}' - } - # API endpoint to find MRs containing the commit - gitlab_url = get_settings().get("GITLAB.URL", 'https://gitlab.com') - response = requests.get( - f'{gitlab_url}/api/v4/projects/{project_id}/repository/commits/{commit_sha}/merge_requests', - headers=headers - ) - merge_requests = response.json() - if merge_requests and response.status_code == 200: - pr_url = merge_requests[0]['web_url'] - return pr_url - else: - get_logger().info(f"No merge requests found for commit: {commit_sha}") - return None - except Exception as e: - get_logger().error(f"Failed to get MR url from commit sha: {e}") - return None + +#async def get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id): +# try: +# import requests +# headers = { +# 'Private-Token': f'{gitlab_token}' +# } +# # API endpoint to find MRs containing the commit +# gitlab_url = get_settings().get("GITLAB.URL", 'https://gitlab.com') +# response = requests.get( +# f'{gitlab_url}/api/v4/projects/{project_id}/repository/commits/{commit_sha}/merge_requests', +# headers=headers +# ) +# merge_requests = response.json() +# if merge_requests and response.status_code == 200: +# pr_url = merge_requests[0]['web_url'] +# return pr_url +# else: +# get_logger().info(f"No merge requests found for commit: {commit_sha}") +# return None +# except Exception as e: +# get_logger().error(f"Failed to get MR url from commit sha: {e}") +# return None async def handle_request(api_url: str, body: str, log_context: dict, sender_id: str): log_context["action"] = body @@ -63,8 +64,7 @@ async def _perform_commands_gitlab(commands_conf: str, agent: PRAgent, api_url: if commands_conf == "pr_commands" and get_settings().config.disable_auto_feedback: # auto commands for PR, and auto feedback is disabled get_logger().info(f"Auto feedback is disabled, skipping auto commands for PR {api_url=}", **log_context) return - if commands_conf != "push_commands" and not should_process_pr_logic(data): - get_logger().info(f"Skipping auto commands for PR {api_url=}", **log_context) + if not should_process_pr_logic(data): # Here we already updated the configurations return commands = get_settings().get(f"gitlab.{commands_conf}", {}) get_settings().set("config.is_auto_command", True) @@ -98,7 +98,6 @@ def is_bot_user(data) -> bool: def should_process_pr_logic(data) -> bool: try: if not data.get('object_attributes', {}): - get_logger().info("No object attributes found in the data") return False title = data['object_attributes'].get('title') sender = data.get("user", {}).get("username", "") @@ -191,23 +190,44 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): # ignore bot users if is_bot_user(data): return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) - if data.get('event_type') != 'note' and data.get('object_kind') != 'push': # not a comment + + log_context["sender"] = sender + if data.get('object_kind') == 'merge_request': # ignore MRs based on title, labels, source and target branches - get_logger().info(f"Processing {data.get('object_kind')} event") if not should_process_pr_logic(data): return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) - log_context["sender"] = sender - if data.get('object_kind') == 'merge_request' and data['object_attributes'].get('action') in ['open', 'reopen']: - title = data['object_attributes'].get('title') - url = data['object_attributes'].get('url') - draft = data['object_attributes'].get('draft') - get_logger().info(f"New merge request: {url}") - if draft: - get_logger().info(f"Skipping draft MR: {url}") - return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) + if data['object_attributes'].get('action') in ['open', 'reopen']: + url = data['object_attributes'].get('url') + draft = data['object_attributes'].get('draft') + get_logger().info(f"New merge request: {url}") + if draft: + get_logger().info(f"Skipping draft MR: {url}") + return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) + + await _perform_commands_gitlab("pr_commands", PRAgent(), url, log_context, data) + + # for push event triggered merge requests + elif data['object_attributes'].get('action') == 'update' and data['object_attributes'].get('oldrev'): + url = data['object_attributes'].get('url') + draft = data['object_attributes'].get('draft') + get_logger().info(f"New merge request: {url}") + if draft: + get_logger().info(f"Skipping draft MR: {url}") + return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) + + # we need first to apply_repo_settings + # apply_repo_settings(url) + commands_on_push = get_settings().get(f"gitlab.push_commands", {}) + handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) + if not commands_on_push or not handle_push_trigger: + get_logger().info("Push event, but no push commands found or push trigger is disabled") + return JSONResponse(status_code=status.HTTP_200_OK, + content=jsonable_encoder({"message": "success"})) + + get_logger().debug(f'A push event has been received: {url}') + await _perform_commands_gitlab("push_commands", PRAgent(), url, log_context, data) - await _perform_commands_gitlab("pr_commands", PRAgent(), url, log_context, data) elif data.get('object_kind') == 'note' and data.get('event_type') == 'note': # comment on MR if 'merge_request' in data: mr = data['merge_request'] @@ -219,35 +239,36 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): body = handle_ask_line(body, data) await handle_request(url, body, log_context, sender_id) - elif data.get('object_kind') == 'push' and data.get('event_name') == 'push': - try: - project_id = data['project_id'] - commit_sha = data['checkout_sha'] - url = await get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id) - if not url: - get_logger().info(f"No MR found for commit: {commit_sha}") - return JSONResponse(status_code=status.HTTP_200_OK, - content=jsonable_encoder({"message": "success"})) + # elif data.get('object_kind') == 'push' and data.get('event_name') == 'push': + # try: + # project_id = data['project_id'] + # commit_sha = data['checkout_sha'] + # url = await get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id) + # if not url: + # get_logger().info(f"No MR found for commit: {commit_sha}") + # return JSONResponse(status_code=status.HTTP_200_OK, + # content=jsonable_encoder({"message": "success"})) - # we need first to apply_repo_settings - apply_repo_settings(url) - commands_on_push = get_settings().get(f"gitlab.push_commands", {}) - handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) - if not commands_on_push or not handle_push_trigger: - get_logger().info("Push event, but no push commands found or push trigger is disabled") - return JSONResponse(status_code=status.HTTP_200_OK, - content=jsonable_encoder({"message": "success"})) + # # we need first to apply_repo_settings + # apply_repo_settings(url) + # commands_on_push = get_settings().get(f"gitlab.push_commands", {}) + # handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) + # if not commands_on_push or not handle_push_trigger: + # get_logger().info("Push event, but no push commands found or push trigger is disabled") + # return JSONResponse(status_code=status.HTTP_200_OK, + # content=jsonable_encoder({"message": "success"})) - get_logger().debug(f'A push event has been received: {url}') - await _perform_commands_gitlab("push_commands", PRAgent(), url, log_context, data) - except Exception as e: - get_logger().error(f"Failed to handle push event: {e}") + # get_logger().debug(f'A push event has been received: {url}') + # await _perform_commands_gitlab("push_commands", PRAgent(), url, log_context, data) + # except Exception as e: + # get_logger().error(f"Failed to handle push event: {e}") background_tasks.add_task(inner, request_json) end_time = datetime.now() get_logger().info(f"Processing time: {end_time - start_time}", request=request_json) return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) + def handle_ask_line(body, data): try: line_range_ = data['object_attributes']['position']['line_range'] From f143a248794f597f39e190d18f1b7eb988c94b0d Mon Sep 17 00:00:00 2001 From: GOOD21 <41340811@qq.com> Date: Fri, 21 Feb 2025 13:35:48 +0800 Subject: [PATCH 3/3] remove unnecessary code --- pr_agent/servers/gitlab_webhook.py | 48 ------------------------------ 1 file changed, 48 deletions(-) diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index fee6710c..b05ddbeb 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -25,29 +25,6 @@ router = APIRouter() secret_provider = get_secret_provider() if get_settings().get("CONFIG.SECRET_PROVIDER") else None -#async def get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id): -# try: -# import requests -# headers = { -# 'Private-Token': f'{gitlab_token}' -# } -# # API endpoint to find MRs containing the commit -# gitlab_url = get_settings().get("GITLAB.URL", 'https://gitlab.com') -# response = requests.get( -# f'{gitlab_url}/api/v4/projects/{project_id}/repository/commits/{commit_sha}/merge_requests', -# headers=headers -# ) -# merge_requests = response.json() -# if merge_requests and response.status_code == 200: -# pr_url = merge_requests[0]['web_url'] -# return pr_url -# else: -# get_logger().info(f"No merge requests found for commit: {commit_sha}") -# return None -# except Exception as e: -# get_logger().error(f"Failed to get MR url from commit sha: {e}") -# return None - async def handle_request(api_url: str, body: str, log_context: dict, sender_id: str): log_context["action"] = body log_context["event"] = "pull_request" if body == "/review" else "comment" @@ -216,8 +193,6 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): get_logger().info(f"Skipping draft MR: {url}") return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) - # we need first to apply_repo_settings - # apply_repo_settings(url) commands_on_push = get_settings().get(f"gitlab.push_commands", {}) handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) if not commands_on_push or not handle_push_trigger: @@ -239,29 +214,6 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): body = handle_ask_line(body, data) await handle_request(url, body, log_context, sender_id) - # elif data.get('object_kind') == 'push' and data.get('event_name') == 'push': - # try: - # project_id = data['project_id'] - # commit_sha = data['checkout_sha'] - # url = await get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id) - # if not url: - # get_logger().info(f"No MR found for commit: {commit_sha}") - # return JSONResponse(status_code=status.HTTP_200_OK, - # content=jsonable_encoder({"message": "success"})) - - # # we need first to apply_repo_settings - # apply_repo_settings(url) - # commands_on_push = get_settings().get(f"gitlab.push_commands", {}) - # handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) - # if not commands_on_push or not handle_push_trigger: - # get_logger().info("Push event, but no push commands found or push trigger is disabled") - # return JSONResponse(status_code=status.HTTP_200_OK, - # content=jsonable_encoder({"message": "success"})) - - # get_logger().debug(f'A push event has been received: {url}') - # await _perform_commands_gitlab("push_commands", PRAgent(), url, log_context, data) - # except Exception as e: - # get_logger().error(f"Failed to handle push event: {e}") background_tasks.add_task(inner, request_json) end_time = datetime.now()