[PATCH 2/2] REST: Add 'patch-comment-created', 'cover-comment-created' events

Stephen Finucane stephen at that.guru
Wed Mar 30 05:57:32 AEDT 2022


From: DJ Delorie <dj at delorie.com>

This patch stitches in "comment created" events for patches and cover
letter into the event queue.

Signed-off-by: DJ Delorie <dj at redhat.com>
Signed-off-by: Stephen Finucane <stephen at that.guru>
Closes: #424
[stephenfin: Extend to cover letters also. Fix some formatting issues.
 Add a release note]
---
 docs/api/schemas/latest/patchwork.yaml        | 71 +++++++++++++++
 docs/api/schemas/patchwork.j2                 | 77 +++++++++++++++++
 docs/api/schemas/v1.0/patchwork.yaml          | 59 +++++++++++++
 docs/api/schemas/v1.1/patchwork.yaml          | 64 ++++++++++++++
 docs/api/schemas/v1.2/patchwork.yaml          | 69 +++++++++++++++
 docs/api/schemas/v1.3/patchwork.yaml          | 71 +++++++++++++++
 patchwork/api/embedded.py                     | 36 ++++++++
 patchwork/api/event.py                        | 86 +++++++++++++++----
 .../migrations/0046_patch_comment_events.py   | 56 ++++++++++++
 patchwork/models.py                           | 16 ++++
 patchwork/signals.py                          | 30 +++++++
 patchwork/tests/test_signals.py               | 36 +++++++-
 .../comment-events-2bc9b754cad1fb32.yaml      |  6 ++
 13 files changed, 657 insertions(+), 20 deletions(-)
 create mode 100644 patchwork/migrations/0046_patch_comment_events.py
 create mode 100644 releasenotes/notes/comment-events-2bc9b754cad1fb32.yaml

diff --git docs/api/schemas/latest/patchwork.yaml docs/api/schemas/latest/patchwork.yaml
index 43edfb04..06be99d3 100644
--- docs/api/schemas/latest/patchwork.yaml
+++ docs/api/schemas/latest/patchwork.yaml
@@ -420,6 +420,8 @@ paths:
               - check-created
               - series-created
               - series-completed
+              - cover-comment-created
+              - patch-comment-created
         - in: query
           name: series
           description: An ID of a series to filter events by.
@@ -459,6 +461,8 @@ paths:
                     - $ref: '#/components/schemas/EventCheckCreated'
                     - $ref: '#/components/schemas/EventSeriesCreated'
                     - $ref: '#/components/schemas/EventSeriesCompleted'
+                    - $ref: '#/components/schemas/EventCoverCommentCreated'
+                    - $ref: '#/components/schemas/EventPatchCommentCreated'
                   discriminator:
                     propertyName: category
                     mapping:
@@ -471,6 +475,8 @@ paths:
                       check-created: '#/components/schemas/EventCheckCreated'
                       series-created: '#/components/schemas/EventSeriesCreated'
                       series-completed: '#/components/schemas/EventSeriesCompleted'
+                      cover-comment-created: '#/components/schemas/EventCoverCommentCreated'
+                      patch-comment-created: '#/components/schemas/EventPatchCommentCreated'
       tags:
         - events
   /api/patches/:
@@ -1919,6 +1925,34 @@ components:
               properties:
                 series:
                   $ref: '#/components/schemas/SeriesEmbedded'
+    EventCoverCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - cover-comment-created
+            payload:
+              properties:
+                cover:
+                  $ref: '#/components/schemas/CoverEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
+    EventPatchCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - patch-comment-created
+            payload:
+              properties:
+                patch:
+                  $ref: '#/components/schemas/PatchEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
     PatchList:
       required:
         - state
@@ -2394,6 +2428,43 @@ components:
           maxLength: 255
           minLength: 1
           readOnly: true
