def post(self, request, organization):
        if not request.user.is_authenticated():
            return Response(status=401)

        if not self.has_feature(request, organization):
            return self.respond(
                {
                    'error_type': 'unavailable_feature',
                    'detail': ['You do not have that feature enabled']
                },
                status=403)

        provider_id = request.DATA.get('provider')

        if provider_id is not None and provider_id.startswith('integrations:'):
            try:
                provider_cls = bindings.get(
                    'integration-repository.provider').get(provider_id)
            except KeyError:
                return Response({
                    'error_type': 'validation',
                }, status=400)
            provider = provider_cls(id=provider_id)
            return provider.dispatch(request, organization)

        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response({
                'error_type': 'validation',
            }, status=400)

        provider = provider_cls(id=provider_id)
        return provider.dispatch(request, organization)
    def post(self, request, organization):
        if not request.user.is_authenticated():
            return Response(status=401)

        if not self.has_feature(request, organization):
            return self.respond({
                'error_type': 'unavailable_feature',
                'detail': ['You do not have that feature enabled']
            }, status=403)

        provider_id = request.DATA.get('provider')
        if features.has('organizations:internal-catchall', organization, actor=request.user):
            if provider_id is not None and provider_id.startswith('integrations:'):
                try:
                    provider_cls = bindings.get('integration-repository.provider').get(provider_id)
                except KeyError:
                    return Response(
                        {
                            'error_type': 'validation',
                        }, status=400
                    )
                provider = provider_cls(id=provider_id)
                return provider.dispatch(request, organization)

        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response(
                {
                    'error_type': 'validation',
                }, status=400
            )

        provider = provider_cls(id=provider_id)
        return provider.dispatch(request, organization)
    def post(self, request, organization):
        if not request.user.is_authenticated():
            return Response(status=401)
        provider_id = request.DATA.get('provider')

        if provider_id is not None and provider_id.startswith('integrations:'):
            try:
                provider_cls = bindings.get('integration-repository.provider').get(provider_id)
            except KeyError:
                return Response(
                    {
                        'error_type': 'validation',
                    }, status=400
                )
            provider = provider_cls(id=provider_id)
            return provider.dispatch(request, organization)

        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response(
                {
                    'error_type': 'validation',
                }, status=400
            )

        provider = provider_cls(id=provider_id)
        return provider.dispatch(request, organization)
Example #4
0
    def get(self, request, organization):
        provider_bindings = bindings.get('repository.provider')
        integrations_provider_bindings = bindings.get(
            'integration-repository.provider')

        providers = []
        for provider_id in provider_bindings:
            provider = provider_bindings.get(provider_id)(id=provider_id)
            # TODO(jess): figure out better way to exclude this
            if provider_id != 'github_apps':
                providers.append({
                    'id': provider_id,
                    'name': provider.name,
                    'config': provider.get_config(),
                })

        if features.has('organizations:internal-catchall',
                        organization,
                        actor=request.user):
            for provider_id in integrations_provider_bindings:
                provider = integrations_provider_bindings.get(provider_id)(
                    id=provider_id)
                providers.append({
                    'id': provider_id,
                    'name': provider.name,
                    'config': provider.get_config(organization),
                })

        return Response({
            'providers': providers,
        })
    def post(self, request, organization):
        if not request.user.is_authenticated():
            return Response(status=401)
        provider_id = request.data.get('provider')

        if provider_id is not None and provider_id.startswith('integrations:'):
            try:
                provider_cls = bindings.get(
                    'integration-repository.provider').get(provider_id)
            except KeyError:
                return Response({
                    'error_type': 'validation',
                }, status=400)
            provider = provider_cls(id=provider_id)
            return provider.dispatch(request, organization)

        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response({
                'error_type': 'validation',
            }, status=400)

        provider = provider_cls(id=provider_id)
        return provider.dispatch(request, organization)
Example #6
0
    def get_provider(self):
        from sentry.plugins import bindings
        if self.has_integration_provider():
            provider_cls = bindings.get('integration-repository.provider').get(self.provider)
            return provider_cls(self.provider)

        provider_cls = bindings.get('repository.provider').get(self.provider)
        return provider_cls(self.provider)
Example #7
0
    def get_provider(self):
        from sentry.plugins import bindings
        if self.has_integration_provider():
            provider_cls = bindings.get('integration-repository.provider').get(self.provider)
            return provider_cls(self.provider)

        provider_cls = bindings.get('repository.provider').get(self.provider)
        return provider_cls(self.provider)
Example #8
0
    def get_provider(self):
        from sentry.plugins import bindings
        if self.provider and self.provider.startswith('integrations:'):
            provider_cls = bindings.get('integration-repository.provider').get(
                self.provider)
            return provider_cls(self.provider)

        provider_cls = bindings.get('repository.provider').get(self.provider)
        return provider_cls(self.provider)
