diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index aad3d19e..51e9c938 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -24,6 +24,25 @@ 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 + # Replace 'your_access_token' with your GitLab personal access token + headers = { + 'Private-Token': f'{gitlab_token}' + } + # API endpoint to find MRs containing the commit + response = requests.get( + f'https://gitlab.com/api/v4/projects/{project_id}/repository/commits/{commit_sha}/merge_requests', + headers=headers + ) + merge_requests = response.json() + pr_url = merge_requests[0]['web_url'] + return pr_url + 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" @@ -51,6 +70,7 @@ async def _perform_commands_gitlab(commands_conf: str, agent: PRAgent, api_url: get_logger().error(f"Failed to perform command {command}: {e}") + @router.post("/webhook") async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): start_time = datetime.now() @@ -87,12 +107,19 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): get_logger().info("GitLab data", artifact=data) sender = data.get("user", {}).get("username", "unknown") sender_id = data.get("user", {}).get("id", "unknown") + + # logic to ignore bot users (unlike Github, no direct flag for bot users in gitlab) + sender_name = data.get("user", {}).get("name", "unknown").lower() + if 'codium' in sender_name or 'bot_' in sender_name or 'bot-' in sender_name or '_bot' in sender_name or '-bot' in sender_name: + get_logger().info(f"Skipping bot user: {sender_name}") + 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']: url = data['object_attributes'].get('url') get_logger().info(f"New merge request: {url}") await _perform_commands_gitlab("pr_commands", PRAgent(), url, log_context) - elif data.get('object_kind') == 'note' and data['event_type'] == 'note': # comment on MR + elif data.get('object_kind') == 'note' and data.get('event_type') == 'note': # comment on MR if 'merge_request' in data: mr = data['merge_request'] url = mr.get('url') @@ -102,6 +129,23 @@ 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': + 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"})) + 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"})) + get_logger().debug(f'A push event has been received: {url}') + await _perform_commands_gitlab("push_commands", PRAgent(), url, log_context) + 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() diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index 98d14414..b7ca3f78 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -178,6 +178,11 @@ pr_commands = [ "/review --pr_reviewer.num_code_suggestions=0", "/improve", ] +handle_push_trigger = false +commands = [ + "/describe", + "/review --pr_reviewer.num_code_suggestions=0", +] [bitbucket_app] pr_commands = [