+    CommentEmbedded:
+      type: object
+      properties:
+        id:
+          title: ID
+          type: integer
+          readOnly: true
+        url:
+          title: URL
+          type: string
+          format: uri
+          readOnly: true
+        web_url:
+          title: Web URL
+          type: string
+          format: uri
+          readOnly: true
+        msgid:
+          title: Message ID
+          type: string
+          readOnly: true
+          minLength: 1
+        list_archive_url:
+          title: List archive URL
+          type: string
+          readOnly: true
+          nullable: true
+        date:
+          title: Date
+          type: string
+          format: iso8601
+          readOnly: true
+        name:
+          title: Name
+          type: string
+          readOnly: true
+          minLength: 1
     CoverEmbedded:
       type: object
       properties:
diff --git docs/api/schemas/patchwork.j2 docs/api/schemas/patchwork.j2
index df72c1ac..f8c6d214 100644
--- docs/api/schemas/patchwork.j2
+++ docs/api/schemas/patchwork.j2
@@ -431,6 +431,10 @@ paths:
               - check-created
               - series-created
               - series-completed
+{% if version >= (1, 3) %}
+              - cover-comment-created
+              - patch-comment-created
+{% endif %}
         - in: query
           name: series
           description: An ID of a series to filter events by.
@@ -470,6 +474,8 @@ paths:
                     - $ref: '#/components/schemas/EventCheckCreated'
                     - $ref: '#/components/schemas/EventSeriesCreated'
                     - $ref: '#/components/schemas/EventSeriesCompleted'
+                    - $ref: '#/components/schemas/EventCoverCommentCreated'
+                    - $ref: '#/components/schemas/EventPatchCommentCreated'
                   discriminator:
                     propertyName: category
                     mapping:
@@ -482,6 +488,8 @@ paths:
                       check-created: '#/components/schemas/EventCheckCreated'
                       series-created: '#/components/schemas/EventSeriesCreated'
                       series-completed: '#/components/schemas/EventSeriesCompleted'
+                      cover-comment-created: '#/components/schemas/EventCoverCommentCreated'
+                      patch-comment-created: '#/components/schemas/EventPatchCommentCreated'
       tags:
         - events
   /api/{{ version_url }}patches/:
@@ -1989,6 +1997,34 @@ components:
               properties:
                 series:
                   $ref: '#/components/schemas/SeriesEmbedded'
+    EventCoverCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - cover-comment-created
+            payload:
+              properties:
+                cover:
+                  $ref: '#/components/schemas/CoverEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
+    EventPatchCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - patch-comment-created
+            payload:
+              properties:
+                patch:
+                  $ref: '#/components/schemas/PatchEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
     PatchList:
       required:
         - state
@@ -2482,6 +2518,47 @@ components:
           maxLength: 255
           minLength: 1
           readOnly: true
+    CommentEmbedded:
+      type: object
+      properties:
+        id:
+          title: ID
+          type: integer
+          readOnly: true
+        url:
+          title: URL
+          type: string
+          format: uri
+          readOnly: true
+{% if version >= (1, 1) %}
+        web_url:
+          title: Web URL
+          type: string
+          format: uri
+          readOnly: true
+{% endif %}
+        msgid:
+          title: Message ID
+          type: string
+          readOnly: true
+          minLength: 1
+{% if version >= (1, 2) %}
+        list_archive_url:
+          title: List archive URL
+          type: string
+          readOnly: true
+          nullable: true
+{% endif %}
+        date:
+          title: Date
+          type: string
+          format: iso8601
+          readOnly: true
+        name:
+          title: Name
+          type: string
+          readOnly: true
+          minLength: 1
     CoverEmbedded:
       type: object
       properties:
diff --git docs/api/schemas/v1.0/patchwork.yaml docs/api/schemas/v1.0/patchwork.yaml
index e2f1362f..53571b60 100644
--- docs/api/schemas/v1.0/patchwork.yaml
+++ docs/api/schemas/v1.0/patchwork.yaml
@@ -285,6 +285,8 @@ paths:
                     - $ref: '#/components/schemas/EventCheckCreated'
                     - $ref: '#/components/schemas/EventSeriesCreated'
                     - $ref: '#/components/schemas/EventSeriesCompleted'
