Browse Source

Create releases on event store and link to event
Related to https://gitlab.com/glitchtip/meta/-/issues/38

David Burke 4 years ago
parent
commit
f0846eb5c5

+ 13 - 1
event_store/serializers.py

@@ -11,6 +11,7 @@ from sentry.eventtypes.base import DefaultEvent
 from issues.models import EventType, Event, Issue, EventTagKey
 from issues.serializers import BaseBreadcrumbsSerializer
 from environments.models import Environment
+from releases.models import Release
 from glitchtip.serializers import FlexibleDateTimeField
 from .event_tag_processors import TAG_PROCESSORS
 from .event_context_processors import EVENT_CONTEXT_PROCESSORS
@@ -196,11 +197,18 @@ class StoreDefaultSerializer(BaseSerializer):
 
     def get_environment(self, name: str, project):
         environment, _ = Environment.objects.get_or_create(
-            name=name, organization_id=project.organization_id
+            name=name, organization=project.organization
         )
         environment.projects.add(project)
         return environment
 
+    def get_release(self, version: str, project):
+        release, _ = Release.objects.get_or_create(
+            version=version, organization=project.organization
+        )
+        release.projects.add(project)
+        return release
+
     def create(self, data):
         project = self.context.get("project")
         eventtype = self.get_eventtype()
@@ -237,6 +245,9 @@ class StoreDefaultSerializer(BaseSerializer):
             environment = None
             if data.get("environment"):
                 environment = self.get_environment(data["environment"], project)
+            release = None
+            if data.get("release"):
+                release = self.get_release(data["release"], project)
 
             json_data = {
                 "breadcrumbs": breadcrumbs,
@@ -268,6 +279,7 @@ class StoreDefaultSerializer(BaseSerializer):
                 "issue": issue,
                 "timestamp": data.get("timestamp"),
                 "data": sanitize_bad_postgres_json(json_data),
+                "release": release,
             }
             try:
                 event = Event.objects.create(**params)

+ 10 - 2
event_store/tests/tests.py

@@ -86,13 +86,13 @@ class EventStoreTestCase(APITestCase):
     def test_performance(self):
         with open("event_store/test_data/py_hi_event.json") as json_file:
             data = json.load(json_file)
-        with self.assertNumQueries(9):
+        with self.assertNumQueries(14):
             res = self.client.post(self.url, data, format="json")
         self.assertEqual(res.status_code, 200)
 
         # Second event should have less queries
         data["event_id"] = "6600a066e64b4caf8ed7ec5af64ac4bb"
-        with self.assertNumQueries(5):
+        with self.assertNumQueries(7):
             res = self.client.post(self.url, data, format="json")
         self.assertEqual(res.status_code, 200)
 
@@ -206,3 +206,11 @@ class EventStoreTestCase(APITestCase):
         res = self.client.post(self.url, data, format="json")
         self.assertEqual(res.status_code, 200)
         self.assertTrue(Issue.objects.exists())
+
+    def test_event_release(self):
+        with open("event_store/test_data/py_hi_event.json") as json_file:
+            data = json.load(json_file)
+        self.client.post(self.url, data, format="json")
+        event = Event.objects.first()
+        self.assertTrue(event.release)
+

+ 20 - 0
issues/migrations/0008_event_release.py

@@ -0,0 +1,20 @@
+# Generated by Django 3.1.4 on 2020-12-27 15:18
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('releases', '0002_auto_20201227_1518'),
+        ('issues', '0007_auto_20201113_1843'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='event',
+            name='release',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='releases.release'),
+        ),
+    ]

+ 3 - 0
issues/models.py

@@ -133,6 +133,9 @@ class Event(models.Model):
     created = models.DateTimeField(auto_now_add=True, db_index=True)
     data = models.JSONField()
     tags = models.ManyToManyField(EventTag, blank=True)
+    release = models.ForeignKey(
+        "releases.Release", blank=True, null=True, on_delete=models.SET_NULL
+    )
 
     class Meta:
         ordering = ["-created"]

+ 3 - 0
issues/serializers.py

@@ -3,6 +3,7 @@ from projects.serializers.base_serializers import ProjectReferenceSerializer
 from user_reports.serializers import UserReportSerializer
 from sentry.interfaces.stacktrace import get_context
 from glitchtip.serializers import FlexibleDateTimeField
+from releases.serializers import ReleaseSerializer
 from .models import Issue, Event, EventTag, EventType, EventStatus
 
 
@@ -145,6 +146,7 @@ class EventDetailSerializer(EventSerializer):
     userReport = UserReportSerializer(source="user_report")
     nextEventID = serializers.SerializerMethodField()
     previousEventID = serializers.SerializerMethodField()
+    release = ReleaseSerializer()
 
     class Meta(EventSerializer.Meta):
         fields = EventSerializer.Meta.fields + (
@@ -152,6 +154,7 @@ class EventDetailSerializer(EventSerializer):
             "userReport",
             "nextEventID",
             "previousEventID",
+            "release",
         )
 
     def get_next_or_previous(self, obj, is_next):

+ 24 - 0
issues/tests/tests.py

@@ -245,3 +245,27 @@ class IssuesAPITestCase(GlitchTipTestCase):
         url = reverse("issue-detail", args=[issue.id])
         res = self.client.get(url)
         self.assertContains(res, issue.get_type_display())
+
+    def test_event_release(self):
+        release = baker.make("releases.Release", organization=self.organization)
+        event = baker.make("issues.Event", issue__project=self.project, release=release)
+
+        url = reverse(
+            "project-events-list",
+            kwargs={
+                "project_pk": f"{self.project.organization.slug}/{self.project.slug}",
+            },
+        )
+        res = self.client.get(url)
+        # Not in list view
+        self.assertNotContains(res, release.version)
+
+        url = reverse(
+            "project-events-detail",
+            kwargs={
+                "project_pk": f"{self.project.organization.slug}/{self.project.slug}",
+                "pk": event.pk,
+            },
+        )
+        res = self.client.get(url)
+        self.assertContains(res, release.version)

+ 18 - 0
releases/migrations/0002_auto_20201227_1518.py

@@ -0,0 +1,18 @@
+# Generated by Django 3.1.4 on 2020-12-27 15:18
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('releases', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='release',
+            name='data',
+            field=models.JSONField(default=dict),
+        ),
+    ]