Example #9
0
    def post(self, request, organization):
        if not request.user.is_authenticated():
            return Response(status=401)

        if not self.has_feature(request, organization):
            return self.respond(
                {
                    'error_type': 'unavailable_feature',
                    'detail': ['You do not have that feature enabled']
                },
                status=403)

        provider_id = request.DATA.get('provider')
        has_ghe = provider_id == 'integrations:github_enterprise' and features.has(
            'organizations:github-enterprise',
            organization,
            actor=request.user)
        has_bb = provider_id == 'integrations:bitbucket' and features.has(
            'organizations:bitbucket-integration',
            organization,
            actor=request.user)
        has_vsts = provider_id == 'integrations:vsts' and features.has(
            'organizations:vsts-integration', organization, actor=request.user)
        has_github = provider_id == 'integrations:github' and features.has(
            'organizations:github-apps', organization, actor=request.user)

        if features.has('organizations:internal-catchall',
                        organization,
                        actor=request.user
                        ) or has_ghe or has_bb or has_vsts or has_github:
            if provider_id is not None and provider_id.startswith(
                    'integrations:'):
                try:
                    provider_cls = bindings.get(
                        'integration-repository.provider').get(provider_id)
                except KeyError:
                    return Response({
                        'error_type': 'validation',
                    }, status=400)
                provider = provider_cls(id=provider_id)
                return provider.dispatch(request, organization)

        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response({
                'error_type': 'validation',
            }, status=400)

        provider = provider_cls(id=provider_id)
        return provider.dispatch(request, organization)
Example #10
0
def fetch_commits(release_id, user_id, refs, prev_release_id=None, **kwargs):
    commit_list = []

    release = Release.objects.get(id=release_id)
    user = User.objects.get(id=user_id)

    prev_release = None
    if prev_release_id is not None:
        try:
            prev_release = Release.objects.get(id=prev_release_id)
        except Release.DoesNotExist:
            pass

    for ref in refs:
        try:
            repo = Repository.objects.get(
                organization_id=release.organization_id,
                name=ref['repository'],
            )
        except Repository.DoesNotExist:
            continue

        try:
            provider_cls = bindings.get('repository.provider').get(
                repo.provider)
        except KeyError:
            continue

        # if previous commit isn't provided, try to get from
        # previous release otherwise, try to get
        # recent commits from provider api
        start_sha = None
        if ref.get('previousCommit'):
            start_sha = ref['previousCommit']
        elif prev_release:
            try:
                start_sha = Commit.objects.filter(
                    organization_id=release.organization_id,
                    releaseheadcommit__release=prev_release,
                    repository_id=repo.id,
                ).values_list('key', flat=True)[0]
            except IndexError:
                pass

        end_sha = ref['commit']
        provider = provider_cls(id=repo.provider)
        try:
            repo_commits = provider.compare_commits(repo,
                                                    start_sha,
                                                    end_sha,
                                                    actor=user)
        except NotImplementedError:
            pass
        except (PluginError, InvalidIdentity) as e:
            logger.exception(six.text_type(e))
        else:
            commit_list.extend(repo_commits)

    if commit_list:
        release.set_commits(commit_list)
Example #11
0
 def _external_url(self, repository, pull):
     from sentry.plugins import bindings
     provider_id = repository.provider
     if not provider_id or not provider_id.startswith('integrations:'):
         return None
     provider_cls = bindings.get('integration-repository.provider').get(provider_id)
     provider = provider_cls(provider_id)
     return provider.pull_request_url(repository, pull)
Example #12
0
 def _external_url(self, repository, pull):
     from sentry.plugins import bindings
     provider_id = repository.provider
     if not provider_id or not provider_id.startswith('integrations:'):
         return None
     provider_cls = bindings.get('integration-repository.provider').get(provider_id)
     provider = provider_cls(provider_id)
     return provider.pull_request_url(repository, pull)
    def get(self, request, organization):
        provider_bindings = bindings.get("repository.provider")
        providers = []
        for provider_id in provider_bindings:
            provider = provider_bindings.get(provider_id)(id=provider_id)
            # TODO(jess): figure out better way to exclude this
            if provider_id == "github_apps":
                continue
            providers.append(
                {"id": provider_id, "name": provider.name, "config": provider.get_config()}
            )

        return Response({"providers": providers})
    def post(self, request, organization):
        if not request.user.is_authenticated():
            return Response(status=401)

        provider_id = request.DATA.get('provider')
        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response({
                'error_type': 'validation',
            }, status=400)

        provider = provider_cls(id=provider_id)
        return provider.dispatch(request, organization)