+                    - $ref: '#/components/schemas/EventCoverCommentCreated'
+                    - $ref: '#/components/schemas/EventPatchCommentCreated'
                   discriminator:
                     propertyName: category
                     mapping:
@@ -297,6 +299,8 @@ paths:
                       check-created: '#/components/schemas/EventCheckCreated'
                       series-created: '#/components/schemas/EventSeriesCreated'
                       series-completed: '#/components/schemas/EventSeriesCompleted'
+                      cover-comment-created: '#/components/schemas/EventCoverCommentCreated'
+                      patch-comment-created: '#/components/schemas/EventPatchCommentCreated'
       tags:
         - events
   /api/1.0/patches/:
@@ -1562,6 +1566,34 @@ components:
               properties:
                 series:
                   $ref: '#/components/schemas/SeriesEmbedded'
+    EventCoverCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - cover-comment-created
+            payload:
+              properties:
+                cover:
+                  $ref: '#/components/schemas/CoverEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
+    EventPatchCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - patch-comment-created
+            payload:
+              properties:
+                patch:
+                  $ref: '#/components/schemas/PatchEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
     PatchList:
       required:
         - state
@@ -1951,6 +1983,33 @@ components:
           maxLength: 255
           minLength: 1
           readOnly: true
+    CommentEmbedded:
+      type: object
+      properties:
+        id:
+          title: ID
+          type: integer
+          readOnly: true
+        url:
+          title: URL
+          type: string
+          format: uri
+          readOnly: true
+        msgid:
+          title: Message ID
+          type: string
+          readOnly: true
+          minLength: 1
+        date:
+          title: Date
+          type: string
+          format: iso8601
+          readOnly: true
+        name:
+          title: Name
+          type: string
+          readOnly: true
+          minLength: 1
     CoverEmbedded:
       type: object
       properties:
diff --git docs/api/schemas/v1.1/patchwork.yaml docs/api/schemas/v1.1/patchwork.yaml
index cdf8ef29..f83b5e01 100644
--- docs/api/schemas/v1.1/patchwork.yaml
+++ docs/api/schemas/v1.1/patchwork.yaml
@@ -285,6 +285,8 @@ paths:
                     - $ref: '#/components/schemas/EventCheckCreated'
                     - $ref: '#/components/schemas/EventSeriesCreated'
                     - $ref: '#/components/schemas/EventSeriesCompleted'
+                    - $ref: '#/components/schemas/EventCoverCommentCreated'
+                    - $ref: '#/components/schemas/EventPatchCommentCreated'
                   discriminator:
                     propertyName: category
                     mapping:
@@ -297,6 +299,8 @@ paths:
                       check-created: '#/components/schemas/EventCheckCreated'
                       series-created: '#/components/schemas/EventSeriesCreated'
                       series-completed: '#/components/schemas/EventSeriesCompleted'
+                      cover-comment-created: '#/components/schemas/EventCoverCommentCreated'
+                      patch-comment-created: '#/components/schemas/EventPatchCommentCreated'
       tags:
         - events
   /api/1.1/patches/:
@@ -1587,6 +1591,34 @@ components:
               properties:
                 series:
                   $ref: '#/components/schemas/SeriesEmbedded'
+    EventCoverCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - cover-comment-created
+            payload:
+              properties:
+                cover:
+                  $ref: '#/components/schemas/CoverEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
+    EventPatchCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - patch-comment-created
+            payload:
+              properties:
+                patch:
+                  $ref: '#/components/schemas/PatchEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
     PatchList:
       required:
         - state
@@ -2002,6 +2034,38 @@ components:
           maxLength: 255
           minLength: 1
           readOnly: true
+    CommentEmbedded:
+      type: object
+      properties:
+        id:
+          title: ID
+          type: integer
+          readOnly: true
+        url:
+          title: URL
+          type: string
+          format: uri
+          readOnly: true
+        web_url:
+          title: Web URL
+          type: string
+          format: uri
+          readOnly: true
+        msgid:
+          title: Message ID
+          type: string
+          readOnly: true
+          minLength: 1
+        date:
+          title: Date
+          type: string
+          format: iso8601
+          readOnly: true
+        name:
+          title: Name
+          type: string
+          readOnly: true
+          minLength: 1
     CoverEmbedded:
       type: object
       properties:
