Browse Source

ref(migration): Create projectcodeowners table (#23715)

Objective:
We need to make a new migration to create the sentry_projectcodeowners table. This allows us to store raw CODEOWNERS files, the code mapping id that we'll use to transform into IssueOwner syntax and the transformed IssueOwner schema. This is a prerequisite for us to import and convert CODEOWNERS into Sentry IssueOwner syntax.
NisanthanNanthakumar 4 years ago
parent
commit
a2ad5a9a8c

+ 1 - 1
migrations_lockfile.txt

@@ -10,7 +10,7 @@ auth: 0008_alter_user_username_max_length
 contenttypes: 0002_remove_content_type_name
 jira_ac: 0001_initial
 nodestore: 0002_nodestore_no_dictfield
-sentry: 0159_create_externaluser_table
+sentry: 0160_create_projectcodeowners_table
 sessions: 0001_initial
 sites: 0002_alter_domain_unique
 social_auth: 0001_initial

+ 78 - 0
src/sentry/migrations/0160_create_projectcodeowners_table.py

@@ -0,0 +1,78 @@
+# Generated by Django 1.11.29 on 2021-02-10 19:04
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import sentry.db.models.fields.bounded
+import sentry.db.models.fields.foreignkey
+import sentry.db.models.fields.jsonfield
+
+
+class Migration(migrations.Migration):
+    # This flag is used to mark that a migration shouldn't be automatically run in
+    # production. We set this to True for operations that we think are risky and want
+    # someone from ops to run manually and monitor.
+    # General advice is that if in doubt, mark your migration as `is_dangerous`.
+    # Some things you should always mark as dangerous:
+    # - Large data migrations. Typically we want these to be run manually by ops so that
+    #   they can be monitored. Since data migrations will now hold a transaction open
+    #   this is even more important.
+    # - Adding columns to highly active tables, even ones that are NULL.
+    is_dangerous = False
+
+    # This flag is used to decide whether to run this migration in a transaction or not.
+    # By default we prefer to run in a transaction, but for migrations where you want
+    # to `CREATE INDEX CONCURRENTLY` this needs to be set to False. Typically you'll
+    # want to create an index concurrently when adding one to an existing table.
+    # You'll also usually want to set this to `False` if you're writing a data
+    # migration, since we don't want the entire migration to run in one long-running
+    # transaction.
+    atomic = True
+
+    dependencies = [
+        ("sentry", "0159_create_externaluser_table"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="ProjectCodeOwners",
+            fields=[
+                (
+                    "id",
+                    sentry.db.models.fields.bounded.BoundedBigAutoField(
+                        primary_key=True, serialize=False
+                    ),
+                ),
+                ("date_updated", models.DateTimeField(default=django.utils.timezone.now)),
+                ("raw", models.TextField(null=True)),
+                ("schema", sentry.db.models.fields.jsonfield.JSONField(null=True)),
+                ("date_added", models.DateTimeField(default=django.utils.timezone.now)),
+                (
+                    "organization_integration",
+                    sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                        null=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="sentry.OrganizationIntegration",
+                    ),
+                ),
+                (
+                    "project",
+                    sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                        db_constraint=False,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="sentry.Project",
+                    ),
+                ),
+                (
+                    "repository_project_path_config",
+                    sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="sentry.RepositoryProjectPathConfig",
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "sentry_projectcodeowners",
+            },
+        ),
+    ]

+ 32 - 0
src/sentry/models/projectcodeowners.py

@@ -0,0 +1,32 @@
+import logging
+
+from django.db import models
+from sentry.db.models import (
+    FlexibleForeignKey,
+    DefaultFieldsModel,
+    JSONField,
+)
+from django.utils import timezone
+
+
+logger = logging.getLogger(__name__)
+
+
+class ProjectCodeOwners(DefaultFieldsModel):
+    __core__ = False
+    # no db constraint to prevent locks on the Project table
+    project = FlexibleForeignKey("sentry.Project", db_constraint=False)
+    # projectcodeowners should work without a repo-based integration.
+    organization_integration = FlexibleForeignKey("sentry.OrganizationIntegration", null=True)
+    # repository_project_path_config ⇒ use this to transform CODEOWNERS paths to stacktrace paths
+    repository_project_path_config = FlexibleForeignKey("sentry.RepositoryProjectPathConfig")
+    # raw ⇒ original CODEOWNERS file.
+    raw = models.TextField(null=True)
+    # schema ⇒ transformed into IssueOwner syntax
+    schema = JSONField(null=True)
+    # override date_added from DefaultFieldsModel
+    date_added = models.DateTimeField(default=timezone.now)
+
+    class Meta:
+        app_label = "sentry"
+        db_table = "sentry_projectcodeowners"