From df1d859e54582f2d45850ecb762cb4c3f6cf7e71 Mon Sep 17 00:00:00 2001 From: Thomas De Keulenaer <11250711+twdkeule@users.noreply.github.com> Date: Tue, 6 May 2025 15:01:48 +0200 Subject: [PATCH] Azure devops: parse PR url starting from the end --- .../git_providers/azuredevops_provider.py | 29 +++++++++---------- tests/unittest/test_azure_devops_parsing.py | 7 +++++ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/pr_agent/git_providers/azuredevops_provider.py b/pr_agent/git_providers/azuredevops_provider.py index 2e1c57b6..80bf68c5 100644 --- a/pr_agent/git_providers/azuredevops_provider.py +++ b/pr_agent/git_providers/azuredevops_provider.py @@ -543,22 +543,21 @@ class AzureDevopsProvider(GitProvider): @staticmethod def _parse_pr_url(pr_url: str) -> Tuple[str, str, int]: parsed_url = urlparse(pr_url) - path_parts = parsed_url.path.strip("/").split("/") - if "pullrequest" not in path_parts: - raise ValueError( - "The provided URL does not appear to be a Azure DevOps PR URL" - ) - if len(path_parts) == 6: # "https://dev.azure.com/organization/project/_git/repo/pullrequest/1" - workspace_slug = path_parts[1] - repo_slug = path_parts[3] - pr_number = int(path_parts[5]) - elif len(path_parts) == 5: # 'https://organization.visualstudio.com/project/_git/repo/pullrequest/1' - workspace_slug = path_parts[0] - repo_slug = path_parts[2] - pr_number = int(path_parts[4]) - else: - raise ValueError("The provided URL does not appear to be a Azure DevOps PR URL") + num_parts = len(path_parts) + if num_parts < 5: + raise ValueError("The provided URL has insufficient path components for an Azure DevOps PR URL") + + # Verify that the second-to-last path component is "pullrequest" + if path_parts[num_parts - 2] != "pullrequest": + raise ValueError("The provided URL does not follow the expected Azure DevOps PR URL format") + + workspace_slug = path_parts[num_parts - 5] + repo_slug = path_parts[num_parts - 3] + try: + pr_number = int(path_parts[num_parts - 1]) + except ValueError as e: + raise ValueError("Cannot parse PR number in the provided URL") from e return workspace_slug, repo_slug, pr_number diff --git a/tests/unittest/test_azure_devops_parsing.py b/tests/unittest/test_azure_devops_parsing.py index 441d4e35..abe0b1fb 100644 --- a/tests/unittest/test_azure_devops_parsing.py +++ b/tests/unittest/test_azure_devops_parsing.py @@ -13,3 +13,10 @@ class TestAzureDevOpsParsing(): # workspace_slug, repo_slug, pr_number assert AzureDevopsProvider._parse_pr_url(pr_url) == ("project", "repo", 1) + + def test_self_hosted_address(self): + pr_url = "http://server.be:8080/tfs/department/project/_git/repo/pullrequest/1" + + # workspace_slug, repo_slug, pr_number + assert AzureDevopsProvider._parse_pr_url(pr_url) == ("project", "repo", 1) +