Просмотр исходного кода

feat(activity): Add the release status of a commit with the activity (#35165)

* backend and frontend changes so far

* fixed FE test

* fixed FE test for resolved in commit with releases

* pr review changes

* removed unused imports
Komal Saini 2 лет назад
Родитель
Сommit
9241994384

+ 8 - 1
src/sentry/api/serializers/models/activity.py

@@ -1,6 +1,7 @@
 import functools
 
 from sentry.api.serializers import Serializer, register, serialize
+from sentry.api.serializers.models.commit import CommitWithReleaseSerializer
 from sentry.models import Activity, Commit, Group, PullRequest
 from sentry.utils.functional import apply_values
 
@@ -19,7 +20,13 @@ class ActivitySerializer(Serializer):
         }
         if commit_ids:
             commit_list = list(Commit.objects.filter(id__in=commit_ids))
-            commits_by_id = {c.id: d for c, d in zip(commit_list, serialize(commit_list, user))}
+            commits_by_id = {
+                c.id: d
+                for c, d in zip(
+                    commit_list,
+                    serialize(commit_list, user, serializer=CommitWithReleaseSerializer()),
+                )
+            }
             commits = {
                 i: commits_by_id.get(i.data["commit"])
                 for i in item_list

+ 59 - 0
static/app/views/organizationGroupDetails/groupActivityItem.tsx

@@ -1,4 +1,5 @@
 import {Fragment} from 'react';
+import moment from 'moment';
 
 import CommitLink from 'sentry/components/commitLink';
 import Duration from 'sentry/components/duration';
@@ -9,6 +10,7 @@ import Version from 'sentry/components/version';
 import {t, tct, tn} from 'sentry/locale';
 import TeamStore from 'sentry/stores/teamStore';
 import {
+  BaseRelease,
   GroupActivity,
   GroupActivityAssigned,
   GroupActivitySetIgnored,
@@ -140,6 +142,63 @@ function GroupActivityItem({activity, orgSlug, projectId, author}: Props) {
               author,
             });
       case GroupActivityType.SET_RESOLVED_IN_COMMIT:
+        const deployedReleases: Array<BaseRelease> = [];
+        for (const release of activity.data.commit?.releases) {
+          if (release.dateReleased !== null) {
+            deployedReleases.push(release);
+          }
+        }
+        deployedReleases.sort(
+          (a, b) => moment(a.dateReleased).valueOf() - moment(b.dateReleased).valueOf()
+        );
+        if (deployedReleases.length === 1) {
+          return tct(
+            '[author] marked this issue as resolved in [version]\n' +
+              'This commit was released in [release]',
+            {
+              author,
+              version: (
+                <CommitLink
+                  inline
+                  commitId={activity.data.commit.id}
+                  repository={activity.data.commit.repository}
+                />
+              ),
+              release: (
+                <Version
+                  version={deployedReleases[0].version}
+                  projectId={projectId}
+                  tooltipRawVersion
+                />
+              ),
+            }
+          );
+        }
+        if (deployedReleases.length > 1) {
+          return tct(
+            '[author] marked this issue as resolved in [version]\n' +
+              'This commit was released in [release] and ' +
+              (deployedReleases.length - 1) +
+              ' others',
+            {
+              author,
+              version: (
+                <CommitLink
+                  inline
+                  commitId={activity.data.commit.id}
+                  repository={activity.data.commit.repository}
+                />
+              ),
+              release: (
+                <Version
+                  version={deployedReleases[0].version}
+                  projectId={projectId}
+                  tooltipRawVersion
+                />
+              ),
+            }
+          );
+        }
         return tct('[author] marked this issue as resolved in [version]', {
           author,
           version: (

+ 97 - 0
tests/js/spec/views/organizationGroupDetails/groupActivity.spec.jsx

@@ -89,6 +89,103 @@ describe('GroupActivity', function () {
     );
   });
 
+  it('resolved in commit with no releases', function () {
+    const wrapper = createWrapper({
+      activity: [
+        {
+          type: 'set_resolved_in_commit',
+          id: '123',
+          data: {
+            author: 'hello',
+            commit: {
+              id: 'komal-commit',
+              repository: {},
+              releases: [],
+            },
+          },
+          user: TestStubs.User(),
+        },
+      ],
+    });
+    expect(wrapper.find('GroupActivityItem').text()).toContain(
+      'Foo Bar marked this issue as resolved in komal-commit'
+    );
+  });
+
+  it('resolved in commit with one release', function () {
+    const wrapper = createWrapper({
+      activity: [
+        {
+          type: 'set_resolved_in_commit',
+          id: '123',
+          data: {
+            author: 'hello',
+            commit: {
+              id: 'komal-commit',
+              repository: {},
+              releases: [
+                {
+                  dateCreated: '2022-05-01',
+                  dateReleased: '2022-05-02',
+                  version: 'random',
+                },
+              ],
+            },
+          },
+          user: TestStubs.User(),
+        },
+      ],
+    });
+    expect(wrapper.find('GroupActivityItem').text()).toContain(
+      'Foo Bar marked this issue as resolved in komal-commit\n' +
+        'This commit was released in random'
+    );
+  });
+
+  it('resolved in commit with multiple releases', function () {
+    const wrapper = createWrapper({
+      activity: [
+        {
+          type: 'set_resolved_in_commit',
+          id: '123',
+          data: {
+            commit: {
+              id: 'komal-commit',
+              repository: {},
+              releases: [
+                {
+                  dateCreated: '2022-05-01',
+                  dateReleased: '2022-05-02',
+                  version: 'random',
+                },
+                {
+                  dateCreated: '2022-06-01',
+                  dateReleased: '2022-06-02',
+                  version: 'newest',
+                },
+                {
+                  dateCreated: '2021-08-03',
+                  dateReleased: '2021-08-03',
+                  version: 'oldest-release',
+                },
+                {
+                  dateCreated: '2022-04-21',
+                  dateReleased: '2022-04-21',
+                  version: 'randomTwo',
+                },
+              ],
+            },
+          },
+          user: TestStubs.User(),
+        },
+      ],
+    });
+    expect(wrapper.find('GroupActivityItem').text()).toContain(
+      'Foo Bar marked this issue as resolved in komal-commit\n' +
+        'This commit was released in oldest-release and 3 others'
+    );
+  });
+
   it('requests assignees that are not in the team store', async function () {
     const team = TestStubs.Team({id: '123', name: 'workflow'});
     const teamRequest = MockApiClient.addMockResponse({

+ 69 - 0
tests/sentry/api/serializers/test_activity.py

@@ -54,3 +54,72 @@ class GroupActivityTestCase(TestCase):
         commit = result["commit"]
         assert commit["repository"]["name"] == "organization-bar"
         assert commit["message"] == "gemuse"
+
+    def test_serialize_set_resolve_in_commit_activity_with_release(self):
+        project = self.create_project(name="test_throwaway")
+        group = self.create_group(project)
+        user = self.create_user()
+        release = self.create_release(project=project, user=user)
+        release.save()
+        commit = Commit.objects.filter(releasecommit__release_id=release.id).get()
+
+        Activity.objects.create(
+            project_id=project.id,
+            group=group,
+            type=Activity.SET_RESOLVED_IN_COMMIT,
+            ident=commit.id,
+            user=user,
+            data={"commit": commit.id},
+        )
+
+        act = Activity.objects.get(type=Activity.SET_RESOLVED_IN_COMMIT)
+        serialized = serialize(act)
+
+        assert len(serialized["data"]["commit"]["releases"]) == 1
+
+    def test_serialize_set_resolve_in_commit_activity_with_no_releases(self):
+        self.org = self.create_organization(name="komal-test")
+        project = self.create_project(name="random-proj")
+        user = self.create_user()
+        repo = self.create_repo(self.project, name="idk-repo")
+        group = self.create_group(project)
+
+        commit = Commit.objects.create(organization_id=self.org.id, repository_id=repo.id)
+
+        Activity.objects.create(
+            project_id=project.id,
+            group=group,
+            type=Activity.SET_RESOLVED_IN_COMMIT,
+            ident=commit.id,
+            user=user,
+            data={"commit": commit.id},
+        )
+
+        act = Activity.objects.get(type=Activity.SET_RESOLVED_IN_COMMIT)
+        serialized = serialize(act)
+
+        assert len(serialized["data"]["commit"]["releases"]) == 0
+        assert not Commit.objects.filter(releasecommit__id=commit.id).exists()
+
+    def test_serialize_set_resolve_in_commit_activity_with_release_not_deployed(self):
+        project = self.create_project(name="random-test")
+        group = self.create_group(project)
+        user = self.create_user()
+        release = self.create_release(project=project, user=user)
+        release.date_released = None
+        release.save()
+        commit = Commit.objects.filter(releasecommit__release_id=release.id).get()
+
+        Activity.objects.create(
+            project_id=project.id,
+            group=group,
+            type=Activity.SET_RESOLVED_IN_COMMIT,
+            ident=commit.id,
+            user=user,
+            data={"commit": commit.id},
+        )
+
+        act = Activity.objects.get(type=Activity.SET_RESOLVED_IN_COMMIT)
+        serialized = serialize(act)
+
+        assert len(serialized["data"]["commit"]["releases"]) == 1