import json import github3 import logging import subprocess import sys import traceback import requests import time def github_set_ref(repo, ref, sha, *, force=False, auto_create=True): url = repo._build_url('git', 'refs', ref, base_url=repo._api) data = {'sha': sha, 'force': force} try: js = repo._json(repo._patch(url, data=json.dumps(data)), 200) except github3.models.GitHubError as e: if e.code == 422 and auto_create: try: return repo.create_ref('refs/' + ref, sha) except github3.models.GitHubError: raise e else: raise return github3.git.Reference(js, repo) if js else None class Status(github3.repos.status.Status): def __init__(self, info): super(Status, self).__init__(info) self.context = info.get('context') def github_iter_statuses(repo, sha): url = repo._build_url('statuses', sha, base_url=repo._api) return repo._iter(-1, url, Status) def github_create_status(repo, sha, state, target_url='', description='', *, context=''): data = {'state': state, 'target_url': target_url, 'description': description, 'context': context} url = repo._build_url('statuses', sha, base_url=repo._api) js = repo._json(repo._post(url, data=data), 201) return Status(js) if js else None def remove_url_keys_from_json(json): if isinstance(json, dict): return {key: remove_url_keys_from_json(value) for key, value in json.items() if not key.endswith('url')} elif isinstance(json, list): return [remove_url_keys_from_json(value) for value in json] else: return json def lazy_debug(logger, f): if logger.isEnabledFor(logging.DEBUG): logger.debug(f()) def logged_call(args): try: subprocess.check_call(args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except subprocess.CalledProcessError as e: print('* Failed to execute command: {}'.format(args)) raise def silent_call(args): return subprocess.call(args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def retry_until(inner, fail, state): err = None exc_info = None for i in range(3, 0, -1): try: inner() except (github3.models.GitHubError, requests.exceptions.RequestException) as e: print('* Intermittent GitHub error: {}'.format(e), file=sys.stderr) err = e exc_info = sys.exc_info() if i != 1: time.sleep(1) else: err = None break if err: print('* GitHub failure in {}'.format(state), file=sys.stderr) traceback.print_exception(*exc_info) fail(err)