Example #15
0
    def get(self, request, organization):
        if not self.has_feature(request, organization):
            return Response(
                {'detail': ['You do not have that feature enabled']},
                status=400)

        # Right now, this is just repository providers, but in
        # theory we want it to also work for other types of plugins
        # in the future
        return Response(
            serialize([
                provider_cls(id=provider_id) for provider_id, provider_cls in
                bindings.get('repository.provider').all()
            ], request.user, ProviderSerializer(organization)))
Example #16
0
    def get(self, request, organization):
        provider_bindings = bindings.get('repository.provider')

        providers = []
        for provider_id in provider_bindings:
            provider = provider_bindings.get(provider_id)(id=provider_id)
            providers.append({
                'id': provider_id,
                'name': provider.name,
                'config': provider.get_config(),
            })

        return Response({
            'providers': providers,
        })
    def get(self, request, organization):
        provider_bindings = bindings.get('repository.provider')

        providers = []
        for provider_id in provider_bindings:
            provider = provider_bindings.get(provider_id)(id=provider_id)
            if provider_id != 'bitbucket' or features.has('organizations:bitbucket-repos', organization):
                providers.append({
                    'id': provider_id,
                    'name': provider.name,
                    'config': provider.get_config(),
                })

        return Response({
            'providers': providers,
        })
Example #18
0
    def get(self, request, organization):
        provider_bindings = bindings.get('repository.provider')

        providers = []
        for provider_id in provider_bindings:
            provider = provider_bindings.get(provider_id)(id=provider_id)
            if provider_id != 'bitbucket' or features.has(
                    'organizations:bitbucket-repos', organization):
                providers.append({
                    'id': provider_id,
                    'name': provider.name,
                    'config': provider.get_config(),
                })

        return Response({
            'providers': providers,
        })
    def get(self, request, organization):
        provider_bindings = bindings.get('repository.provider')
        providers = []
        for provider_id in provider_bindings:
            provider = provider_bindings.get(provider_id)(id=provider_id)
            # TODO(jess): figure out better way to exclude this
            if provider_id == 'github_apps':
                continue
            providers.append({
                'id': provider_id,
                'name': provider.name,
                'config': provider.get_config(),
            })

        return Response({
            'providers': providers,
        })
Example #20
0
    def post(self, request, organization):
        if not self.has_feature(request, organization):
            return Response(
                {'detail': ['You do not have that feature enabled']},
                status=400)

        serializer = IntegrationSerializer(data=request.DATA)

        if not serializer.is_valid():
            return Response(serializer.errors, status=400)

        result = serializer.object

        provider_id = result['provider']

        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response({
                'error_type': 'validation',
            }, status=400)

        provider = provider_cls(id=provider_id)

        try:
            # raise if they're trying to link an auth they
            # aren't allowed to
            provider.link_auth(
                request.user, organization, {
                    'default_auth_id': result.get('defaultAuthId'),
                    'integration_id': result.get('integrationId'),
                })
        except PluginError as exc:
            return Response(
                {
                    'error_type': 'validation',
                    'message': exc.message,
                },
                status=400)

        return Response(serialize(provider, request.user,
                                  ProviderSerializer(organization)),
                        status=201)
    def get(self, request, organization):
        provider_bindings = bindings.get('repository.provider')
        providers = []
        for provider_id in provider_bindings:
            provider = provider_bindings.get(provider_id)(id=provider_id)
            # TODO(jess): figure out better way to exclude this
            if provider_id == 'github_apps':
                continue
            providers.append(
                {
                    'id': provider_id,
                    'name': provider.name,
                    'config': provider.get_config(),
                }
            )

        return Response({
            'providers': providers,
        })
    def post(self, request, organization):
        if not request.user.is_authenticated():
            return Response(status=401)

        if not self.has_feature(request, organization):
            return self.respond({
                'error_type': 'unavailable_feature',
                'detail': ['You do not have that feature enabled']
            }, status=403)

        provider_id = request.DATA.get('provider')
        try:
            provider_cls = bindings.get('repository.provider').get(provider_id)
        except KeyError:
            return Response(
                {
                    'error_type': 'validation',
                }, status=400
            )

        provider = provider_cls(id=provider_id)
        return provider.dispatch(request, organization)
