Browse Source

feat(sourcemaps): Implement new tables supporting debug ids (#44572)

Riccardo Busetti 2 years ago
parent
commit
a255e71bca

+ 1 - 1
migrations_lockfile.txt

@@ -6,5 +6,5 @@ To resolve this, rebase against latest master and regenerate your migration. Thi
 will then be regenerated, and you should be able to merge without conflicts.
 
 nodestore: 0002_nodestore_no_dictfield
-sentry: 0362_break_project_integration_fk
+sentry: 0363_debug_id_artifact_bundle
 social_auth: 0001_initial

+ 147 - 0
src/sentry/migrations/0363_debug_id_artifact_bundle.py

@@ -0,0 +1,147 @@
+# Generated by Django 2.2.28 on 2023-02-27 10:53
+
+import django.db.models.deletion
+import django.utils.timezone
+from django.db import migrations, models
+
+import sentry.db.models.fields.bounded
+import sentry.db.models.fields.foreignkey
+from sentry.new_migrations.migrations import CheckedMigration
+
+
+class Migration(CheckedMigration):
+    # This flag is used to mark that a migration shouldn't be automatically run in production. For
+    # the most part, 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 dangerous:
+    # - Large data migrations. Typically we want these to be run manually by ops 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
+    #   have ops run this and not block the deploy. Note that while adding an index is a schema
+    #   change, it's completely safe to run the operation after the code has deployed.
+    is_dangerous = False
+
+    dependencies = [
+        ("sentry", "0362_break_project_integration_fk"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="ArtifactBundle",
+            fields=[
+                (
+                    "id",
+                    sentry.db.models.fields.bounded.BoundedBigAutoField(
+                        primary_key=True, serialize=False
+                    ),
+                ),
+                (
+                    "organization_id",
+                    sentry.db.models.fields.bounded.BoundedBigIntegerField(db_index=True),
+                ),
+                ("bundle_id", models.UUIDField(null=True)),
+                ("artifact_count", sentry.db.models.fields.bounded.BoundedPositiveIntegerField()),
+                ("date_added", models.DateTimeField(default=django.utils.timezone.now)),
+                (
+                    "file",
+                    sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="sentry.File"
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "sentry_artifactbundle",
+                "unique_together": {("organization_id", "bundle_id")},
+            },
+        ),
+        migrations.CreateModel(
+            name="ReleaseArtifactBundle",
+            fields=[
+                (
+                    "id",
+                    sentry.db.models.fields.bounded.BoundedBigAutoField(
+                        primary_key=True, serialize=False
+                    ),
+                ),
+                (
+                    "organization_id",
+                    sentry.db.models.fields.bounded.BoundedBigIntegerField(db_index=True),
+                ),
+                ("release_name", models.CharField(max_length=250)),
+                ("dist_id", sentry.db.models.fields.bounded.BoundedBigIntegerField(null=True)),
+                ("date_added", models.DateTimeField(default=django.utils.timezone.now)),
+                (
+                    "artifact_bundle",
+                    sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="sentry.ArtifactBundle"
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "sentry_releaseartifactbundle",
+                "unique_together": {
+                    ("organization_id", "release_name", "dist_id", "artifact_bundle")
+                },
+            },
+        ),
+        migrations.CreateModel(
+            name="ProjectArtifactBundle",
+            fields=[
+                (
+                    "id",
+                    sentry.db.models.fields.bounded.BoundedBigAutoField(
+                        primary_key=True, serialize=False
+                    ),
+                ),
+                (
+                    "organization_id",
+                    sentry.db.models.fields.bounded.BoundedBigIntegerField(db_index=True),
+                ),
+                (
+                    "project_id",
+                    sentry.db.models.fields.bounded.BoundedBigIntegerField(db_index=True),
+                ),
+                ("date_added", models.DateTimeField(default=django.utils.timezone.now)),
+                (
+                    "artifact_bundle",
+                    sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="sentry.ArtifactBundle"
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "sentry_projectartifactbundle",
+                "unique_together": {("project_id", "artifact_bundle")},
+            },
+        ),
+        migrations.CreateModel(
+            name="DebugIdArtifactBundle",
+            fields=[
+                (
+                    "id",
+                    sentry.db.models.fields.bounded.BoundedBigAutoField(
+                        primary_key=True, serialize=False
+                    ),
+                ),
+                (
+                    "organization_id",
+                    sentry.db.models.fields.bounded.BoundedBigIntegerField(db_index=True),
+                ),
+                ("debug_id", models.UUIDField()),
+                ("source_file_type", models.IntegerField()),
+                ("date_added", models.DateTimeField(default=django.utils.timezone.now)),
+                ("date_last_accessed", models.DateTimeField(default=django.utils.timezone.now)),
+                (
+                    "artifact_bundle",
+                    sentry.db.models.fields.foreignkey.FlexibleForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="sentry.ArtifactBundle"
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "sentry_debugidartifactbundle",
+                "unique_together": {("debug_id", "artifact_bundle", "source_file_type")},
+            },
+        ),
+    ]

+ 1 - 0
src/sentry/models/__init__.py

@@ -7,6 +7,7 @@ from .apikey import *  # NOQA
 from .apiscopes import *  # NOQA
 from .apitoken import *  # NOQA
 from .appconnectbuilds import *  # NOQA
+from .artifactbundle import *  # NOQA
 from .assistant import *  # NOQA
 from .auditlogentry import *  # NOQA
 from .authenticator import *  # NOQA

+ 93 - 0
src/sentry/models/artifactbundle.py

@@ -0,0 +1,93 @@
+from enum import Enum
+
+from django.db import models
+from django.utils import timezone
+
+from sentry.db.models import (
+    BoundedBigIntegerField,
+    BoundedPositiveIntegerField,
+    FlexibleForeignKey,
+    Model,
+    region_silo_only_model,
+)
+
+
+class SourceFileType(Enum):
+    SOURCE = 1
+    MINIFIED_SOURCE = 2
+    SOURCE_MAP = 3
+    INDEXED_RAM_BUNDLE = 4
+
+    @classmethod
+    def choices(cls):
+        return [(key.value, key.name) for key in cls]
+
+
+@region_silo_only_model
+class ArtifactBundle(Model):
+    __include_in_export__ = False
+
+    organization_id = BoundedBigIntegerField(db_index=True)
+    bundle_id = models.UUIDField(null=True)
+    file = FlexibleForeignKey("sentry.File")
+    artifact_count = BoundedPositiveIntegerField()
+    date_added = models.DateTimeField(default=timezone.now)
+
+    class Meta:
+        app_label = "sentry"
+        db_table = "sentry_artifactbundle"
+
+        unique_together = (("organization_id", "bundle_id"),)
+
+
+@region_silo_only_model
+class ReleaseArtifactBundle(Model):
+    __include_in_export__ = False
+
+    organization_id = BoundedBigIntegerField(db_index=True)
+    release_name = models.CharField(max_length=250)
+    dist_id = BoundedBigIntegerField(null=True)
+    artifact_bundle = FlexibleForeignKey("sentry.ArtifactBundle")
+    date_added = models.DateTimeField(default=timezone.now)
+
+    class Meta:
+        app_label = "sentry"
+        db_table = "sentry_releaseartifactbundle"
+
+        unique_together = (("organization_id", "release_name", "dist_id", "artifact_bundle"),)
+
+
+@region_silo_only_model
+class DebugIdArtifactBundle(Model):
+    __include_in_export__ = False
+
+    organization_id = BoundedBigIntegerField(db_index=True)
+    debug_id = models.UUIDField()
+    artifact_bundle = FlexibleForeignKey("sentry.ArtifactBundle")
+    source_file_type = models.IntegerField(choices=SourceFileType.choices())
+    date_added = models.DateTimeField(default=timezone.now)
+    date_last_accessed = models.DateTimeField(default=timezone.now)
+
+    class Meta:
+        app_label = "sentry"
+        db_table = "sentry_debugidartifactbundle"
+
+        # We can have the same debug_id pointing to different artifact_bundle(s) because the user might upload
+        # the same artifacts twice, or they might have certain build files that don't change across builds.
+        unique_together = (("debug_id", "artifact_bundle", "source_file_type"),)
+
+
+@region_silo_only_model
+class ProjectArtifactBundle(Model):
+    __include_in_export__ = False
+
+    organization_id = BoundedBigIntegerField(db_index=True)
+    project_id = BoundedBigIntegerField(db_index=True)
+    artifact_bundle = FlexibleForeignKey("sentry.ArtifactBundle")
+    date_added = models.DateTimeField(default=timezone.now)
+
+    class Meta:
+        app_label = "sentry"
+        db_table = "sentry_projectartifactbundle"
+
+        unique_together = (("project_id", "artifact_bundle"),)