use merge_request with oldrev instead of push

This commit is contained in:
GOOD21
2025-02-21 13:24:20 +08:00
parent 5e1cc12df4
commit 347af1dd99

View File

@ -24,28 +24,29 @@ router = APIRouter()
secret_provider = get_secret_provider() if get_settings().get("CONFIG.SECRET_PROVIDER") else None 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: #async def get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id):
import requests # try:
headers = { # import requests
'Private-Token': f'{gitlab_token}' # headers = {
} # 'Private-Token': f'{gitlab_token}'
# API endpoint to find MRs containing the commit # }
gitlab_url = get_settings().get("GITLAB.URL", 'https://gitlab.com') # # API endpoint to find MRs containing the commit
response = requests.get( # gitlab_url = get_settings().get("GITLAB.URL", 'https://gitlab.com')
f'{gitlab_url}/api/v4/projects/{project_id}/repository/commits/{commit_sha}/merge_requests', # response = requests.get(
headers=headers # 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: # merge_requests = response.json()
pr_url = merge_requests[0]['web_url'] # if merge_requests and response.status_code == 200:
return pr_url # pr_url = merge_requests[0]['web_url']
else: # return pr_url
get_logger().info(f"No merge requests found for commit: {commit_sha}") # else:
return None # get_logger().info(f"No merge requests found for commit: {commit_sha}")
except Exception as e: # return None
get_logger().error(f"Failed to get MR url from commit sha: {e}") # except Exception as e:
return None # 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): async def handle_request(api_url: str, body: str, log_context: dict, sender_id: str):
log_context["action"] = body 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 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) get_logger().info(f"Auto feedback is disabled, skipping auto commands for PR {api_url=}", **log_context)
return return
if commands_conf != "push_commands" and not should_process_pr_logic(data): if not should_process_pr_logic(data): # Here we already updated the configurations
get_logger().info(f"Skipping auto commands for PR {api_url=}", **log_context)
return return
commands = get_settings().get(f"gitlab.{commands_conf}", {}) commands = get_settings().get(f"gitlab.{commands_conf}", {})
get_settings().set("config.is_auto_command", True) 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: def should_process_pr_logic(data) -> bool:
try: try:
if not data.get('object_attributes', {}): if not data.get('object_attributes', {}):
get_logger().info("No object attributes found in the data")
return False return False
title = data['object_attributes'].get('title') title = data['object_attributes'].get('title')
sender = data.get("user", {}).get("username", "") sender = data.get("user", {}).get("username", "")
@ -191,15 +190,14 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request):
# ignore bot users # ignore bot users
if is_bot_user(data): if is_bot_user(data):
return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) 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 # 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): if not should_process_pr_logic(data):
return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"}))
log_context["sender"] = sender if data['object_attributes'].get('action') in ['open', 'reopen']:
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') url = data['object_attributes'].get('url')
draft = data['object_attributes'].get('draft') draft = data['object_attributes'].get('draft')
get_logger().info(f"New merge request: {url}") get_logger().info(f"New merge request: {url}")
@ -208,6 +206,28 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request):
return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"}))
await _perform_commands_gitlab("pr_commands", PRAgent(), url, log_context, data) 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)
elif data.get('object_kind') == 'note' and data.get('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: if 'merge_request' in data:
mr = data['merge_request'] mr = data['merge_request']
@ -219,35 +239,36 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request):
body = handle_ask_line(body, data) body = handle_ask_line(body, data)
await handle_request(url, body, log_context, sender_id) await handle_request(url, body, log_context, sender_id)
elif data.get('object_kind') == 'push' and data.get('event_name') == 'push': # elif data.get('object_kind') == 'push' and data.get('event_name') == 'push':
try: # try:
project_id = data['project_id'] # project_id = data['project_id']
commit_sha = data['checkout_sha'] # commit_sha = data['checkout_sha']
url = await get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id) # url = await get_mr_url_from_commit_sha(commit_sha, gitlab_token, project_id)
if not url: # if not url:
get_logger().info(f"No MR found for commit: {commit_sha}") # get_logger().info(f"No MR found for commit: {commit_sha}")
return JSONResponse(status_code=status.HTTP_200_OK, # return JSONResponse(status_code=status.HTTP_200_OK,
content=jsonable_encoder({"message": "success"})) # content=jsonable_encoder({"message": "success"}))
# we need first to apply_repo_settings # # we need first to apply_repo_settings
apply_repo_settings(url) # apply_repo_settings(url)
commands_on_push = get_settings().get(f"gitlab.push_commands", {}) # commands_on_push = get_settings().get(f"gitlab.push_commands", {})
handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) # handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False)
if not commands_on_push or not handle_push_trigger: # 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") # get_logger().info("Push event, but no push commands found or push trigger is disabled")
return JSONResponse(status_code=status.HTTP_200_OK, # return JSONResponse(status_code=status.HTTP_200_OK,
content=jsonable_encoder({"message": "success"})) # content=jsonable_encoder({"message": "success"}))
get_logger().debug(f'A push event has been received: {url}') # 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("push_commands", PRAgent(), url, log_context, data)
except Exception as e: # except Exception as e:
get_logger().error(f"Failed to handle push event: {e}") # get_logger().error(f"Failed to handle push event: {e}")
background_tasks.add_task(inner, request_json) background_tasks.add_task(inner, request_json)
end_time = datetime.now() end_time = datetime.now()
get_logger().info(f"Processing time: {end_time - start_time}", request=request_json) 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"})) return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"}))
def handle_ask_line(body, data): def handle_ask_line(body, data):
try: try:
line_range_ = data['object_attributes']['position']['line_range'] line_range_ = data['object_attributes']['position']['line_range']