diff --git docs/api/schemas/v1.2/patchwork.yaml docs/api/schemas/v1.2/patchwork.yaml
index 2a37d81b..e8cee0e5 100644
--- docs/api/schemas/v1.2/patchwork.yaml
+++ docs/api/schemas/v1.2/patchwork.yaml
@@ -393,6 +393,8 @@ paths:
                     - $ref: '#/components/schemas/EventCheckCreated'
                     - $ref: '#/components/schemas/EventSeriesCreated'
                     - $ref: '#/components/schemas/EventSeriesCompleted'
+                    - $ref: '#/components/schemas/EventCoverCommentCreated'
+                    - $ref: '#/components/schemas/EventPatchCommentCreated'
                   discriminator:
                     propertyName: category
                     mapping:
@@ -405,6 +407,8 @@ paths:
                       check-created: '#/components/schemas/EventCheckCreated'
                       series-created: '#/components/schemas/EventSeriesCreated'
                       series-completed: '#/components/schemas/EventSeriesCompleted'
+                      cover-comment-created: '#/components/schemas/EventCoverCommentCreated'
+                      patch-comment-created: '#/components/schemas/EventPatchCommentCreated'
       tags:
         - events
   /api/1.2/patches/:
@@ -1770,6 +1774,34 @@ components:
               properties:
                 series:
                   $ref: '#/components/schemas/SeriesEmbedded'
+    EventCoverCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - cover-comment-created
+            payload:
+              properties:
+                cover:
+                  $ref: '#/components/schemas/CoverEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
+    EventPatchCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - patch-comment-created
+            payload:
+              properties:
+                patch:
+                  $ref: '#/components/schemas/PatchEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
     PatchList:
       required:
         - state
@@ -2245,6 +2277,43 @@ components:
           maxLength: 255
           minLength: 1
           readOnly: true
+    CommentEmbedded:
+      type: object
+      properties:
+        id:
+          title: ID
+          type: integer
+          readOnly: true
+        url:
+          title: URL
+          type: string
+          format: uri
+          readOnly: true
+        web_url:
+          title: Web URL
+          type: string
+          format: uri
+          readOnly: true
+        msgid:
+          title: Message ID
+          type: string
+          readOnly: true
+          minLength: 1
+        list_archive_url:
+          title: List archive URL
+          type: string
+          readOnly: true
+          nullable: true
+        date:
+          title: Date
+          type: string
+          format: iso8601
+          readOnly: true
+        name:
+          title: Name
+          type: string
+          readOnly: true
+          minLength: 1
     CoverEmbedded:
       type: object
       properties:
diff --git docs/api/schemas/v1.3/patchwork.yaml docs/api/schemas/v1.3/patchwork.yaml
index 88c4e355..8b3b1154 100644
--- docs/api/schemas/v1.3/patchwork.yaml
+++ docs/api/schemas/v1.3/patchwork.yaml
@@ -420,6 +420,8 @@ paths:
               - check-created
               - series-created
               - series-completed
+              - cover-comment-created
+              - patch-comment-created
         - in: query
           name: series
           description: An ID of a series to filter events by.
@@ -459,6 +461,8 @@ paths:
                     - $ref: '#/components/schemas/EventCheckCreated'
                     - $ref: '#/components/schemas/EventSeriesCreated'
                     - $ref: '#/components/schemas/EventSeriesCompleted'
+                    - $ref: '#/components/schemas/EventCoverCommentCreated'
+                    - $ref: '#/components/schemas/EventPatchCommentCreated'
                   discriminator:
                     propertyName: category
                     mapping:
@@ -471,6 +475,8 @@ paths:
                       check-created: '#/components/schemas/EventCheckCreated'
                       series-created: '#/components/schemas/EventSeriesCreated'
                       series-completed: '#/components/schemas/EventSeriesCompleted'
+                      cover-comment-created: '#/components/schemas/EventCoverCommentCreated'
+                      patch-comment-created: '#/components/schemas/EventPatchCommentCreated'
       tags:
         - events
   /api/1.3/patches/:
