diff --git a/src/sentry/api/helpers/group_index/update.py b/src/sentry/api/helpers/group_index/update.py index 5da0c774e1af5b..47df9355255456 100644 --- a/src/sentry/api/helpers/group_index/update.py +++ b/src/sentry/api/helpers/group_index/update.py @@ -37,7 +37,6 @@ from sentry.models.grouphistory import record_group_history_from_activity_type from sentry.models.groupinbox import GroupInboxRemoveAction, remove_group_from_inbox from sentry.models.grouplink import GroupLink -from sentry.models.grouprelease import GroupRelease from sentry.models.groupresolution import GroupResolution from sentry.models.groupseen import GroupSeen from sentry.models.groupshare import GroupShare @@ -136,24 +135,7 @@ def get_current_release_version_of_group(group: Group, follows_semver: bool = Fa """ current_release_version = None if follows_semver: - if not features.has( - "organizations:releases-resolve-next-release-semver-fix", group.project.organization - ): - try: - # This sets current_release_version to the latest semver version associated with a group - associated_release_id = GroupRelease.objects.filter( - project_id=group.project.id, group_id=group.id - ).values_list("release_id") - current_release_version = ( - get_semver_releases(group.project) - .filter(id__in=associated_release_id) - .values_list("version", flat=True)[:1] - .get() - ) - except Release.DoesNotExist: - pass - else: - current_release_version = greatest_semver_release(group.project).version + current_release_version = greatest_semver_release(group.project).version else: # This sets current_release_version to the most recent release associated with a group @@ -839,18 +821,10 @@ def prepare_response( def get_release_to_resolve_by(project: Project) -> Release | None: - # XXX: Remove block once released - follows_semver = False - if features.has("organizations:releases-resolve-next-release-semver-fix", project.organization): - follows_semver = follows_semver_versioning_scheme( - org_id=project.organization_id, project_id=project.id - ) - - if follows_semver: - release = greatest_semver_release(project) - else: - release = most_recent_release(project) - return release + follows_semver = follows_semver_versioning_scheme( + org_id=project.organization_id, project_id=project.id + ) + return greatest_semver_release(project) if follows_semver else most_recent_release(project) def most_recent_release(project: Project) -> Release | None: diff --git a/src/sentry/features/temporary.py b/src/sentry/features/temporary.py index d94275feca8560..6e0a87453c5855 100644 --- a/src/sentry/features/temporary.py +++ b/src/sentry/features/temporary.py @@ -354,8 +354,6 @@ def register_temporary_features(manager: FeatureManager): manager.add("organizations:relay-cardinality-limiter", OrganizationFeature, FeatureHandlerStrategy.INTERNAL, api_expose=False) # Enable the release details performance section manager.add("organizations:release-comparison-performance", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True) - # Fixes the next release resolution for semver releases - manager.add("organizations:releases-resolve-next-release-semver-fix", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True) # enable new release set_commits functionality manager.add("organizations:set-commits-updated", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False) # Enable new release UI diff --git a/tests/sentry/issues/endpoints/test_group_details.py b/tests/sentry/issues/endpoints/test_group_details.py index 2e4a6709d73ccb..e202523f17a144 100644 --- a/tests/sentry/issues/endpoints/test_group_details.py +++ b/tests/sentry/issues/endpoints/test_group_details.py @@ -355,53 +355,6 @@ def test_resolved_in_next_release_non_semver(self): assert group_resolution.status == GroupResolution.Status.pending assert group_resolution.release.version == most_recent_version.version - # XXX: Remove this test once the feature flag is removed - def test_resolved_in_next_release_semver_no_flag_and_first_release(self): - self.login_as(user=self.user) - project = self.create_project_with_releases() - first_release = Release.get_or_create(version="com.foo.bar@1.0+0", project=project) - Release.get_or_create(version="com.foo.bar@2.0+0", project=project) - wrong_release = Release.get_or_create(version="com.foo.bar@1.0+1", project=project) - # Using store_event() instead of create_group() produces GroupRelease objects - # which is considered during the update_groups() call - event = self.store_event(data={"release": first_release.version}, project_id=project.id) - group = event.group - assert group is not None - assert group.status == GroupStatus.UNRESOLVED - assert group.substatus == GroupSubStatus.NEW - assert group.first_release == first_release - assert GroupResolution.objects.all().count() == 0 - - url = f"/api/0/issues/{group.id}/" - data = {"status": "resolvedInNextRelease"} - response = self.client.put(url, data=data) - assert response.status_code == 200, response.content == {} - - # Refetch from DB to ensure the latest state is fetched - group = Group.objects.get(id=group.id, project=project.id) - assert group.status == GroupStatus.RESOLVED - - group_resolution = GroupResolution.objects.filter(group=group).first() - assert group_resolution is not None - assert group_resolution.group == group - # For semver projects, we consider resolution based on an expression rather than a specific release, - # thus, it is considered resolved in the release that has the highest semver - assert group_resolution.type == GroupResolution.Type.in_release - assert group_resolution.status == GroupResolution.Status.resolved - assert group_resolution.release.version == wrong_release.version - assert response.data["statusDetails"]["inRelease"] == wrong_release.version - - # Let's test that it does not regress to the first release - event = self.store_event(data={"release": first_release.version}, project_id=project.id) - group = Group.objects.get(id=group.id, project=project.id) - assert group.status == GroupStatus.RESOLVED - - # Let's test that it does regress - this is fixed with the feature flag - event = self.store_event(data={"release": wrong_release.version}, project_id=project.id) - group = Group.objects.get(id=group.id, project=project.id) - assert group.status == GroupStatus.UNRESOLVED - assert group.substatus == GroupSubStatus.REGRESSED - def create_project_with_releases(self) -> Project: project = self.create_project() project.flags.has_releases = True @@ -482,12 +435,10 @@ def resolved_in_next_release_helper(self, with_first_release: bool = True) -> No assert group.status == GroupStatus.UNRESOLVED assert group.substatus == GroupSubStatus.REGRESSED - @with_feature("organizations:releases-resolve-next-release-semver-fix") - def test_resolved_in_next_release_semver_with_flag_no_first_release(self): + def test_resolved_in_next_release_semver_no_first_release(self): self.resolved_in_next_release_helper(with_first_release=False) - @with_feature("organizations:releases-resolve-next-release-semver-fix") - def test_resolved_in_next_release_semver_with_flag_and_first_release(self): + def test_resolved_in_next_release_semver_and_first_release(self): self.resolved_in_next_release_helper(with_first_release=True) def test_resolved_in_next_release_no_release(self): @@ -499,23 +450,6 @@ def test_resolved_in_next_release_no_release(self): response = self.client.put(url, data={"status": "resolvedInNextRelease"}) assert response.status_code == 200, response.content - group = Group.objects.get(id=group.id, project=group.project.id) - assert group.status == GroupStatus.RESOLVED - - # no GroupResolution because there is no release - assert not GroupResolution.objects.filter(group=group).exists() - assert response.data["statusDetails"] == {} - - @with_feature("organizations:releases-resolve-next-release-semver-fix") - def test_resolved_in_next_release_with_flag_no_release(self): - self.login_as(user=self.user) - project = self.create_project_with_releases() - group = self.create_group_with_no_release(project) - - url = f"/api/0/organizations/{group.organization.slug}/issues/{group.id}/" - response = self.client.put(url, data={"status": "resolvedInNextRelease"}) - assert response.status_code == 200, response.content - # Refetch from DB to ensure the latest state is fetched group = Group.objects.get(id=group.id, project=group.project.id) assert group.status == GroupStatus.RESOLVED diff --git a/tests/sentry/issues/endpoints/test_organization_group_index.py b/tests/sentry/issues/endpoints/test_organization_group_index.py index 89e5711d07f0ad..166fb5bac8ba3d 100644 --- a/tests/sentry/issues/endpoints/test_organization_group_index.py +++ b/tests/sentry/issues/endpoints/test_organization_group_index.py @@ -4348,15 +4348,15 @@ def test_in_semver_projects_group_resolution_stores_current_release_version(self GroupResolution.current_release_version is set to the latest release associated with a Group, when the project follows semantic versioning scheme """ - release_1 = self.create_release(version="fake_package@21.1.0") - release_2 = self.create_release(version="fake_package@21.1.1") - release_3 = self.create_release(version="fake_package@21.1.2") + release_21_1_0 = self.create_release(version="fake_package@21.1.0") + release_21_1_1 = self.create_release(version="fake_package@21.1.1") + release_21_1_2 = self.create_release(version="fake_package@21.1.2") self.store_event( data={ "timestamp": iso_format(before_now(seconds=10)), "fingerprint": ["group-1"], - "release": release_2.version, + "release": release_21_1_1.version, }, project_id=self.project.id, ) @@ -4364,7 +4364,7 @@ def test_in_semver_projects_group_resolution_stores_current_release_version(self data={ "timestamp": iso_format(before_now(seconds=12)), "fingerprint": ["group-1"], - "release": release_1.version, + "release": release_21_1_0.version, }, project_id=self.project.id, ).group @@ -4381,7 +4381,7 @@ def test_in_semver_projects_group_resolution_stores_current_release_version(self # a group grp_resolution = GroupResolution.objects.get(group=group) - assert grp_resolution.current_release_version == release_2.version + assert grp_resolution.current_release_version == release_21_1_2.version # "resolvedInNextRelease" with semver releases is considered as "resolvedInRelease" assert grp_resolution.type == GroupResolution.Type.in_release @@ -4389,12 +4389,13 @@ def test_in_semver_projects_group_resolution_stores_current_release_version(self # Add release that is between 2 and 3 to ensure that any release after release 2 should # not have a resolution - release_4 = self.create_release(version="fake_package@21.1.1+1") + release_21_1_1_plus_1 = self.create_release(version="fake_package@21.1.1+1") + release_21_1_3 = self.create_release(version="fake_package@21.1.3") - for release in [release_1, release_2]: + for release in [release_21_1_0, release_21_1_1, release_21_1_1_plus_1, release_21_1_2]: assert GroupResolution.has_resolution(group=group, release=release) - for release in [release_3, release_4]: + for release in [release_21_1_3]: assert not GroupResolution.has_resolution(group=group, release=release) # Ensure that Activity has `current_release_version` set on `Resolved in next release` @@ -4404,7 +4405,7 @@ def test_in_semver_projects_group_resolution_stores_current_release_version(self ident=grp_resolution.id, ) - assert activity.data["current_release_version"] == release_2.version + assert activity.data["current_release_version"] == release_21_1_2.version def test_in_non_semver_projects_group_resolution_stores_current_release_version(self) -> None: """