diff --git a/src/sentry/integrations/tasks/sync_status_inbound.py b/src/sentry/integrations/tasks/sync_status_inbound.py index 98226977ae2fe9..7b117b74a6ab31 100644 --- a/src/sentry/integrations/tasks/sync_status_inbound.py +++ b/src/sentry/integrations/tasks/sync_status_inbound.py @@ -13,6 +13,7 @@ from sentry.constants import ObjectStatus from sentry.integrations.models.integration import Integration from sentry.integrations.services.integration import integration_service +from sentry.models.activity import Activity from sentry.models.group import Group, GroupStatus from sentry.models.groupresolution import GroupResolution from sentry.models.organization import Organization @@ -275,6 +276,16 @@ def sync_status_inbound( if not created: resolution.update(datetime=django_timezone.now(), **resolution_params) + # Link the activity to the resolution so regressions can find it. + if created: + latest_resolution_activity = ( + Activity.objects.filter(group=group, type=activity_type.value) + .order_by("-datetime") + .first() + ) + if latest_resolution_activity and not latest_resolution_activity.ident: + latest_resolution_activity.update(ident=resolution.id) + issue_resolved.send_robust( organization_id=organization_id, user=None, diff --git a/tests/sentry/integrations/tasks/test_sync_status_inbound.py b/tests/sentry/integrations/tasks/test_sync_status_inbound.py index d68d8a31c675c4..32485fb0e8b65f 100644 --- a/tests/sentry/integrations/tasks/test_sync_status_inbound.py +++ b/tests/sentry/integrations/tasks/test_sync_status_inbound.py @@ -10,6 +10,7 @@ from sentry.integrations.models import Integration from sentry.integrations.models.organization_integration import OrganizationIntegration from sentry.integrations.tasks.sync_status_inbound import sync_status_inbound +from sentry.models.activity import Activity from sentry.models.group import Group, GroupStatus from sentry.models.grouplink import GroupLink from sentry.models.groupresolution import GroupResolution @@ -240,6 +241,18 @@ def test_resolve_next_release(self, mock_get_resolve_sync_action: mock.MagicMock self._assert_group_resolved(self.group.id) self._assert_resolve_in_release_activity_created(in_next_release=True) + # Verify the activity is linked to GroupResolution via ident + resolution = GroupResolution.objects.get(group=self.group) + activity = ( + Activity.objects.filter( + group=self.group, type=ActivityType.SET_RESOLVED_IN_RELEASE.value + ) + .order_by("-datetime") + .first() + ) + assert activity is not None + assert activity.ident == str(resolution.id) + @mock.patch.object(ExampleIntegration, "get_resolve_sync_action") def test_resolve_current_release(self, mock_get_resolve_sync_action: mock.MagicMock) -> None: mock_get_resolve_sync_action.return_value = ResolveSyncAction.RESOLVE @@ -272,6 +285,18 @@ def test_resolve_current_release(self, mock_get_resolve_sync_action: mock.MagicM self._assert_group_resolved(self.group.id) self._assert_resolve_in_release_activity_created(in_next_release=False) + # Verify the activity is linked to GroupResolution via ident + resolution = GroupResolution.objects.get(group=self.group) + activity = ( + Activity.objects.filter( + group=self.group, type=ActivityType.SET_RESOLVED_IN_RELEASE.value + ) + .order_by("-datetime") + .first() + ) + assert activity is not None + assert activity.ident == str(resolution.id) + @mock.patch.object(ExampleIntegration, "get_resolve_sync_action") def test_resolve_no_releases(self, mock_get_resolve_sync_action: mock.MagicMock) -> None: mock_get_resolve_sync_action.return_value = ResolveSyncAction.RESOLVE