@@ -1919,6 +1925,34 @@ components:
               properties:
                 series:
                   $ref: '#/components/schemas/SeriesEmbedded'
+    EventCoverCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - cover-comment-created
+            payload:
+              properties:
+                cover:
+                  $ref: '#/components/schemas/CoverEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
+    EventPatchCommentCreated:
+      allOf:
+        - $ref: '#/components/schemas/EventBase'
+        - type: object
+          properties:
+            category:
+              enum:
+                - patch-comment-created
+            payload:
+              properties:
+                patch:
+                  $ref: '#/components/schemas/PatchEmbedded'
+                comment:
+                  $ref: '#/components/schemas/CommentEmbedded'
     PatchList:
       required:
         - state
@@ -2394,6 +2428,43 @@ components:
           maxLength: 255
           minLength: 1
           readOnly: true
+    CommentEmbedded:
+      type: object
+      properties:
+        id:
+          title: ID
+          type: integer
+          readOnly: true
+        url:
+          title: URL
+          type: string
+          format: uri
+          readOnly: true
+        web_url:
+          title: Web URL
+          type: string
+          format: uri
+          readOnly: true
+        msgid:
+          title: Message ID
+          type: string
+          readOnly: true
+          minLength: 1
+        list_archive_url:
+          title: List archive URL
+          type: string
+          readOnly: true
+          nullable: true
+        date:
+          title: Date
+          type: string
+          format: iso8601
+          readOnly: true
+        name:
+          title: Name
+          type: string
+          readOnly: true
+          minLength: 1
     CoverEmbedded:
       type: object
       properties:
diff --git patchwork/api/embedded.py patchwork/api/embedded.py
index 78316979..4ba80f4a 100644
--- patchwork/api/embedded.py
+++ patchwork/api/embedded.py
@@ -120,6 +120,24 @@ class CoverSerializer(SerializedRelatedField):
             }
 
 
+class CoverCommentSerializer(SerializedRelatedField):
+
+    class _Serializer(MboxMixin, WebURLMixin, BaseHyperlinkedModelSerializer):
+
+        class Meta:
+            model = models.CoverComment
+            fields = ('id', 'url', 'web_url', 'msgid', 'list_archive_url',
+                      'date', 'name')
+            read_only_fields = fields
+            versioned_fields = {
+                '1.1': ('web_url', 'mbox', ),
+                '1.2': ('list_archive_url',),
+            }
+            extra_kwargs = {
+                'url': {'view_name': 'api-cover-comment-detail'},
+            }
+
+
 class PatchSerializer(SerializedRelatedField):
 
     class _Serializer(MboxMixin, WebURLMixin, BaseHyperlinkedModelSerializer):
@@ -138,6 +156,24 @@ class PatchSerializer(SerializedRelatedField):
             }
 
 
+class PatchCommentSerializer(SerializedRelatedField):
+
+    class _Serializer(MboxMixin, WebURLMixin, BaseHyperlinkedModelSerializer):
+
+        class Meta:
+            model = models.PatchComment
+            fields = ('id', 'url', 'web_url', 'msgid', 'list_archive_url',
+                      'date', 'name')
+            read_only_fields = fields
+            versioned_fields = {
+                '1.1': ('web_url', 'mbox', ),
+                '1.2': ('list_archive_url',),
+            }
+            extra_kwargs = {
+                'url': {'view_name': 'api-patch-comment-detail'},
+            }
+
+
 class PersonSerializer(SerializedRelatedField):
 
     class _Serializer(BaseHyperlinkedModelSerializer):
diff --git patchwork/api/event.py patchwork/api/event.py
index 71f95937..c1b09ab9 100644
--- patchwork/api/event.py
+++ patchwork/api/event.py
@@ -12,7 +12,9 @@ from rest_framework.serializers import SlugRelatedField
 
 from patchwork.api.embedded import CheckSerializer
 from patchwork.api.embedded import CoverSerializer