Example #23
0
    def set_refs(self, refs, user, fetch_commits=False):
        from sentry.models import Commit, ReleaseHeadCommit, Repository
        from sentry.plugins import bindings

        # TODO: this does the wrong thing unless you are on the most
        # recent release.  Add a timestamp compare?
        prev_release = type(self).objects.filter(
            organization_id=self.organization_id,
            projects__in=self.projects.all(),
        ).exclude(version=self.version).order_by('-date_added').first()

        commit_list = []

        for ref in refs:
            try:
                repo = Repository.objects.get(
                    organization_id=self.organization_id,
                    name=ref['repository'],
                )
            except Repository.DoesNotExist:
                continue

            commit = Commit.objects.get_or_create(
                organization_id=self.organization_id,
                repository_id=repo.id,
                key=ref['commit'],
            )[0]
            # update head commit for repo/release if exists
            ReleaseHeadCommit.objects.create_or_update(
                organization_id=self.organization_id,
                repository_id=repo.id,
                release=self,
                values={
                    'commit': commit,
                })
            if fetch_commits:
                try:
                    provider_cls = bindings.get('repository.provider').get(
                        repo.provider)
                except KeyError:
                    continue

                # if previous commit isn't provided, try to get from
                # previous release otherwise, give up
                if ref.get('previousCommit'):
                    start_sha = ref['previousCommit']
                elif prev_release:
                    try:
                        start_sha = Commit.objects.filter(
                            organization_id=self.organization_id,
                            releaseheadcommit__release=prev_release,
                            repository_id=repo.id,
                        ).values_list('key', flat=True)[0]
                    except IndexError:
                        continue
                else:
                    continue

                end_sha = commit.key
                provider = provider_cls(id=repo.provider)
                try:
                    repo_commits = provider.compare_commits(repo,
                                                            start_sha,
                                                            end_sha,
                                                            actor=user)
                except NotImplementedError:
                    pass
                except (PluginError, InvalidIdentity) as e:
                    logger.exception(six.text_type(e))
                else:
                    commit_list.extend(repo_commits)

            if commit_list:
                self.set_commits(commit_list)
Example #24
0
def fetch_commits(release_id, user_id, refs, prev_release_id=None, **kwargs):
    # TODO(dcramer): this function could use some cleanup/refactoring as it's a bit unwieldy
    commit_list = []

    release = Release.objects.get(id=release_id)
    user = User.objects.get(id=user_id)
    prev_release = None
    if prev_release_id is not None:
        try:
            prev_release = Release.objects.get(id=prev_release_id)
        except Release.DoesNotExist:
            pass

    for ref in refs:
        try:
            repo = Repository.objects.get(
                organization_id=release.organization_id,
                name=ref["repository"])
        except Repository.DoesNotExist:
            logger.info(
                "repository.missing",
                extra={
                    "organization_id": release.organization_id,
                    "user_id": user_id,
                    "repository": ref["repository"],
                },
            )
            continue

        binding_key = ("integration-repository.provider"
                       if is_integration_provider(repo.provider) else
                       "repository.provider")
        try:
            provider_cls = bindings.get(binding_key).get(repo.provider)
        except KeyError:
            continue

        # if previous commit isn't provided, try to get from
        # previous release otherwise, try to get
        # recent commits from provider api
        start_sha = None
        if ref.get("previousCommit"):
            start_sha = ref["previousCommit"]
        elif prev_release:
            try:
                start_sha = ReleaseHeadCommit.objects.filter(
                    organization_id=release.organization_id,
                    release=prev_release,
                    repository_id=repo.id,
                ).values_list("commit__key", flat=True)[0]
            except IndexError:
                pass

        end_sha = ref["commit"]
        provider = provider_cls(id=repo.provider)
        try:
            if is_integration_provider(provider.id):
                repo_commits = provider.compare_commits(
                    repo, start_sha, end_sha)
            else:
                repo_commits = provider.compare_commits(repo,
                                                        start_sha,
                                                        end_sha,
                                                        actor=user)
        except NotImplementedError:
            pass
        except Exception as exc:
            logger.info(
                "fetch_commits.error",
                extra={
                    "organization_id": repo.organization_id,
                    "user_id": user_id,
                    "repository": repo.name,
                    "provider": provider.id,
                    "error": six.text_type(exc),
                    "end_sha": end_sha,
                    "start_sha": start_sha,
                },
            )
            if isinstance(exc, InvalidIdentity) and getattr(
                    exc, "identity", None):
                handle_invalid_identity(identity=exc.identity,
                                        commit_failure=True)
            elif isinstance(exc,
                            (PluginError, InvalidIdentity, IntegrationError)):
                msg = generate_fetch_commits_error_email(release, exc.message)
                msg.send_async(to=[user.email])
            else:
                msg = generate_fetch_commits_error_email(
                    release, "An internal system error occurred.")
                msg.send_async(to=[user.email])
        else:
            logger.info(
                "fetch_commits.complete",
                extra={
                    "organization_id": repo.organization_id,
                    "user_id": user_id,
                    "repository": repo.name,
                    "end_sha": end_sha,
                    "start_sha": start_sha,
                    "num_commits": len(repo_commits or []),
                },
            )
            commit_list.extend(repo_commits)

    if commit_list:
        release.set_commits(commit_list)
        deploys = Deploy.objects.filter(
            organization_id=release.organization_id,
            release=release,
            notified=False).values_list("id", "environment_id",
                                        "date_finished")

        # XXX(dcramer): i dont know why this would have multiple environments, but for
        # our sanity lets assume it can
        pending_notifications = []
        last_deploy_per_environment = {}
        for deploy_id, environment_id, date_finished in deploys:
            last_deploy_per_environment[environment_id] = (deploy_id,
                                                           date_finished)
            pending_notifications.append(deploy_id)

        repo_queryset = ReleaseHeadCommit.objects.filter(
            organization_id=release.organization_id,
            release=release).values_list("repository_id", "commit")

        # we need to mark LatestRelease, but only if there's not a deploy which has completed
        # *after* this deploy (given we might process commits out of order)
        for repository_id, commit_id in repo_queryset:
            for environment_id, (deploy_id, date_finished) in six.iteritems(
                    last_deploy_per_environment):
                if not Deploy.objects.filter(
                        id__in=LatestRelease.objects.filter(
                            repository_id=repository_id,
                            environment_id=environment_id).values("deploy_id"),
                        date_finished__gt=date_finished,
                ).exists():
                    LatestRelease.objects.create_or_update(
                        repository_id=repository_id,
                        environment_id=environment_id,
                        values={
                            "release_id": release.id,
                            "deploy_id": deploy_id,
                            "commit_id": commit_id,
                        },
                    )

        for deploy_id in pending_notifications:
            Deploy.notify_if_ready(deploy_id, fetch_complete=True)
