示例#1
0
    def get_provider(self):
        from sentry.plugins.base 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)
示例#2
0
    def _external_url(self, repository, pull):
        from sentry.plugins.base 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)
示例#3
0
    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)
    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})
示例#5
0
文件: commits.py 项目: sugusbs/sentry
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 e:
            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(e),
                    "end_sha": end_sha,
                    "start_sha": start_sha,
                },
            )
            if isinstance(e, InvalidIdentity) and getattr(e, "identity", None):
                handle_invalid_identity(identity=e.identity,
                                        commit_failure=True)
            elif isinstance(e,
                            (PluginError, InvalidIdentity, IntegrationError)):
                msg = generate_fetch_commits_error_email(
                    release, repo, six.text_type(e))
                emails = get_emails_for_user_or_org(user,
                                                    release.organization_id)
                msg.send_async(to=emails)
            else:
                msg = generate_fetch_commits_error_email(
                    release, repo, "An internal system error occurred.")
                emails = get_emails_for_user_or_org(user,
                                                    release.organization_id)
                msg.send_async(to=emails)
        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:
        try:
            release.set_commits(commit_list)
        except ReleaseCommitError:
            # Another task or webworker is currently setting commits on this
            # release. Return early as that task will do the remaining work.
            logger.info(
                "fetch_commits.duplicate",
                extra={
                    "release_id": release.id,
                    "organization_id": release.organization_id,
                    "user_id": user_id,
                },
            )
            return

        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")

        # for each repo, update (or create if this is the first one) our records
        # of the latest commit-associated release in each env
        # use deploys as a proxy for ReleaseEnvironment, because they contain
        # a timestamp in addition to release and env data
        for repository_id, commit_id in repo_queryset:
            for environment_id, (deploy_id, date_finished) in six.iteritems(
                    last_deploy_per_environment):
                # we need to mark LatestRepoReleaseEnvironment, but only if there's not a
                # deploy in the given environment which has completed *after*
                # this deploy (given we might process commits out of order)
                if not Deploy.objects.filter(
                        id__in=LatestRepoReleaseEnvironment.objects.filter(
                            repository_id=repository_id,
                            environment_id=environment_id).values("deploy_id"),
                        date_finished__gt=date_finished,
                ).exists():
                    LatestRepoReleaseEnvironment.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)