'Create a New Release for an Organization
Create a new release for the given Organization.  Releases are used by
Sentry to improve its error reporting abilities by correlating
first seen events with the release that might have introduced the
problem.
Releases are also necessary for sourcemaps and other debug features
that require manual upload for functioning well.
:pparam string organization_slug: the slug of the organization the
release belongs to.
:param string version: a version identifier for this release.  Can
be a version number, a commit hash etc.
:param string ref: an optional commit reference.  This is useful if
a tagged version has been provided.
:param url url: a URL that points to the release.  This can be the
path to an online interface to the sourcecode
for instance.
:param array projects: a list of project slugs that are involved in
this release
:param datetime dateReleased: an optional date that indicates when
the release went live.  If not provided
the current time is assumed.
:param array commits: an optional list of commit data to be associated
with the release. Commits must include parameters
``id`` (the sha of the commit), and can optionally
include ``repository``, ``message``, ``author_name``,
``author_email``, and ``timestamp``.
:param array refs: an optional way to indicate the start and end commits
for each repository included in a release. Head commits
must include parameters ``repository`` and ``commit``
(the HEAD sha). They can optionally include ``previousCommit``
(the sha of the HEAD of the previous release), which should
be specified if this is the first time you\'ve sent commit data.
:auth: required'

@attach_scenarios([create_new_org_release_scenario])
def post(self, request, organization):

    serializer = ReleaseSerializerWithProjects(data=request.DATA)
    if serializer.is_valid():
        result = serializer.object
        allowed_projects = {p.slug: p for p in self.get_allowed_projects(request, organization)}
        projects = []
        for slug in result['projects']:
            if (slug not in allowed_projects):
                return Response({'projects': ['Invalid    project    slugs']}, status=400)
            projects.append(allowed_projects[slug])
        try:
            with transaction.atomic():
                (release, created) = (Release.objects.create(organization_id=organization.id, version=result['version'], ref=result.get('ref'), url=result.get('url'), owner=result.get('owner'), date_released=result.get('dateReleased')), True)
        except IntegrityError:
            (release, created) = (Release.objects.get(organization_id=organization.id, version=result['version']), False)
        new_projects = []
        for project in projects:
            created = release.add_project(project)
            if created:
                new_projects.append(project)
        if release.date_released:
            for project in new_projects:
                Activity.objects.create(type=Activity.RELEASE, project=project, ident=result['version'], data={'version': result['version']}, datetime=release.date_released)
        commit_list = result.get('commits')
        if commit_list:
            release.set_commits(commit_list)
        refs = result.get('refs')
        if (not refs):
            refs = [{'repository': r['repository'], 'previousCommit': r.get('previousId'), 'commit': r['currentId']} for r in result.get('headCommits', [])]
        if refs:
            if (not request.user.is_authenticated()):
                return Response({'refs': ['You    must    use    an    authenticated    API    token    to    fetch    refs']}, status=400)
            fetch_commits = (not commit_list)
            try:
                release.set_refs(refs, request.user, fetch=fetch_commits)
            except InvalidRepository as exc:
                return Response({'refs': [exc.message]}, status=400)
        if ((not created) and (not new_projects)):
            status = 208
        else:
            status = 201
        return Response(serialize(release, request.user), status=status)
    return Response(serializer.errors, status=400)
