From 3dd486d55b7b80c550f3cb069a8d21d730696dd8 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Thu, 7 May 2026 10:54:05 -0700 Subject: [PATCH] test: Validate MOVE_TO_PENDING historical_silo_assignments check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test PR for #115087 — removes GroupCommitResolution and adds a MOVE_TO_PENDING migration without adding sentry_groupcommitresolution to historical_silo_assignments. Expected to fail CI at the migration replay step with "Cannot determine database for deleted model sentry.GroupCommitResolution". DO NOT MERGE. Co-Authored-By: Claude Opus 4.7 (1M context) --- migrations_lockfile.txt | 2 +- pyproject.toml | 1 - src/sentry/deletions/__init__.py | 1 - src/sentry/deletions/defaults/commit.py | 12 ++----- src/sentry/deletions/defaults/group.py | 1 - .../1085_remove_groupcommitresolution.py | 33 +++++++++++++++++++ src/sentry/models/__init__.py | 1 - src/sentry/models/groupcommitresolution.py | 25 -------------- tests/sentry/deletions/test_commit.py | 9 ----- 9 files changed, 37 insertions(+), 48 deletions(-) create mode 100644 src/sentry/migrations/1085_remove_groupcommitresolution.py delete mode 100644 src/sentry/models/groupcommitresolution.py diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index c36414b2b0c219..965f6d9b47f165 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -31,7 +31,7 @@ replays: 0007_organizationmember_replay_access seer: 0010_drop_legacy_columns -sentry: 1084_delete_dashboardlastvisited +sentry: 1085_remove_groupcommitresolution social_auth: 0003_social_auth_json_field diff --git a/pyproject.toml b/pyproject.toml index 1646cf550d7434..ff8404354b4889 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1131,7 +1131,6 @@ module = [ "sentry.models.files.*", "sentry.models.group", "sentry.models.groupbookmark", - "sentry.models.groupcommitresolution", "sentry.models.groupemailthread", "sentry.models.groupenvironment", "sentry.models.grouphash", diff --git a/src/sentry/deletions/__init__.py b/src/sentry/deletions/__init__.py index 99e3de8919b44c..a2825e06ad5be9 100644 --- a/src/sentry/deletions/__init__.py +++ b/src/sentry/deletions/__init__.py @@ -60,7 +60,6 @@ def load_defaults(manager: DeletionTaskManager) -> None: manager.register(models.Group, defaults.GroupDeletionTask) manager.register(models.GroupAssignee, BulkModelDeletionTask) manager.register(models.GroupBookmark, BulkModelDeletionTask) - manager.register(models.GroupCommitResolution, BulkModelDeletionTask) manager.register(models.GroupEmailThread, BulkModelDeletionTask) manager.register(models.GroupEnvironment, BulkModelDeletionTask) manager.register(models.GroupHash, defaults.GroupHashDeletionTask) diff --git a/src/sentry/deletions/defaults/commit.py b/src/sentry/deletions/defaults/commit.py index 8abad8a97ff0e1..559e3f1c88d31c 100644 --- a/src/sentry/deletions/defaults/commit.py +++ b/src/sentry/deletions/defaults/commit.py @@ -16,13 +16,11 @@ def get_query_filter(self) -> Q: 2. Not referenced by any ReleaseHeadCommit (not a head commit of any release) 3. Not referenced by any GroupReaction (not reacted to by any group) 4. Not referenced by any CommitComparison (not part of any comparison) - 5. Not referenced by any GroupCommitResolution (not resolving any group) - 6. Not referenced by any GroupLink (not linked to any group) - 7. Not referenced by any LatestRepoReleaseEnvironment.commit_id - 8. Older than 90 days + 5. Not referenced by any GroupLink (not linked to any group) + 6. Not referenced by any LatestRepoReleaseEnvironment.commit_id + 7. Older than 90 days """ from sentry.models.commitcomparison import CommitComparison - from sentry.models.groupcommitresolution import GroupCommitResolution from sentry.models.grouplink import GroupLink from sentry.models.groupreaction import GroupReaction from sentry.models.latestreporeleaseenvironment import LatestRepoReleaseEnvironment @@ -42,9 +40,6 @@ def get_query_filter(self) -> Q: commitcomparison_base_exists = Exists( CommitComparison.objects.filter(base_commit_id=OuterRef("id")) ) - groupcommitresolution_exists = Exists( - GroupCommitResolution.objects.filter(commit_id=OuterRef("id")) - ) grouplink_exists = Exists( GroupLink.objects.filter( project__organization_id=OuterRef("organization_id"), @@ -62,7 +57,6 @@ def get_query_filter(self) -> Q: | groupreaction_exists | commitcomparison_head_exists | commitcomparison_base_exists - | groupcommitresolution_exists | grouplink_exists | latestrepo_exists ) diff --git a/src/sentry/deletions/defaults/group.py b/src/sentry/deletions/defaults/group.py index 13302c8b9d88a4..2d59dfce1b44d6 100644 --- a/src/sentry/deletions/defaults/group.py +++ b/src/sentry/deletions/defaults/group.py @@ -60,7 +60,6 @@ # XXX: We could remove GroupHash from here since we call delete_group_hashes() in the _delete_children() method. models.GroupHash, models.GroupAssignee, - models.GroupCommitResolution, models.GroupLink, models.GroupHistory, models.GroupBookmark, diff --git a/src/sentry/migrations/1085_remove_groupcommitresolution.py b/src/sentry/migrations/1085_remove_groupcommitresolution.py new file mode 100644 index 00000000000000..a1f0473cf10e4e --- /dev/null +++ b/src/sentry/migrations/1085_remove_groupcommitresolution.py @@ -0,0 +1,33 @@ +# Generated by Django 5.2.12 on 2026-05-07 17:51 + + +from sentry.new_migrations.migrations import CheckedMigration +from sentry.new_migrations.monkey.models import SafeDeleteModel +from sentry.new_migrations.monkey.state import DeletionAction + + +class Migration(CheckedMigration): + # This flag is used to mark that a migration shouldn't be automatically run in production. + # This should only be used for operations where it's safe to run the migration after your + # code has deployed. So this should not be used for most operations that alter the schema + # of a table. + # Here are some things that make sense to mark as post deployment: + # - Large data migrations. Typically we want these to be run manually so that they can be + # monitored and not block the deploy for a long period of time while they run. + # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to + # run this outside deployments so that we don't block them. Note that while adding an index + # is a schema change, it's completely safe to run the operation after the code has deployed. + # Once deployed, run these manually via: https://develop.sentry.dev/database-migrations/#migration-deployment + + is_post_deployment = False + + dependencies = [ + ("sentry", "1084_delete_dashboardlastvisited"), + ] + + operations = [ + SafeDeleteModel( + name="GroupCommitResolution", + deletion_action=DeletionAction.MOVE_TO_PENDING, + ), + ] diff --git a/src/sentry/models/__init__.py b/src/sentry/models/__init__.py index 50c886bbbb11e9..a86c4a293d7cda 100644 --- a/src/sentry/models/__init__.py +++ b/src/sentry/models/__init__.py @@ -40,7 +40,6 @@ from .group import * # NOQA from .groupassignee import * # NOQA from .groupbookmark import * # NOQA -from .groupcommitresolution import * # NOQA from .groupemailthread import * # NOQA from .groupenvironment import * # NOQA from .grouphash import * # NOQA diff --git a/src/sentry/models/groupcommitresolution.py b/src/sentry/models/groupcommitresolution.py deleted file mode 100644 index d3b49637c70b26..00000000000000 --- a/src/sentry/models/groupcommitresolution.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.db import models -from django.utils import timezone - -from sentry.backup.scopes import RelocationScope -from sentry.db.models import BoundedBigIntegerField, Model, cell_silo_model, sane_repr - - -@cell_silo_model -class GroupCommitResolution(Model): - """ - When a Group is referenced via a commit, its association is stored here. - """ - - __relocation_scope__ = RelocationScope.Excluded - - group_id = BoundedBigIntegerField() - commit_id = BoundedBigIntegerField(db_index=True) - datetime = models.DateTimeField(default=timezone.now, db_index=True) - - class Meta: - db_table = "sentry_groupcommitresolution" - app_label = "sentry" - unique_together = (("group_id", "commit_id"),) - - __repr__ = sane_repr("group_id", "commit_id") diff --git a/tests/sentry/deletions/test_commit.py b/tests/sentry/deletions/test_commit.py index 69c3f6acbfb93e..4f81097598509c 100644 --- a/tests/sentry/deletions/test_commit.py +++ b/tests/sentry/deletions/test_commit.py @@ -6,7 +6,6 @@ from sentry.deletions.defaults.commit import CommitDeletionTask from sentry.models.commit import Commit from sentry.models.commitcomparison import CommitComparison -from sentry.models.groupcommitresolution import GroupCommitResolution from sentry.models.grouplink import GroupLink from sentry.models.groupreaction import GroupReaction, GroupReactionType from sentry.models.latestreporeleaseenvironment import LatestRepoReleaseEnvironment @@ -99,14 +98,6 @@ def test_get_query_filter_does_not_select_commit_in_comparison(self) -> None: assert head_commit not in commits_to_delete assert base_commit not in commits_to_delete - def test_get_query_filter_does_not_select_commit_resolving_group(self) -> None: - """Test that commits in GroupCommitResolution are NOT selected""" - commit = self._create_old_commit() - group = self.create_group(project=self.project) - GroupCommitResolution.objects.create(group_id=group.id, commit_id=commit.id) - commits_to_delete = self._get_filtered_commits() - assert commit not in commits_to_delete - def test_get_query_filter_does_not_select_latest_repo_commit(self) -> None: """Test that commits in LatestRepoReleaseEnvironment are NOT selected""" commit = self._create_old_commit()