+from patchwork.api.embedded import CoverCommentSerializer
 from patchwork.api.embedded import PatchSerializer
+from patchwork.api.embedded import PatchCommentSerializer
 from patchwork.api.embedded import ProjectSerializer
 from patchwork.api.embedded import SeriesSerializer
 from patchwork.api.embedded import UserSerializer
@@ -35,20 +37,41 @@ class EventSerializer(ModelSerializer):
     created_check = CheckSerializer()
     previous_relation = SerializerMethodField()
     current_relation = SerializerMethodField()
+    cover_comment = CoverCommentSerializer()
+    patch_comment = PatchCommentSerializer()
 
+    # Mapping of event type to fields to include in the response
     _category_map = {
         Event.CATEGORY_COVER_CREATED: ['cover'],
         Event.CATEGORY_PATCH_CREATED: ['patch'],
         Event.CATEGORY_PATCH_COMPLETED: ['patch', 'series'],
-        Event.CATEGORY_PATCH_STATE_CHANGED: ['patch', 'previous_state',
-                                             'current_state'],
-        Event.CATEGORY_PATCH_DELEGATED: ['patch', 'previous_delegate',
-                                         'current_delegate'],
-        Event.CATEGORY_PATCH_RELATION_CHANGED: ['patch', 'previous_relation',
-                                                'current_relation'],
+        Event.CATEGORY_PATCH_STATE_CHANGED: [
+            'patch',
+            'previous_state',
+            'current_state',
+        ],
+        Event.CATEGORY_PATCH_DELEGATED: [
+            'patch',
+            'previous_delegate',
+            'current_delegate',
+        ],
+        Event.CATEGORY_PATCH_RELATION_CHANGED: [
+            'patch',
+            'previous_relation',
+            'current_relation',
+        ],
         Event.CATEGORY_CHECK_CREATED: ['patch', 'created_check'],
         Event.CATEGORY_SERIES_CREATED: ['series'],
         Event.CATEGORY_SERIES_COMPLETED: ['series'],
+        Event.CATEGORY_COVER_COMMENT_CREATED: ['cover', 'cover_comment'],
+        Event.CATEGORY_PATCH_COMMENT_CREATED: ['patch', 'patch_comment'],
+    }
+
+    # Mapping of database column names to REST API representations
+    _field_name_map = {
+        'created_check': 'check',
+        'cover_comment': 'comment',
+        'patch_comment': 'comment',
     }
 
     def get_previous_relation(self, instance):
@@ -61,13 +84,19 @@ class EventSerializer(ModelSerializer):
         data = super(EventSerializer, self).to_representation(instance)
         payload = OrderedDict()
         kept_fields = self._category_map[instance.category] + [
-            'id', 'category', 'project', 'date', 'actor']
+            'id',
+            'category',
+            'project',
+            'date',
+            'actor',
+        ]
 
         for field in [x for x in data]:
             if field not in kept_fields:
                 del data[field]
             elif field in self._category_map[instance.category]:
-                field_name = 'check' if field == 'created_check' else field
+                # remap fields if necessary
+                field_name = self._field_name_map.get(field, field)
                 payload[field_name] = data.pop(field)
 
         data['payload'] = payload
@@ -77,14 +106,27 @@ class EventSerializer(ModelSerializer):
     class Meta:
         model = Event
         fields = (
-            'id', 'category', 'project', 'date', 'actor', 'patch',
-            'series', 'cover', 'previous_state', 'current_state',
-            'previous_delegate', 'current_delegate', 'created_check',
-            'previous_relation', 'current_relation',
+            'id',
+            'category',
+            'project',
+            'date',
+            'actor',
+            'patch',
+            'series',
+            'cover',
+            'previous_state',
+            'current_state',
+            'previous_delegate',
+            'current_delegate',
+            'created_check',
+            'previous_relation',
+            'current_relation',
+            'cover_comment',
+            'patch_comment',
         )
         read_only_fields = fields
         versioned_fields = {
-            '1.2': ('actor', ),
+            '1.2': ('actor',),
         }
 
 
@@ -98,8 +140,16 @@ class EventList(ListAPIView):
     ordering = '-date'
 
     def get_queryset(self):