Example #25
0
def fetch_commits(release_id, user_id, refs, prev_release_id=None, **kwargs):
    commit_list = []

    release = Release.objects.get(id=release_id)
    user = User.objects.get(id=user_id)

    prev_release = None
    if prev_release_id is not None:
        try:
            prev_release = Release.objects.get(id=prev_release_id)
        except Release.DoesNotExist:
            pass

    for ref in refs:
        try:
            repo = Repository.objects.get(
                organization_id=release.organization_id,
                name=ref['repository'],
            )
        except Repository.DoesNotExist:
            logger.info('repository.missing',
                        extra={
                            'organization_id': release.organization_id,
                            'user_id': user_id,
                            'repository': ref['repository'],
                        })
            continue

        try:
            provider_cls = bindings.get('repository.provider').get(
                repo.provider)
        except KeyError:
            continue

        # if previous commit isn't provided, try to get from
        # previous release otherwise, try to get
        # recent commits from provider api
        start_sha = None
        if ref.get('previousCommit'):
            start_sha = ref['previousCommit']
        elif prev_release:
            try:
                start_sha = ReleaseHeadCommit.objects.filter(
                    organization_id=release.organization_id,
                    release=prev_release,
                    repository_id=repo.id,
                ).values_list('commit__key', flat=True)[0]
            except IndexError:
                pass

        end_sha = ref['commit']
        provider = provider_cls(id=repo.provider)

        try:
            repo_commits = provider.compare_commits(repo,
                                                    start_sha,
                                                    end_sha,
                                                    actor=user)
        except NotImplementedError:
            pass
        except Exception as exc:
            logger.exception('fetch_commits.error',
                             exc_info=True,
                             extra={
                                 'organization_id': repo.organization_id,
                                 'user_id': user_id,
                                 'repository': repo.name,
                                 'end_sha': end_sha,
                                 'start_sha': start_sha,
                             })
            if isinstance(exc, InvalidIdentity) and getattr(
                    exc, 'identity', None):
                handle_invalid_identity(identity=exc.identity,
                                        commit_failure=True)
            elif isinstance(exc, (PluginError, InvalidIdentity)):
                msg = generate_fetch_commits_error_email(release, exc.message)
                msg.send_async(to=[user.email])
            else:
                msg = generate_fetch_commits_error_email(
                    release, 'An internal system error occurred.')
                msg.send_async(to=[user.email])
        else:
            logger.info('fetch_commits.complete',
                        extra={
                            'organization_id': repo.organization_id,
                            'user_id': user_id,
                            'repository': repo.name,
                            'end_sha': end_sha,
                            'start_sha': start_sha,
                            'num_commits': len(repo_commits or []),
                        })
            commit_list.extend(repo_commits)

    if commit_list:
        release.set_commits(commit_list)
        deploys = Deploy.objects.filter(
            organization_id=release.organization_id,
            release=release,
            notified=False,
        ).values_list('id', flat=True)
        for d_id in deploys:
            Deploy.notify_if_ready(d_id, fetch_complete=True)
