Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move release commits endpoint to organization path #4863

Merged
merged 4 commits into from Mar 10, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES
Expand Up @@ -16,6 +16,7 @@ Schema Changes
~~~~~~~~~~~~~~

- Added ``Deploy`` model
- Added OrganizationReleaseCommitsEndpoint
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an API change.


Version 8.14.1
--------------
Expand Down
43 changes: 43 additions & 0 deletions src/sentry/api/endpoints/organization_release_commits.py
@@ -0,0 +1,43 @@
from __future__ import absolute_import

from sentry.api.base import DocSection
from sentry.api.bases.organization import OrganizationReleasesBaseEndpoint
from sentry.api.exceptions import ResourceDoesNotExist
from sentry.api.serializers import serialize
from sentry.models import Release, ReleaseCommit


class OrganizationReleaseCommitsEndpoint(OrganizationReleasesBaseEndpoint):
doc_section = DocSection.RELEASES

def get(self, request, organization, version):
"""
List an Organization Release's Commits
``````````````````````````````````````

Retrieve a list of commits for a given release.

:pparam string organization_slug: the slug of the organization the
release belongs to.
:pparam string version: the version identifier of the release.
:auth: required
"""
try:
release = Release.objects.get(
organization_id=organization.id,
projects=self.get_allowed_projects(request, organization),
version=version,
)
except Release.DoesNotExist:
raise ResourceDoesNotExist

queryset = ReleaseCommit.objects.filter(
release=release,
).select_related('commit', 'commit__author')

return self.paginate(
request=request,
queryset=queryset,
order_by='order',
on_results=lambda x: serialize([rc.commit for rc in x], request.user),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're only serializing the Commit objects instead of the ReleaseCommit, why don't we just query for Commits instead? Seems a bit awkward going through ReleaseCommit just to get that.

You could just do:

Commit.objects.filter(releasecommit__release=release)

And you'll directly have the objects you want. Then the order_by becomes releasecommit__order.

This gives us SQL like:

SELECT "sentry_commit"."id", "sentry_commit"."organization_id", "sentry_commit"."repository_id", "sentry_commit"."key", "sentry_commit"."date_added", "sentry_commit"."author_id", "sentry_commit"."message"
FROM "sentry_commit"
INNER JOIN "sentry_releasecommit" ON (
  "sentry_commit"."id" = "sentry_releasecommit"."commit_id"
)
WHERE "sentry_releasecommit"."release_id" = 1 
ORDER BY "sentry_releasecommit"."order" ASC

Unless I'm missing something here with what you're doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i just did it this way because that's how we were doing it in the project version of this endpoint (see below file). but i can change it in both places

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so that doesn't work because of https://github.com/getsentry/sentry/blob/master/src/sentry/api/paginator.py#L120

like Commit.objects.filter(releasecommit__release=release).order_by('releasecommit__order') works, but the paginator tries to do commit.releasecommit__order which doesn't.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

welp 😢

)
Expand Up @@ -7,14 +7,14 @@
from sentry.models import Release, ReleaseCommit


class ReleaseCommitsEndpoint(ProjectEndpoint):
class ProjectReleaseCommitsEndpoint(ProjectEndpoint):
doc_section = DocSection.RELEASES
permission_classes = (ProjectReleasePermission,)

