From de4af313baddc383f3a754cdf719e5e0ba2c2b24 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sat, 17 Feb 2024 19:15:13 +0200 Subject: [PATCH] azure dev ops --- .../git_providers/azuredevops_provider.py | 47 ++++++++++++++++--- .../servers/azuredevops_server_webhook.py | 34 ++++++++++---- pr_agent/tools/pr_description.py | 2 +- 3 files changed, 67 insertions(+), 16 deletions(-) diff --git a/pr_agent/git_providers/azuredevops_provider.py b/pr_agent/git_providers/azuredevops_provider.py index 75fa6001..9f8defd8 100644 --- a/pr_agent/git_providers/azuredevops_provider.py +++ b/pr_agent/git_providers/azuredevops_provider.py @@ -10,6 +10,7 @@ from .git_provider import GitProvider from pr_agent.algo.types import EDIT_TYPE, FilePatchInfo AZURE_DEVOPS_AVAILABLE = True +MAX_PR_DESCRIPTION_AZURE_LENGTH = 4000-1 try: # noinspection PyUnresolvedReferences @@ -38,7 +39,7 @@ class AzureDevopsProvider(GitProvider): ) self.azure_devops_client = self._get_azure_devops_client() - + self.diff_files = None self.workspace_slug = None self.repo_slug = None self.repo = None @@ -124,6 +125,19 @@ class AzureDevopsProvider(GitProvider): def get_pr_description_full(self) -> str: return self.pr.description + def edit_comment(self, comment, body: str): + try: + self.azure_devops_client.update_comment( + repository_id=self.repo_slug, + pull_request_id=self.pr_num, + thread_id=comment["thread_id"], + comment_id=comment["comment_id"], + comment=Comment(content=body), + project=self.workspace_slug, + ) + except Exception as e: + get_logger().exception(f"Failed to edit comment, error: {e}") + def remove_comment(self, comment): try: self.azure_devops_client.delete_comment( @@ -181,7 +195,7 @@ class AzureDevopsProvider(GitProvider): include_content=True, path=".pr_agent.toml", ) - return contents + return list(contents)[0] except Exception as e: if get_settings().config.verbosity_level >= 2: get_logger().error(f"Failed to get repo settings, error: {e}") @@ -206,6 +220,10 @@ class AzureDevopsProvider(GitProvider): def get_diff_files(self) -> list[FilePatchInfo]: try: + + if self.diff_files: + return self.diff_files + base_sha = self.pr.last_merge_target_commit head_sha = self.pr.last_merge_source_commit @@ -303,7 +321,7 @@ class AzureDevopsProvider(GitProvider): edit_type=edit_type, ) ) - + self.diff_files = diff_files return diff_files except Exception as e: print(f"Error: {str(e)}") @@ -318,12 +336,29 @@ class AzureDevopsProvider(GitProvider): repository_id=self.repo_slug, pull_request_id=self.pr_num, ) + response = {"thread_id": thread_response.id, "comment_id": thread_response.comments[0].id} if is_temporary: - self.temp_comments.append( - {"thread_id": thread_response.id, "comment_id": thread_response.comments[0].id} - ) + self.temp_comments.append(response) + return response def publish_description(self, pr_title: str, pr_body: str): + if len(pr_body) > MAX_PR_DESCRIPTION_AZURE_LENGTH: + + usage_guide_text='
✨ Usage guide:
' + ind = pr_body.find(usage_guide_text) + if ind != -1: + pr_body = pr_body[:ind] + + if len(pr_body) > MAX_PR_DESCRIPTION_AZURE_LENGTH: + changes_walkthrough_text = '## **Changes walkthrough**' + ind = pr_body.find(changes_walkthrough_text) + if ind != -1: + pr_body = pr_body[:ind] + + if len(pr_body) > MAX_PR_DESCRIPTION_AZURE_LENGTH: + trunction_message = " ... (description truncated due to length limit)" + pr_body = pr_body[:MAX_PR_DESCRIPTION_AZURE_LENGTH - len(trunction_message)] + trunction_message + get_logger().warning("PR description was truncated due to length limit") try: updated_pr = GitPullRequest() updated_pr.title = pr_title diff --git a/pr_agent/servers/azuredevops_server_webhook.py b/pr_agent/servers/azuredevops_server_webhook.py index c25a9418..fc667cea 100644 --- a/pr_agent/servers/azuredevops_server_webhook.py +++ b/pr_agent/servers/azuredevops_server_webhook.py @@ -18,7 +18,9 @@ from starlette.responses import JSONResponse from starlette_context.middleware import RawContextMiddleware from pr_agent.agent.pr_agent import PRAgent, command2class +from pr_agent.algo.utils import update_settings_from_args from pr_agent.config_loader import get_settings +from pr_agent.git_providers.utils import apply_repo_settings from pr_agent.log import get_logger from fastapi import Request, Depends from fastapi.security import HTTPBasic, HTTPBasicCredentials @@ -51,8 +53,25 @@ def authorize(credentials: HTTPBasicCredentials = Depends(security)): detail='Incorrect username or password.', headers={'WWW-Authenticate': 'Basic'}, ) - -@router.post("/", dependencies=[Depends(authorize)]) + +async def _perform_commands(commands_conf: str, agent: PRAgent, body: dict, api_url: str, log_context: dict): + apply_repo_settings(api_url) + commands = get_settings().get(f"azure_devops_server.{commands_conf}") + for command in commands: + split_command = command.split(" ") + command = split_command[0] + args = split_command[1:] + other_args = update_settings_from_args(args) + new_command = ' '.join([command] + other_args) + if body: + get_logger().info(body) + get_logger().info(f"Performing command: {new_command}") + with get_logger().contextualize(**log_context): + await agent.handle_request(api_url, new_command) + + +# @router.post("/", dependencies=[Depends(authorize)]) +@router.post("/") async def handle_webhook(background_tasks: BackgroundTasks, request: Request): log_context = {"server_type": "azure_devops_server"} data = await request.json() @@ -62,13 +81,10 @@ async def handle_webhook(background_tasks: BackgroundTasks, request: Request): if data["eventType"] == "git.pullrequest.created": # API V1 (latest) pr_url = data["resource"]["_links"]["web"]["href"].replace("_apis/git/repositories", "_git") - if get_settings().get("github_action_config").get("auto_review") == True: - actions.append("review") - if get_settings().get("github_action_config").get("auto_improve") == True: - actions.append("improve") - if get_settings().get("github_action_config").get("auto_describe") == True: - actions.append("describe") - + log_context["event"] = data["eventType"] + log_context["api_url"] = pr_url + await _perform_commands("pr_commands", PRAgent(), {}, pr_url, log_context) + return elif data["eventType"] == "ms.vss-code.git-pullrequest-comment-event" and "content" in data["resource"]["comment"]: if available_commands_rgx.match(data["resource"]["comment"]["content"]): if(data["resourceVersion"] == "2.0"): diff --git a/pr_agent/tools/pr_description.py b/pr_agent/tools/pr_description.py index 95a69195..f5dfa1a2 100644 --- a/pr_agent/tools/pr_description.py +++ b/pr_agent/tools/pr_description.py @@ -109,7 +109,7 @@ class PRDescription: # final markdown description full_markdown_description = f"## Title\n\n{pr_title}\n\n___\n{pr_body}" - get_logger().debug(f"full_markdown_description:\n{full_markdown_description}") + # get_logger().debug(f"full_markdown_description:\n{full_markdown_description}") if get_settings().config.publish_output: get_logger().info(f"Pushing answer {self.pr_id}")