Example #26
0
def fetch_commits(release_id, user_id, refs, prev_release_id=None, **kwargs):
    commit_list = []

    release = Release.objects.get(id=release_id)
    user = User.objects.get(id=user_id)

    prev_release = None
    if prev_release_id is not None:
        try:
            prev_release = Release.objects.get(id=prev_release_id)
        except Release.DoesNotExist:
            pass

    for ref in refs:
        try:
            repo = Repository.objects.get(
                organization_id=release.organization_id,
                name=ref['repository'],
            )
        except Repository.DoesNotExist:
            logger.info(
                'repository.missing',
                extra={
                    'organization_id': release.organization_id,
                    'user_id': user_id,
                    'repository': ref['repository'],
                }
            )
            continue

        try:
            provider_cls = bindings.get('repository.provider').get(repo.provider)
        except KeyError:
            continue

        # if previous commit isn't provided, try to get from
        # previous release otherwise, try to get
        # recent commits from provider api
        start_sha = None
        if ref.get('previousCommit'):
            start_sha = ref['previousCommit']
        elif prev_release:
            try:
                start_sha = ReleaseHeadCommit.objects.filter(
                    organization_id=release.organization_id,
                    release=prev_release,
                    repository_id=repo.id,
                ).values_list(
                    'commit__key', flat=True
                )[0]
            except IndexError:
                pass

        end_sha = ref['commit']
        provider = provider_cls(id=repo.provider)

        try:
            repo_commits = provider.compare_commits(repo, start_sha, end_sha, actor=user)
        except NotImplementedError:
            pass
        except Exception as exc:
            logger.exception(
                'fetch_commits.error',
                exc_info=True,
                extra={
                    'organization_id': repo.organization_id,
                    'user_id': user_id,
                    'repository': repo.name,
                    'end_sha': end_sha,
                    'start_sha': start_sha,
                }
            )
            if isinstance(exc, InvalidIdentity) and getattr(exc, 'identity', None):
                handle_invalid_identity(identity=exc.identity, commit_failure=True)
            elif isinstance(exc, (PluginError, InvalidIdentity)):
                msg = generate_fetch_commits_error_email(release, exc.message)
                msg.send_async(to=[user.email])
            else:
                msg = generate_fetch_commits_error_email(
                    release, 'An internal system error occurred.')
                msg.send_async(to=[user.email])
        else:
            logger.info(
                'fetch_commits.complete',
                extra={
                    'organization_id': repo.organization_id,
                    'user_id': user_id,
                    'repository': repo.name,
                    'end_sha': end_sha,
                    'start_sha': start_sha,
                    'num_commits': len(repo_commits or []),
                }
            )
            commit_list.extend(repo_commits)

    if commit_list:
        release.set_commits(commit_list)
        deploys = Deploy.objects.filter(
            organization_id=release.organization_id,
            release=release,
            notified=False,
        ).values_list(
            'id', flat=True
        )
        for d_id in deploys:
            Deploy.notify_if_ready(d_id, fetch_complete=True)
