Skip to content

Commit 09a63a3

Browse files
committed
Enhance the Jira URL support #350
Signed-off-by: tdruez <[email protected]>
1 parent b0fbf65 commit 09a63a3

File tree

4 files changed

+31
-32
lines changed

4 files changed

+31
-32
lines changed

workflow/integrations/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
GITLAB_PATTERN = re.compile(r"^https://gitlab\.com/[^/]+/[^/]+/?$")
3030

3131
JIRA_PATTERN = re.compile(
32-
r"^https://[a-zA-Z0-9.-]+\.atlassian\.net/(?:projects|jira/software/projects)/[A-Z][A-Z0-9]+"
32+
r"^https://[a-zA-Z0-9.-]+\.atlassian\.net(?:/[^/]+)*"
33+
r"/(?:projects|browse)/[A-Z][A-Z0-9]+(?:/[^/]*)*/*$"
3334
)
3435

3536
ISSUE_TRACKER_PATTERNS = [

workflow/integrations/base.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ def get_headers(self):
3636
"""
3737
raise NotImplementedError
3838

39+
def post(self, url, data):
40+
response = self.session.post(
41+
url,
42+
json=data,
43+
timeout=self.default_timeout,
44+
)
45+
response.raise_for_status()
46+
return response.json()
47+
3948
@staticmethod
4049
def make_issue_title(request):
4150
return f"[DEJACODE] {request.title}"

workflow/integrations/jira.py

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,7 @@ def create_issue(self, project_key, title, body=""):
7777
"issuetype": {"name": "Request"},
7878
}
7979
}
80-
81-
response = self.session.post(
82-
url,
83-
json=data,
84-
timeout=self.default_timeout,
85-
)
86-
response.raise_for_status()
87-
return response.json()
80+
return self.post(url, data)
8881

8982
def update_issue(self, issue_id, title=None, body=None, status=None):
9083
"""Update an existing Jira issue."""
@@ -112,17 +105,9 @@ def update_issue(self, issue_id, title=None, body=None, status=None):
112105
def post_comment(self, repo_id, issue_id, comment_body):
113106
"""Post a comment on an existing Jira issue."""
114107
api_url = repo_id.rstrip("/") + JIRA_API_PATH
115-
116108
url = f"{api_url}/issue/{issue_id}/comment"
117109
data = {"body": markdown_to_adf(comment_body)}
118-
119-
response = self.session.post(
120-
url,
121-
json=data,
122-
timeout=self.default_timeout,
123-
)
124-
response.raise_for_status()
125-
return response.json()
110+
return self.post(url, data)
126111

127112
def transition_issue(self, issue_id, target_status_name):
128113
"""Transition a Jira issue to a new status by name."""
@@ -138,12 +123,8 @@ def transition_issue(self, issue_id, target_status_name):
138123
else:
139124
raise ValueError(f"No transition found for status '{target_status_name}'")
140125

141-
response = self.session.post(
142-
transitions_url,
143-
json={"transition": {"id": transition_id}},
144-
timeout=self.default_timeout,
145-
)
146-
response.raise_for_status()
126+
data = {"transition": {"id": transition_id}}
127+
return self.post(transitions_url, data)
147128

148129
@staticmethod
149130
def extract_jira_info(url):
@@ -153,6 +134,7 @@ def extract_jira_info(url):
153134
- https://<domain>.atlassian.net/projects/PROJECTKEY
154135
- https://<domain>.atlassian.net/browse/PROJECTKEY
155136
- https://<domain>.atlassian.net/jira/software/projects/PROJECTKEY/...
137+
- https://<domain>.atlassian.net/jira/servicedesk/projects/PROJECTKEY/...
156138
"""
157139
parsed = urlparse(url)
158140
if not parsed.netloc.endswith("atlassian.net"):
@@ -161,7 +143,7 @@ def extract_jira_info(url):
161143
base_url = f"{parsed.scheme}://{parsed.netloc}"
162144
path = parsed.path
163145

164-
project_key_pattern = r"/(?:projects|browse|jira/software/projects)/([A-Z][A-Z0-9]+)"
146+
project_key_pattern = r"/(?:[^/]+/)*(?:projects|browse)/([A-Z][A-Z0-9]+)"
165147
match = re.search(project_key_pattern, path)
166148
if match:
167149
return base_url, match.group(1)

workflow/tests/test_integrations.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,24 @@
2525

2626

2727
class WorkflowIntegrationsTestCase(TestCase):
28-
def test_is_valid_issue_tracker_id(self):
28+
def test_integrations_is_valid_issue_tracker_id(self):
2929
valid_urls = [
30+
# GitHub
3031
"https://github.com/org/repo",
32+
# GitLab
3133
"https://gitlab.com/group/project",
34+
# Jira
35+
"https://aboutcode.atlassian.net/browse/PROJ",
3236
"https://aboutcode.atlassian.net/projects/PROJ",
37+
"https://aboutcode.atlassian.net/projects/PROJ/",
38+
"https://aboutcode.atlassian.net/projects/PROJ/summary",
3339
"https://aboutcode.atlassian.net/jira/software/projects/PROJ",
40+
"https://aboutcode.atlassian.net/jira/software/projects/PROJ/",
41+
"https://aboutcode.atlassian.net/jira/software/projects/PROJ/summary",
42+
"https://aboutcode.atlassian.net/jira/servicedesk/projects/PROJ",
3443
]
3544
for url in valid_urls:
36-
with self.subTest(url=url):
37-
self.assertTrue(is_valid_issue_tracker_id(url))
45+
self.assertTrue(is_valid_issue_tracker_id(url), msg=url)
3846

3947
invalid_urls = [
4048
"https://bitbucket.org/team/repo",
@@ -44,18 +52,17 @@ def test_is_valid_issue_tracker_id(self):
4452
"https://example.com",
4553
]
4654
for url in invalid_urls:
47-
with self.subTest(url=url):
48-
self.assertFalse(is_valid_issue_tracker_id(url))
55+
self.assertFalse(is_valid_issue_tracker_id(url), msg=url)
4956

50-
def test_get_class_for_tracker(self):
57+
def test_integrations_get_class_for_tracker(self):
5158
self.assertIs(get_class_for_tracker("https://github.com/org/repo"), GitHubIntegration)
5259
self.assertIs(get_class_for_tracker("https://gitlab.com/group/project"), GitLabIntegration)
5360
self.assertIs(
5461
get_class_for_tracker("https://aboutcode.atlassian.net/projects/PROJ"), JiraIntegration
5562
)
5663
self.assertIsNone(get_class_for_tracker("https://example.com"))
5764

58-
def test_get_class_for_platform(self):
65+
def test_integrations_get_class_for_platform(self):
5966
self.assertIs(get_class_for_platform("github"), GitHubIntegration)
6067
self.assertIs(get_class_for_platform("gitlab"), GitLabIntegration)
6168
self.assertIs(get_class_for_platform("jira"), JiraIntegration)

0 commit comments

Comments
 (0)