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)
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)
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)
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)
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)
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)
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)
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)))
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, })
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, })
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)
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)
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)
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)
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)
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)
def get_provider(self): from sentry.plugins import bindings provider_cls = bindings.get('repository.provider').get(self.provider) return provider_cls(self.provider)
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)
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)