Example #27
0
def fetch_commits(release_id, user_id, refs, prev_release_id=None, **kwargs):
    # TODO(dcramer): this function could use some cleanup/refactoring as its a bit unwieldly
    commit_list = []

    release = Release.objects.get(id=release_id)
    user = User.objects.get(id=user_id)

    prev_release = None
    if prev_release_id is not None:
        try:
            prev_release = Release.objects.get(id=prev_release_id)
        except Release.DoesNotExist:
            pass

    for ref in refs:
        try:
            repo = Repository.objects.get(
                organization_id=release.organization_id,
                name=ref['repository'],
            )
        except Repository.DoesNotExist:
            logger.info('repository.missing',
                        extra={
                            'organization_id': release.organization_id,
                            'user_id': user_id,
                            'repository': ref['repository'],
                        })
            continue

        binding_key = 'integration-repository.provider' if repo.provider and repo.provider.startswith(
            'integrations:') else 'repository.provider'
        try:
            provider_cls = bindings.get(binding_key).get(repo.provider)
        except KeyError:
            continue

        # if previous commit isn't provided, try to get from
        # previous release otherwise, try to get
        # recent commits from provider api
        start_sha = None
        if ref.get('previousCommit'):
            start_sha = ref['previousCommit']
        elif prev_release:
            try:
                start_sha = ReleaseHeadCommit.objects.filter(
                    organization_id=release.organization_id,
                    release=prev_release,
                    repository_id=repo.id,
                ).values_list('commit__key', flat=True)[0]
            except IndexError:
                pass

        end_sha = ref['commit']
        provider = provider_cls(id=repo.provider)

        try:
            repo_commits = provider.compare_commits(repo,
                                                    start_sha,
                                                    end_sha,
                                                    actor=user)
        except NotImplementedError:
            pass
        except Exception as exc:
            logger.exception('fetch_commits.error',
                             exc_info=True,
                             extra={
                                 'organization_id': repo.organization_id,
                                 'user_id': user_id,
                                 'repository': repo.name,
                                 'end_sha': end_sha,
                                 'start_sha': start_sha,
                             })
            if isinstance(exc, InvalidIdentity) and getattr(
                    exc, 'identity', None):
                handle_invalid_identity(identity=exc.identity,
                                        commit_failure=True)
            elif isinstance(exc, (PluginError, InvalidIdentity)):
                msg = generate_fetch_commits_error_email(release, exc.message)
                msg.send_async(to=[user.email])
            else:
                msg = generate_fetch_commits_error_email(
                    release, 'An internal system error occurred.')
                msg.send_async(to=[user.email])
        else:
            logger.info('fetch_commits.complete',
                        extra={
                            'organization_id': repo.organization_id,
                            'user_id': user_id,
                            'repository': repo.name,
                            'end_sha': end_sha,
                            'start_sha': start_sha,
                            'num_commits': len(repo_commits or []),
                        })
            commit_list.extend(repo_commits)

    if commit_list:
        release.set_commits(commit_list)
        deploys = Deploy.objects.filter(
            organization_id=release.organization_id,
            release=release,
            notified=False,
        ).values_list('id', 'environment_id', 'date_finished')

        # XXX(dcramer): i dont know why this would have multiple environments, but for
        # our sanity lets assume it can
        pending_notifications = []
        last_deploy_per_environment = {}
        for deploy_id, environment_id, date_finished in deploys:
            last_deploy_per_environment[environment_id] = (deploy_id,
                                                           date_finished)
            pending_notifications.append(deploy_id)

        repo_queryset = ReleaseHeadCommit.objects.filter(
            organization_id=release.organization_id,
            release=release,
        ).values_list(
            'repository_id',
            'commit',
        )

        # we need to mark LatestRelease, but only if there's not a deploy which has completed
        # *after* this deploy (given we might process commits out of order)
        for repository_id, commit_id in repo_queryset:
            for environment_id, (deploy_id, date_finished) in six.iteritems(
                    last_deploy_per_environment):
                if not Deploy.objects.filter(
                        id__in=LatestRelease.objects.filter(
                            repository_id=repository_id,
                            environment_id=environment_id,
                        ).values('deploy_id'),
                        date_finished__gt=date_finished,
                ).exists():
                    LatestRelease.objects.create_or_update(
                        repository_id=repository_id,
                        environment_id=environment_id,
                        values={
                            'release_id': release.id,
                            'deploy_id': deploy_id,
                            'commit_id': commit_id,
                        })

        for deploy_id in pending_notifications:
            Deploy.notify_if_ready(deploy_id, fetch_complete=True)
Example #28
0
 def get_provider(self):
     from sentry.plugins import bindings
     provider_cls = bindings.get('repository.provider').get(self.provider)
     return provider_cls(self.provider)
Example #29
0
    def set_head_commits(self, head_commits, user, fetch_commits=False):
        from sentry.models import Commit, ReleaseHeadCommit, Repository
        from sentry.plugins import bindings

        prev_release = type(self).objects.filter(
            organization_id=self.organization_id,
            projects__in=self.projects.all(),
        ).order_by('-date_added').first()

        commit_list = []

        for head_commit in head_commits:
            try:
                repo = Repository.objects.get(
                    organization_id=self.organization_id,
                    name=head_commit['repository'],
                )
            except Repository.DoesNotExist:
                continue

            commit = Commit.objects.get_or_create(
                organization_id=self.organization_id,
                repository_id=repo.id,
                key=head_commit['currentId'],
            )[0]
            # update head commit for repo/release if exists
            ReleaseHeadCommit.objects.create_or_update(
                organization_id=self.organization_id,
                repository_id=repo.id,
                release=self,
                values={
                    'commit': commit,
                }
            )
            if fetch_commits:
                try:
                    provider_cls = bindings.get('repository.provider').get(repo.provider)
                except KeyError:
                    continue

                # if previous commit isn't provided, try to get from
                # previous release otherwise, give up
                if head_commit.get('previousId'):
                    start_sha = head_commit['previousId']
                elif prev_release:
                    try:
                        start_sha = Commit.objects.filter(
                            organization_id=self.organization_id,
                            releaseheadcommit__release=prev_release,
                            repository_id=repo.id,
                        ).values_list('key', flat=True)[0]
                    except IndexError:
                        continue
                else:
                    continue

                end_sha = commit.key
                provider = provider_cls(id=repo.provider)
                try:
                    repo_commits = provider.compare_commits(
                        repo, start_sha, end_sha, actor=user
                    )
                except NotImplementedError:
                    pass
                except (PluginError, InvalidIdentity) as e:
                    logger.exception(six.text_type(e))
                else:
                    commit_list.extend(repo_commits)

            if commit_list:
                self.set_commits(commit_list)
