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