-        return Event.objects.all()\
-            .prefetch_related('project', 'patch__project', 'series__project',
-                              'cover', 'previous_state', 'current_state',
-                              'previous_delegate', 'current_delegate',
-                              'created_check')
+        return Event.objects.all().prefetch_related(
+            'project',
+            'patch__project',
+            'series__project',
+            'cover',
+            'previous_state',
+            'current_state',
+            'previous_delegate',
+            'current_delegate',
+            'created_check',
+            'cover_comment',
+            'patch_comment',
+        )
diff --git patchwork/migrations/0046_patch_comment_events.py patchwork/migrations/0046_patch_comment_events.py
new file mode 100644
index 00000000..db198bd4
--- /dev/null
+++ patchwork/migrations/0046_patch_comment_events.py
@@ -0,0 +1,56 @@
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('patchwork', '0045_addressed_fields'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='event',
+            name='cover_comment',
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='+',
+                to='patchwork.covercomment',
+            ),
+        ),
+        migrations.AddField(
+            model_name='event',
+            name='patch_comment',
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='+',
+                to='patchwork.patchcomment',
+            ),
+        ),
+        migrations.AlterField(
+            model_name='event',
+            name='category',
+            field=models.CharField(
+                choices=[
+                    ('cover-created', 'Cover Letter Created'),
+                    ('patch-created', 'Patch Created'),
+                    ('patch-completed', 'Patch Completed'),
+                    ('patch-state-changed', 'Patch State Changed'),
+                    ('patch-delegated', 'Patch Delegate Changed'),
+                    ('patch-relation-changed', 'Patch Relation Changed'),
+                    ('check-created', 'Check Created'),
+                    ('series-created', 'Series Created'),
+                    ('series-completed', 'Series Completed'),
+                    ('cover-comment-created', 'Cover Comment Created'),
+                    ('patch-comment-created', 'Patch Comment Created'),
+                ],
+                db_index=True,
+                help_text='The category of the event.',
+                max_length=25,
+            ),
+        ),
+    ]
diff --git patchwork/models.py patchwork/models.py
index 6304b34d..e4a910ed 100644
--- patchwork/models.py
+++ patchwork/models.py
@@ -1028,6 +1028,8 @@ class Event(models.Model):
     CATEGORY_CHECK_CREATED = 'check-created'
     CATEGORY_SERIES_CREATED = 'series-created'
     CATEGORY_SERIES_COMPLETED = 'series-completed'
+    CATEGORY_COVER_COMMENT_CREATED = 'cover-comment-created'
+    CATEGORY_PATCH_COMMENT_CREATED = 'patch-comment-created'
     CATEGORY_CHOICES = (
         (CATEGORY_COVER_CREATED, 'Cover Letter Created'),
         (CATEGORY_PATCH_CREATED, 'Patch Created'),
@@ -1038,6 +1040,8 @@ class Event(models.Model):
         (CATEGORY_CHECK_CREATED, 'Check Created'),
         (CATEGORY_SERIES_CREATED, 'Series Created'),
         (CATEGORY_SERIES_COMPLETED, 'Series Completed'),
+        (CATEGORY_COVER_COMMENT_CREATED, 'Cover Comment Created'),
+        (CATEGORY_PATCH_COMMENT_CREATED, 'Patch Comment Created'),
     )
 
     # parents
@@ -1113,6 +1117,18 @@ class Event(models.Model):
         Check, related_name='+', null=True, blank=True,
         on_delete=models.CASCADE)
 
+    # fields for 'cover-comment-created' events
+
+    cover_comment = models.ForeignKey(
+        CoverComment, related_name='+', null=True, blank=True,
+        on_delete=models.CASCADE)
+
+    # fields for 'patch-comment-created' events
+
+    patch_comment = models.ForeignKey(
+        PatchComment, related_name='+', null=True, blank=True,
+        on_delete=models.CASCADE)
+
     # TODO(stephenfin): Validate that the correct fields are being set by way
     # of a 'clean' method
 