def get(self, request, project, version):
"""
List a Release's Commits
````````````````````````
List a Project Release's Commits
````````````````````````````````

Retrieve a list of commits for a given release.

Expand Down
10 changes: 7 additions & 3 deletions src/sentry/api/urls.py
Expand Up @@ -46,6 +46,7 @@
from .endpoints.organization_release_details import OrganizationReleaseDetailsEndpoint
from .endpoints.organization_release_files import OrganizationReleaseFilesEndpoint
from .endpoints.organization_release_file_details import OrganizationReleaseFileDetailsEndpoint
from .endpoints.organization_release_commits import OrganizationReleaseCommitsEndpoint
from .endpoints.organization_repositories import OrganizationRepositoriesEndpoint
from .endpoints.organization_config_repositories import OrganizationConfigRepositoriesEndpoint
from .endpoints.organization_repository_commits import OrganizationRepositoryCommitsEndpoint
Expand Down Expand Up @@ -81,12 +82,12 @@
from .endpoints.project_user_reports import ProjectUserReportsEndpoint
from .endpoints.project_processingissues import ProjectProcessingIssuesEndpoint
from .endpoints.project_reprocessing import ProjectReprocessingEndpoint
from .endpoints.release_commits import ReleaseCommitsEndpoint
from .endpoints.filechange import CommitFileChangeEndpoint
from .endpoints.issues_resolved_in_release import IssuesResolvedInReleaseEndpoint
from .endpoints.project_release_details import ProjectReleaseDetailsEndpoint
from .endpoints.project_release_files import ProjectReleaseFilesEndpoint
from .endpoints.project_release_file_details import ProjectReleaseFileDetailsEndpoint
from .endpoints.project_release_commits import ProjectReleaseCommitsEndpoint
from .endpoints.release_deploys import ReleaseDeploysEndpoint
from .endpoints.dsym_files import DSymFilesEndpoint, GlobalDSymFilesEndpoint, \
UnknownDSymFilesEndpoint, UnknownGlobalDSymFilesEndpoint
Expand Down Expand Up @@ -223,6 +224,9 @@
url(r'^organizations/(?P<organization_slug>[^\/]+)/releases/(?P<version>[^/]+)/deploys/$',
ReleaseDeploysEndpoint.as_view(),
name='sentry-api-0-organization-release-deploys'),
url(r'^organizations/(?P<organization_slug>[^\/]+)/releases/(?P<version>[^/]+)/commits/$',
OrganizationReleaseCommitsEndpoint.as_view(),
name='sentry-api-0-organization-release-commits'),
url(r'^organizations/(?P<organization_slug>[^\/]+)/stats/$',
OrganizationStatsEndpoint.as_view(),
name='sentry-api-0-organization-stats'),
Expand Down Expand Up @@ -308,8 +312,8 @@
ProjectReleaseDetailsEndpoint.as_view(),
name='sentry-api-0-project-release-details'),
url(r'^projects/(?P<organization_slug>[^\/]+)/(?P<project_slug>[^\/]+)/releases/(?P<version>[^/]+)/commits/$',
ReleaseCommitsEndpoint.as_view(),
name='sentry-api-0-release-commits'),
ProjectReleaseCommitsEndpoint.as_view(),
name='sentry-api-0-project-release-commits'),
url(r'^projects/(?P<organization_slug>[^\/]+)/(?P<project_slug>[^\/]+)/releases/(?P<version>[^/]+)/resolved/$',
IssuesResolvedInReleaseEndpoint.as_view(),
name='sentry-api-0-release-resolved'),
Expand Down
57 changes: 57 additions & 0 deletions tests/sentry/api/endpoints/test_organization_release_commits.py
@@ -0,0 +1,57 @@
from __future__ import absolute_import

from django.core.urlresolvers import reverse

from sentry.models import Commit, Release, ReleaseCommit, Repository
from sentry.testutils import APITestCase


class ReleaseCommitsListTest(APITestCase):
def test_simple(self):
project = self.create_project(
name='foo',
)
release = Release.objects.create(
organization_id=project.organization_id,
version='1',
)
release.add_project(project)
repo = Repository.objects.create(
organization_id=project.organization_id,
name=project.name,
)
commit = Commit.objects.create(
organization_id=project.organization_id,
repository_id=repo.id,
key='a' * 40,
)
commit2 = Commit.objects.create(
organization_id=project.organization_id,
repository_id=repo.id,
key='b' * 40,
)
ReleaseCommit.objects.create(
organization_id=project.organization_id,
release=release,
commit=commit,
order=1,
)
ReleaseCommit.objects.create(
organization_id=project.organization_id,
release=release,
commit=commit2,
order=0,
)
url = reverse('sentry-api-0-organization-release-commits', kwargs={
'organization_slug': project.organization.slug,
'version': release.version,
})

self.login_as(user=self.user)

response = self.client.get(url)

assert response.status_code == 200, response.content
assert len(response.data) == 2
assert response.data[0]['id'] == commit2.key
assert response.data[1]['id'] == commit.key
Expand Up @@ -42,7 +42,7 @@ def test_simple(self):
commit=commit2,
order=0,
)
url = reverse('sentry-api-0-release-commits', kwargs={
url = reverse('sentry-api-0-project-release-commits', kwargs={
'organization_slug': project.organization.slug,
'project_slug': project.slug,
'version': release.version,
Expand Down