Skip to content

Commit 5c67952

Browse files
authored
fix(issues): structured issue annotations (#74648)
1 parent f4e7e24 commit 5c67952

File tree

7 files changed

+22
-19
lines changed

7 files changed

+22
-19
lines changed

src/sentry/api/serializers/models/group.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ def merge_list_dictionaries(
7272
dict1.setdefault(key, []).extend(val)
7373

7474

75+
class GroupAnnotation(TypedDict):
76+
displayName: str
77+
url: str
78+
79+
7580
class GroupStatusDetailsResponseOptional(TypedDict, total=False):
7681
autoResolved: bool
7782
ignoreCount: int
@@ -145,7 +150,7 @@ class BaseGroupSerializerResponse(BaseGroupResponseOptional):
145150
isSubscribed: bool
146151
subscriptionDetails: GroupSubscriptionResponseOptional | None
147152
hasSeen: bool
148-
annotations: Sequence[str]
153+
annotations: Sequence[GroupAnnotation]
149154

150155

151156
class SeenStats(TypedDict):

src/sentry/integrations/mixins/issues.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ def map_external_issues_to_annotations(self, external_issues):
348348
for ei in external_issues:
349349
link = self.get_issue_url(ei.key)
350350
label = self.get_issue_display_name(ei) or ei.key
351-
annotations.append(f'<a href="{link}">{label}</a>')
351+
annotations.append({"url": link, "displayName": label})
352352

353353
return annotations
354354

src/sentry/models/platformexternalissue.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def get_annotations_for_group_list(cls, group_list):
3535
# group annotations by group id
3636
annotations_by_group_id = defaultdict(list)
3737
for ei in external_issues:
38-
annotation = f'<a href="{ei.web_url}">{ei.display_name}</a>'
38+
annotation = {"url": ei.web_url, "displayName": ei.display_name}
3939
annotations_by_group_id[ei.group_id].append(annotation)
4040

4141
return annotations_by_group_id

src/sentry/plugins/bases/issue.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from django import forms
44
from django.conf import settings
5-
from django.utils.html import format_html
65
from rest_framework.request import Request
76

87
from sentry.models.activity import Activity
@@ -312,11 +311,10 @@ def tags(self, request: Request, group, tag_list, **kwargs):
312311
return tag_list
313312

314313
tag_list.append(
315-
format_html(
316-
'<a href="{}" rel="noreferrer">{}</a>',
317-
self.get_issue_url(group=group, issue_id=issue_id),
318-
self.get_issue_label(group=group, issue_id=issue_id),
319-
)
314+
{
315+
"url": self.get_issue_url(group=group, issue_id=issue_id),
316+
"displayName": self.get_issue_label(group=group, issue_id=issue_id),
317+
}
320318
)
321319

322320
return tag_list

src/sentry/plugins/bases/issue2.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from django.conf import settings
44
from django.urls import re_path, reverse
5-
from django.utils.html import format_html
65
from rest_framework.request import Request
76
from rest_framework.response import Response
87

@@ -431,11 +430,10 @@ def tags(self, request: Request, group, tag_list, **kwargs):
431430
return tag_list
432431

433432
tag_list.append(
434-
format_html(
435-
'<a href="{}">{}</a>',
436-
self._get_issue_url_compat(group, issue),
437-
self._get_issue_label_compat(group, issue),
438-
)
433+
{
434+
"url": self._get_issue_url_compat(group, issue),
435+
"displayName": self._get_issue_label_compat(group, issue),
436+
}
439437
)
440438

441439
return tag_list

tests/sentry/api/endpoints/test_group_details.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def test_platform_external_issue_annotation(self):
156156
response = self.client.get(url, format="json")
157157

158158
assert response.data["annotations"] == [
159-
'<a href="https://example.com/issues/2">Issue#2</a>'
159+
{"url": "https://example.com/issues/2", "displayName": "Issue#2"}
160160
]
161161

162162
def test_plugin_external_issue_annotation(self):
@@ -172,7 +172,9 @@ def test_plugin_external_issue_annotation(self):
172172
url = f"/api/0/issues/{group.id}/"
173173
response = self.client.get(url, format="json")
174174

175-
assert response.data["annotations"] == ['<a href="https://trello.com/c/134">Trello-134</a>']
175+
assert response.data["annotations"] == [
176+
{"url": "https://trello.com/c/134", "displayName": "Trello-134"}
177+
]
176178

177179
def test_integration_external_issue_annotation(self):
178180
group = self.create_group()
@@ -191,7 +193,7 @@ def test_integration_external_issue_annotation(self):
191193
response = self.client.get(url, format="json")
192194

193195
assert response.data["annotations"] == [
194-
'<a href="https://example.com/browse/api-123">api-123</a>'
196+
{"url": "https://example.com/browse/api-123", "displayName": "api-123"}
195197
]
196198

197199
def test_permalink_superuser(self):

tests/sentry/integrations/test_issues.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ def test_annotations(self):
505505
link = self.installation.get_issue_url(self.external_issue.key)
506506

507507
assert self.installation.get_annotations_for_group_list([self.group]) == {
508-
self.group.id: [f'<a href="{link}">{label}</a>']
508+
self.group.id: [{"url": link, "displayName": label}]
509509
}
510510

511511
with assume_test_silo_mode(SiloMode.CONTROL):

0 commit comments

Comments
 (0)