From da120a1ef268325518f8b2c514c0a83fafcc9dc2 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 12 Jun 2015 16:34:13 -0400 Subject: [PATCH 1/2] Handle the case where GH auth fails on a trigger request Fixes #124 --- endpoints/trigger.py | 81 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 11 deletions(-) diff --git a/endpoints/trigger.py b/endpoints/trigger.py index f05bdb787..e87264c4b 100644 --- a/endpoints/trigger.py +++ b/endpoints/trigger.py @@ -9,7 +9,8 @@ import json import gitlab from endpoints.building import PreparedBuild -from github import Github, UnknownObjectException, GithubException +from github import (Github, UnknownObjectException, GithubException, + BadCredentialsException as GitHubBadCredentialsException) from bitbucket import BitBucket from tempfile import SpooledTemporaryFile from jsonschema import validate @@ -737,7 +738,45 @@ class GithubBuildTrigger(BuildTriggerHandler): raise RepositoryReadException(message) @staticmethod - def _build_commit_info(repo, commit_sha): + def _build_commit_info(repo, payload, commit_sha): + if repo: + return GithubBuildTrigger._build_repo_commit_info(repo, commit_sha) + else: + return GithubBuildTrigger._build_payload_commit_info(payload, commit_sha) + + @staticmethod + def _build_payload_commit_info(payload, commit_sha): + head_commit = payload.get('head_commit', {}) + sender = payload.get('sender', {}) + + commit_info = { + 'url': head_commit.get('url', ''), + 'message': head_commit.get('message', ''), + 'date': head_commit.get('timestamp', ''), + } + + if 'author' in head_commit: + commit_info['author'] = { + 'username': head_commit['author'].get('username'), + } + + if head_commit['author']['username'] == sender.get('login'): + commit_info['author']['avatar_url'] = sender.get('avatar_url', '') + commit_info['author']['url'] = sender.get('html_url', '') + + if 'committer' in head_commit: + commit_info['author'] = { + 'username': head_commit['committer'].get('username'), + } + + if head_commit['committer']['username'] == sender.get('login'): + commit_info['committer']['avatar_url'] = sender.get('avatar_url', '') + commit_info['committer']['url'] = sender.get('html_url', '') + + return commit_info + + @staticmethod + def _build_repo_commit_info(repo, commit_sha): try: commit = repo.get_commit(commit_sha) except GithubException: @@ -801,12 +840,23 @@ class GithubBuildTrigger(BuildTriggerHandler): return tarball_subdir, dockerfile_id - def _prepare_build(self, repo, ref, commit_sha, is_manual): + def _get_payload(self, payload, *args): + current = payload + for arg in args: + current = current.get(arg, {}) + + return current + + + def _prepare_build(self, ref, commit_sha, is_manual, repo=None, payload=None): config = self.config prepared = PreparedBuild(self.trigger) # If the trigger isn't using git, prepare the buildpack. if self.trigger.private_key is None: + if repo is None: + raise SkipRequestException() + tarball_subdir, dockerfile_id = GithubBuildTrigger._prepare_tarball(repo, commit_sha) prepared.subdirectory = os.path.join(tarball_subdir, config['subdir']) @@ -818,18 +868,23 @@ class GithubBuildTrigger(BuildTriggerHandler): prepared.name_from_sha(commit_sha) # Set the tag(s). - prepared.tags_from_ref(ref, repo.default_branch) + if repo: + default_branch = repo.default_branch + else: + default_branch = self._get_payload(payload, 'repository', 'default_branch') + + prepared.tags_from_ref(ref, default_branch) # Build and set the metadata. metadata = { 'commit': commit_sha, 'ref': ref, - 'default_branch': repo.default_branch, - 'git_url': repo.ssh_url, + 'default_branch': default_branch, + 'git_url': repo.ssh_url if repo else self._get_payload(payload, 'repository', 'ssh_url'), } # add the commit info. - commit_info = GithubBuildTrigger._build_commit_info(repo, commit_sha) + commit_info = GithubBuildTrigger._build_commit_info(repo, payload, commit_sha) if commit_info is not None: metadata['commit_info'] = commit_info @@ -867,10 +922,14 @@ class GithubBuildTrigger(BuildTriggerHandler): gh_client = self._get_client() repo = gh_client.get_repo(repo_full_name) + return self._prepare_build(ref, commit_sha, False, repo=repo) + except GitHubBadCredentialsException: + logger.exception('Got GitHub Credentials Exception, retrying with a manual payload') + return self._prepare_build(ref, commit_sha, False, payload=payload) + except GithubException: + logger.exception("Got GitHub Exception when trying to start trigger %s", self.trigger.id) + raise SkipRequestException() - return self._prepare_build(repo, ref, commit_sha, False) - except GithubException as ghe: - raise TriggerStartException(ghe.data['message']) def manual_start(self, run_parameters=None): config = self.config @@ -887,7 +946,7 @@ class GithubBuildTrigger(BuildTriggerHandler): commit_sha = branch.commit.sha ref = 'refs/heads/%s' % (branch_name) - return self._prepare_build(repo, ref, commit_sha, True) + return self._prepare_build(ref, commit_sha, True, repo=repo) except GithubException as ghe: raise TriggerStartException(ghe.data['message']) From 48ee4671a7ee5618f45a3f39b65b1fd978cf46ea Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Tue, 16 Jun 2015 15:46:58 -0400 Subject: [PATCH 2/2] Some additional fixes when testing this branch --- endpoints/trigger.py | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/endpoints/trigger.py b/endpoints/trigger.py index e87264c4b..db4ccd91e 100644 --- a/endpoints/trigger.py +++ b/endpoints/trigger.py @@ -765,7 +765,7 @@ class GithubBuildTrigger(BuildTriggerHandler): commit_info['author']['url'] = sender.get('html_url', '') if 'committer' in head_commit: - commit_info['author'] = { + commit_info['committer'] = { 'username': head_commit['committer'].get('username'), } @@ -960,25 +960,39 @@ class GithubBuildTrigger(BuildTriggerHandler): config = self.config if field_name == 'tag_name': - gh_client = self._get_client() - source = config['build_source'] - repo = gh_client.get_repo(source) - return [tag.name for tag in repo.get_tags()] + try: + gh_client = self._get_client() + source = config['build_source'] + repo = gh_client.get_repo(source) + return [tag.name for tag in repo.get_tags()] + except GitHubBadCredentialsException: + return [] + except GithubException: + logger.exception("Got GitHub Exception when trying to list tags for trigger %s", + self.trigger.id) + return [] if field_name == 'branch_name': - gh_client = self._get_client() - source = config['build_source'] - repo = gh_client.get_repo(source) - branches = [branch.name for branch in repo.get_branches()] + try: + gh_client = self._get_client() + source = config['build_source'] + repo = gh_client.get_repo(source) + branches = [branch.name for branch in repo.get_branches()] - if not repo.default_branch in branches: - branches.insert(0, repo.default_branch) + if not repo.default_branch in branches: + branches.insert(0, repo.default_branch) - if branches[0] != repo.default_branch: - branches.remove(repo.default_branch) - branches.insert(0, repo.default_branch) + if branches[0] != repo.default_branch: + branches.remove(repo.default_branch) + branches.insert(0, repo.default_branch) - return branches + return branches + except GitHubBadCredentialsException: + return ['master'] + except GithubException: + logger.exception("Got GitHub Exception when trying to list branches for trigger %s", + self.trigger.id) + return ['master'] return None