Example #30
0
 def get_provider(self):
     from sentry.plugins import bindings
     provider_cls = bindings.get('repository.provider').get(self.provider)
     return provider_cls(self.provider)
Example #31
0
def fetch_commits(release_id, user_id, refs, prev_release_id=None, **kwargs):
    # TODO(dcramer): this function could use some cleanup/refactoring as its a bit unwieldly
    commit_list = []

    release = Release.objects.get(id=release_id)
    user = User.objects.get(id=user_id)
    prev_release = None
    if prev_release_id is not None:
        try:
            prev_release = Release.objects.get(id=prev_release_id)
        except Release.DoesNotExist:
            pass

    for ref in refs:
        try:
            repo = Repository.objects.get(
                organization_id=release.organization_id,
                name=ref['repository'],
            )
        except Repository.DoesNotExist:
            logger.info(
                'repository.missing',
                extra={
                    'organization_id': release.organization_id,
                    'user_id': user_id,
                    'repository': ref['repository'],
                }
            )
            continue

        binding_key = 'integration-repository.provider' if is_integration_provider(repo.provider) else 'repository.provider'
        try:
            provider_cls = bindings.get(binding_key).get(repo.provider)
        except KeyError:
            continue

        # if previous commit isn't provided, try to get from
        # previous release otherwise, try to get
        # recent commits from provider api
        start_sha = None
        if ref.get('previousCommit'):
            start_sha = ref['previousCommit']
        elif prev_release:
            try:
                start_sha = ReleaseHeadCommit.objects.filter(
                    organization_id=release.organization_id,
                    release=prev_release,
                    repository_id=repo.id,
                ).values_list(
                    'commit__key', flat=True
                )[0]
            except IndexError:
                pass

        end_sha = ref['commit']
        provider = provider_cls(id=repo.provider)
        try:
            if is_integration_provider(provider.id):
                repo_commits = provider.compare_commits(repo, start_sha, end_sha)
            else:
                repo_commits = provider.compare_commits(repo, start_sha, end_sha, actor=user)
        except NotImplementedError:
            pass
        except Exception as exc:
            logger.exception(
                'fetch_commits.error',
                exc_info=True,
                extra={
                    'organization_id': repo.organization_id,
                    'user_id': user_id,
                    'repository': repo.name,
                    'end_sha': end_sha,
                    'start_sha': start_sha,
                }
            )
            if isinstance(exc, InvalidIdentity) and getattr(exc, 'identity', None):
                handle_invalid_identity(identity=exc.identity, commit_failure=True)
            elif isinstance(exc, (PluginError, InvalidIdentity)):
                msg = generate_fetch_commits_error_email(release, exc.message)
                msg.send_async(to=[user.email])
            else:
                msg = generate_fetch_commits_error_email(
                    release, 'An internal system error occurred.')
                msg.send_async(to=[user.email])
        else:
            logger.info(
                'fetch_commits.complete',
                extra={
                    'organization_id': repo.organization_id,
                    'user_id': user_id,
                    'repository': repo.name,
                    'end_sha': end_sha,
                    'start_sha': start_sha,
                    'num_commits': len(repo_commits or []),
                }
            )
            commit_list.extend(repo_commits)

    if commit_list:
        release.set_commits(commit_list)
        deploys = Deploy.objects.filter(
            organization_id=release.organization_id,
            release=release,
            notified=False,
        ).values_list(
            'id', 'environment_id', 'date_finished'
        )

        # XXX(dcramer): i dont know why this would have multiple environments, but for
        # our sanity lets assume it can
        pending_notifications = []
        last_deploy_per_environment = {}
        for deploy_id, environment_id, date_finished in deploys:
            last_deploy_per_environment[environment_id] = (deploy_id, date_finished)
            pending_notifications.append(deploy_id)

        repo_queryset = ReleaseHeadCommit.objects.filter(
            organization_id=release.organization_id,
            release=release,
        ).values_list(
            'repository_id', 'commit',
        )

        # we need to mark LatestRelease, but only if there's not a deploy which has completed
        # *after* this deploy (given we might process commits out of order)
        for repository_id, commit_id in repo_queryset:
            for environment_id, (deploy_id, date_finished) in six.iteritems(
                    last_deploy_per_environment):
                if not Deploy.objects.filter(
                    id__in=LatestRelease.objects.filter(
                        repository_id=repository_id,
                        environment_id=environment_id,
                    ).values('deploy_id'),
                    date_finished__gt=date_finished,
                ).exists():
                    LatestRelease.objects.create_or_update(
                        repository_id=repository_id,
                        environment_id=environment_id,
                        values={
                            'release_id': release.id,
                            'deploy_id': deploy_id,
                            'commit_id': commit_id,
                        }
                    )

        for deploy_id in pending_notifications:
            Deploy.notify_if_ready(deploy_id, fetch_complete=True)