diff --git patchwork/signals.py patchwork/signals.py
index dc08129c..d1aac8cf 100644
--- patchwork/signals.py
+++ patchwork/signals.py
@@ -11,9 +11,11 @@ from django.dispatch import receiver
 
 from patchwork.models import Check
 from patchwork.models import Cover
+from patchwork.models import CoverComment
 from patchwork.models import Event
 from patchwork.models import Patch
 from patchwork.models import PatchChangeNotification
+from patchwork.models import PatchComment
 from patchwork.models import Series
 
 
@@ -267,3 +269,31 @@ def create_series_completed_event(sender, instance, raw, **kwargs):
     # the instance yet so we duplicate that logic here but with an offset
     if (instance.series.received_total + 1) >= instance.series.total:
         create_event(instance.series)
+
+
+ at receiver(post_save, sender=CoverComment)
+def create_cover_comment_created_event(sender, instance, raw, **kwargs):
+
+    def create_event(comment):
+        return Event.objects.create(
+            category=Event.CATEGORY_COVER_COMMENT_CREATED,
+            project=comment.cover.project,
+            cover=comment.cover,
+            cover_comment=comment,
+        )
+
+    create_event(instance)
+
+
+ at receiver(post_save, sender=PatchComment)
+def create_patch_comment_created_event(sender, instance, raw, **kwargs):
+
+    def create_event(comment):
+        return Event.objects.create(
+            category=Event.CATEGORY_PATCH_COMMENT_CREATED,
+            project=comment.patch.project,
+            patch=comment.patch,
+            patch_comment=comment,
+        )
+
+    create_event(instance)
diff --git patchwork/tests/test_signals.py patchwork/tests/test_signals.py
index 090b6dc0..5d5d8e3b 100644
--- patchwork/tests/test_signals.py
+++ patchwork/tests/test_signals.py
@@ -8,8 +8,12 @@ from django.test import TestCase
 from patchwork.models import Event
 from patchwork.tests import utils
 
-BASE_FIELDS = ['previous_state', 'current_state', 'previous_delegate',
-               'current_delegate']
+BASE_FIELDS = [
+    'previous_state',
+    'current_state',
+    'previous_delegate',
+    'current_delegate',
+]
 
 
 def _get_events(**filters):
@@ -277,3 +281,31 @@ class SeriesChangedTest(_BaseTestCase):
         events = _get_events(series=series)
         self.assertIn(Event.CATEGORY_SERIES_COMPLETED,
                       [x.category for x in events])
+
+
+class CoverCommentCreatedTest(_BaseTestCase):
+
+    def test_cover_comment_created(self):
+        """Validate 'cover-comment-created' events."""
+        comment = utils.create_cover_comment()
+        events = _get_events(cover_comment=comment)
+        self.assertEqual(events.count(), 1)
+        self.assertEqual(
+            events[0].category, Event.CATEGORY_COVER_COMMENT_CREATED,
+        )
+        self.assertEqual(events[0].project, comment.cover.project)
+        self.assertEventFields(events[0])
+
+
+class PatchCommentCreatedTest(_BaseTestCase):
+
+    def test_patch_comment_created(self):
+        """Validate 'patch-comment-created' events."""
+        comment = utils.create_patch_comment()
+        events = _get_events(patch_comment=comment)
+        self.assertEqual(events.count(), 1)
+        self.assertEqual(
+            events[0].category, Event.CATEGORY_PATCH_COMMENT_CREATED,
+        )
+        self.assertEqual(events[0].project, comment.patch.project)
+        self.assertEventFields(events[0])
diff --git releasenotes/notes/comment-events-2bc9b754cad1fb32.yaml releasenotes/notes/comment-events-2bc9b754cad1fb32.yaml
new file mode 100644
index 00000000..a0895d44
--- /dev/null
+++ releasenotes/notes/comment-events-2bc9b754cad1fb32.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Two new event types have been added: ``cover-comment-created`` and
+    ``patch-comment-created``. As their names would suggest, these track the
+    creation of new cover letter and patch comments respectively.
-- 
2.35.1



More information about the Patchwork mailing list