def post(self): full_name = self.request.get('repo').lower() split = full_name.split('/') if len(split) != 2: self.response.set_status(400) self.response.write('Bad request, not repo') return owner = split[0] repo = split[1] access_token = exchange_token(self) if access_token is None: return # Validate access token against repo repos_response = util.github_get('repos/%s' % full_name, access_token=access_token) if repos_response.status_code != 200: self.response.set_status(401) self.response.write('Cannot access repo') return info = json.loads(repos_response.content) has_access = info['permissions']['admin'] if not has_access: self.response.set_status(401) self.response.write('Do not have access to the repo') return parsed_url = urlparse(self.request.url) params = {'name': 'web', 'events': ['pull_request']} params['config'] = { 'url': '%s://%s/api/preview-event' % (parsed_url.scheme, parsed_url.netloc), 'content_type': 'json', } # Check if the webhook exists list_webhooks_response = util.github_post('repos', owner, repo, 'hooks', access_token=access_token) if list_webhooks_response.status_code != 200: logging.error('Unable to query existing webhooks, continuing anyway. Github %s: %s', list_webhooks_response.status_code, list_webhooks_response.content) else: webhooks = json.loads(list_webhooks_response.content) for webhook in webhooks: if webhook['active'] and webhook['config'] == params['config']: self.response.write('Webhook is already configured') return # Create the webhook create_webhook_response = util.github_post('repos', owner, repo, 'hooks', params, access_token) if create_webhook_response.status_code != 201: self.response.set_status(500) self.response.write('Failed to create webhook.') logging.error('Failed to create webhook. Github %s: %s', create_webhook_response.status_code, create_webhook_response.content) return # Trigger shallow ingestion of the library so we can store the access token. util.new_task(util.ingest_webhook_task(owner, repo), params={'access_token': access_token}, target='manage') self.response.write('Created webhook')
def post(self): if self.request.headers.get('X-Github-Event') != 'pull_request': self.response.set_status(202) # Accepted self.response.write('Payload was not for a pull_request, aborting.') return payload = json.loads(self.request.body) if payload['action'] != 'opened' and payload['action'] != 'synchronize': self.response.set_status(202) # Accepted self.response.write('Payload was not opened or synchronize, aborting.') return # Original repo origin_owner = payload['repository']['owner']['login'] origin_repo = payload['repository']['name'] origin_full_name = payload['repository']['full_name'] # Repo where the pull request came from. pull_owner = payload['pull_request']['head']['repo']['owner']['login'] pull_repo = payload['pull_request']['head']['repo']['name'] key = ndb.Key(Library, Library.id(origin_owner, origin_repo)) library = key.get(read_policy=ndb.EVENTUAL_CONSISTENCY) if library is None: logging.error('No library object found for %s', origin_full_name) self.response.set_status(400) # Bad request self.response.write('It does not seem like this repository was registered') return sha = payload['pull_request']['head']['sha'] parsed_url = urlparse(self.request.url) params = { 'state': 'success', 'target_url': '%s://%s/preview/%s/%s/%s' % (parsed_url.scheme, parsed_url.netloc, pull_owner, pull_repo, sha), 'description': 'Preview is ready!', # TODO: Don't lie 'context': 'webcomponents/preview' } response = util.github_post('repos', origin_owner, origin_repo, 'statuses/%s' % sha, params, library.github_access_token) if response.status_code != 201: logging.error('Failed to set status on Github PR. Github returned %s:%s', response.status_code, response.content) self.response.set_status(500) self.response.write('Failed to set status on PR.') return pull_request_url = payload['pull_request']['url'] util.new_task(util.ingest_preview_task(pull_owner, pull_repo), params={'commit': sha, 'url': pull_request_url}, target='manage')