def refresh(owner, repo, refresh_ref): authentification() integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) installation_id = utils.get_installation_id(integration, owner) if not installation_id: # pragma: no cover flask.abort(400, "%s have not installed mergify_engine" % owner) token = integration.get_access_token(installation_id).token g = github.Github(token) r = g.get_repo("%s/%s" % (owner, repo)) try: r.get_contents(".mergify.yml") except github.GithubException as e: # pragma: no cover if e.status == 404: return "No .mergify.yml", 202 else: raise if refresh_ref == "full" or refresh_ref.startswith("branch/"): if refresh_ref.startswith("branch/"): branch = refresh_ref[7:] pulls = r.get_pulls(base=branch) else: branch = '*' pulls = r.get_pulls() key = "queues~%s~%s~%s~%s~%s" % (installation_id, owner.lower(), repo.lower(), r.private, branch) utils.get_redis_for_cache().delete(key) else: try: pull_number = int(refresh_ref[5:]) except ValueError: # pragma: no cover return "Invalid PR ref", 400 pulls = [r.get_pull(pull_number)] subscription = utils.get_subscription(utils.get_redis_for_cache(), installation_id) if not subscription["token"]: # pragma: no cover return "", 202 if r.private and not subscription["subscribed"]: # pragma: no cover return "", 202 for p in pulls: # Mimic the github event format data = { 'repository': r.raw_data, 'installation': { 'id': installation_id }, 'pull_request': p.raw_data, } get_queue(r.full_name, subscription).enqueue(worker.event_handler, "refresh", subscription, data) return "", 202
def report(url): path = url.replace("https://github.com/", "") owner, repo, _, pull_number = path.split("/") integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) install_id = utils.get_installation_id(integration, owner) installation_token = integration.get_access_token(install_id).token g = github.Github(installation_token) r = g.get_repo(owner + "/" + repo) p = r.get_pull(int(pull_number)) print("* CONFIGURATION:") print(r.get_contents(".mergify.yml").decoded_content.decode()) mp = mergify_pull.MergifyPull(p, installation_token) print("* PULL REQUEST:") pprint.pprint(mp.to_dict(), width=160) print("is_behind: %s" % mp.is_behind()) print("* MERGIFY STATUSES:") commit = p.base.repo.get_commit(p.head.sha) for s in commit.get_combined_status().statuses: if s.context.startswith("mergify"): print("[%s]: %s" % (s.context, s.state)) print("* MERGIFY CHECKS:") checks = list(check_api.get_checks(p)) for c in checks: if c.name.startswith("Mergify"): print("[%s]: %s | %s" % (c.name, c.conclusion, c.output.get("title"))) print("> " + "\n> ".join(c.output.get("summary").split("\n"))) return g, p
def job_marketplace(event_type, event_id, data): owner = data["marketplace_purchase"]["account"]["login"] account_type = data["marketplace_purchase"]["account"]["type"] integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) try: installation_id = utils.get_installation_id( integration, owner, account_type=account_type ) except github.GithubException as e: LOG.warning("%s: mergify not installed", owner, error=str(e)) installation_id = None subscription = { "subscription_active": "Unknown", "subscription_reason": "No", "tokens": None, } else: r = utils.get_redis_for_cache() r.delete("subscription-cache-%s" % installation_id) subscription = sub_utils.get_subscription(r, installation_id) LOG.info( "Marketplace event", event_type=event_type, event_id=event_id, install_id=installation_id, sender=data["sender"]["login"], subscription_active=subscription["subscription_active"], subscription_reason=subscription["subscription_reason"], )
def status_repo(login, repo="*"): r = utils.get_redis_for_cache() integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) installation_id = utils.get_installation_id(integration, login) return (_get_status(r, installation_id, login, repo), 200, {'Content-Type': 'application/json'})
def test(): import github from mergify_engine import gh_pr from mergify_engine import utils utils.setup_logging() config.log() gh_pr.monkeypatch_github() parts = sys.argv[1].split("/") LOG.info("Getting repo %s ..." % sys.argv[1]) integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) installation_id = utils.get_installation_id(integration, parts[3]) token = integration.get_access_token(installation_id).token g = github.Github(token) user = g.get_user(parts[3]) repo = user.get_repo(parts[4]) LOG.info("Protecting repo %s branch %s ..." % (sys.argv[1], sys.argv[2])) rule = rules.get_branch_rule(repo, sys.argv[2]) configure_protection_if_needed(repo, sys.argv[2], rule)
def test(): from mergify_engine import gh_pr from mergify_engine import utils utils.setup_logging() config.log() gh_pr.monkeypatch_github() parts = sys.argv[1].split("/") LOG.info("Getting repo %s ..." % sys.argv[1]) if True: # With access_token got from oauth token = sys.argv[2] g = github.Github(token) user = g.get_user(parts[3]) repo = user.get_repo(parts[4]) pull = repo.get_pull(int(parts[6])) update_branch(pull, token) else: # With access_token got from integration integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) installation_id = utils.get_installation_id(integration, parts[3]) token = integration.get_access_token(installation_id).token update_branch(pull, "x-access-token:%s" % token)
def refresh(owner, repo, refresh_ref): authentification() installation_id = utils.get_installation_id(INTEGRATION, owner) if not installation_id: flask.abort(400, "%s have not installed mergify_engine" % owner) token = INTEGRATION.get_access_token(installation_id).token g = github.Github(token) r = g.get_repo("%s/%s" % (owner, repo)) if refresh_ref == "full" or refresh_ref.startswith("branch/"): if refresh_ref.startswith("branch/"): branch = refresh_ref[7:] pulls = r.get_pulls(base=branch) else: branch = '*' pulls = r.get_pulls() key = "queues~%s~%s~%s~%s" % (installation_id, owner, repo, branch) utils.get_redis().delete(key) else: pulls = [r.get_pull(int(refresh_ref[5:]))] for p in pulls: # Mimic the github event format data = { 'repository': r.raw_data, 'installation': {'id': installation_id}, 'pull_request': p.raw_data, } get_queue().enqueue(worker.event_handler, "refresh", data) return "", 202
def stream_repo(login, repo="*"): integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) installation_id = utils.get_installation_id(integration, login) return flask.Response(flask.stream_with_context( stream_generate(installation_id, login, repo) ), mimetype="text/event-stream")
def job_refresh(owner, repo, refresh_ref): LOG.info("%s/%s/%s: refreshing", owner, repo, refresh_ref) integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) try: installation_id = utils.get_installation_id(integration, owner, repo) except github.GithubException as e: LOG.warning("%s/%s/%s: mergify not installed", owner, repo, refresh_ref, error=str(e)) return token = integration.get_access_token(installation_id).token g = github.Github(token, base_url="https://api.%s" % config.GITHUB_DOMAIN) r = g.get_repo("%s/%s" % (owner, repo)) if refresh_ref == "full" or refresh_ref.startswith("branch/"): if refresh_ref.startswith("branch/"): branch = refresh_ref[7:] pulls = r.get_pulls(base=branch) else: branch = '*' pulls = r.get_pulls() key = "queues~%s~%s~%s~%s~%s" % (installation_id, owner.lower(), repo.lower(), r.private, branch) utils.get_redis_for_cache().delete(key) else: try: pull_number = int(refresh_ref[5:]) except ValueError: # pragma: no cover LOG.info("%s/%s/%s: Invalid PR ref", owner, repo, refresh_ref) return pulls = [r.get_pull(pull_number)] subscription = sub_utils.get_subscription(utils.get_redis_for_cache(), installation_id) if r.archived: # pragma: no cover LOG.warning("%s/%s/%s: repository archived", owner, repo, refresh_ref) return if not subscription["tokens"]: # pragma: no cover LOG.warning("%s/%s/%s: installation without token", owner, repo, refresh_ref) return for p in pulls: # Mimic the github event format data = { 'repository': r.raw_data, 'installation': {'id': installation_id}, 'pull_request': p.raw_data, } engine.run.s('refresh', data).apply_async()
def job_refresh(owner, repo, kind, ref=None): LOG.info("job refresh", kind=kind, ref=ref, gh_owner=owner, gh_repo=repo) integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) try: installation_id = utils.get_installation_id(integration, owner, repo) except github.GithubException as e: LOG.warning( "mergify not installed", kind=kind, ref=ref, gh_owner=owner, gh_repo=repo, error=str(e), ) return token = integration.get_access_token(installation_id).token g = github.Github(token, base_url="https://api.%s" % config.GITHUB_DOMAIN) r = g.get_repo("%s/%s" % (owner, repo)) if kind == "repo": pulls = r.get_pulls() elif kind == "branch": pulls = r.get_pulls(base=ref) elif kind == "pull": pulls = [r.get_pull(ref)] else: raise RuntimeError("Invalid kind") for p in pulls: # Mimic the github event format data = { "repository": r.raw_data, "installation": { "id": installation_id }, "pull_request": p.raw_data, "sender": { "login": "******" }, } github_events.job_filter_and_dispatch.s("refresh", str(uuid.uuid4()), data).apply_async()
def PullRequestUrl(v): _, owner, repo, _, pull_number = urlsplit(v).path.split("/") pull_number = int(pull_number) integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) try: installation_id = utils.get_installation_id(integration, owner, repo) except github.GithubException: raise PullRequestUrlInvalid( message="Mergify not installed on repository '%s'" % owner) token = integration.get_access_token(installation_id).token try: return mergify_pull.MergifyPull.from_number(installation_id, token, owner, repo, pull_number) except github.UnknownObjectException: raise PullRequestUrlInvalid(message=("Pull request '%s' not found" % v))
def job_marketplace(event_type, event_id, data): owner = data["marketplace_purchase"]["account"]["login"] integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) installation_id = utils.get_installation_id(integration, owner) r = utils.get_redis_for_cache() r.delete("subscription-cache-%s" % installation_id) subscription = sub_utils.get_subscription( utils.get_redis_for_cache(), installation_id) LOG.info('Marketplace event', event_type=event_type, event_id=event_id, install_id=installation_id, sender=data["sender"]["login"], subscription_active=subscription["subscription_active"], subscription_reason=subscription["subscription_reason"])
def report(url): redis = utils.get_redis_for_cache() path = url.replace("https://github.com/", "") try: owner, repo, _, pull_number = path.split("/") except ValueError: print(f"Wrong URL: {url}") return slug = owner + "/" + repo integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) install_id = utils.get_installation_id(integration, owner, repo=repo) print("* INSTALLATION ID: %s" % install_id) cached_sub = sub_utils.get_subscription(redis, install_id) db_sub = sub_utils._retrieve_subscription_from_db(install_id) print("* SUBSCRIBED (cache/db): %s / %s" % (cached_sub["subscription_active"], db_sub["subscription_active"])) report_sub(install_id, slug, cached_sub, "ENGINE-CACHE") report_sub(install_id, slug, db_sub, "DASHBOARD") installation_token = integration.get_access_token(install_id).token g = github.Github(installation_token, base_url="https://api.%s" % config.GITHUB_DOMAIN) r = g.get_repo(owner + "/" + repo) print("* REPOSITORY IS %s" % "PRIVATE" if r.private else "PUBLIC") print("* CONFIGURATION:") try: mergify_config_content = rules.get_mergify_config_content(r) except rules.NoRules: # pragma: no cover print(".mergify.yml is missing") else: print(mergify_config_content.decode()) try: mergify_config = rules.UserConfigurationSchema(mergify_config_content) except rules.InvalidRules as e: # pragma: no cover print("configuration is invalid %s" % str(e)) else: pull_request_rules_raw = mergify_config["pull_request_rules"].as_dict() pull_request_rules_raw["rules"].extend( actions_runner.MERGIFY_RULE["rules"]) pull_request_rules = rules.PullRequestRules(**pull_request_rules_raw) try: p = r.get_pull(int(pull_number)) except github.UnknownObjectException: print("Wrong pull request number") return g, None mp = mergify_pull.MergifyPull(g, p, install_id) print("* PULL REQUEST:") pprint.pprint(mp.to_dict(), width=160) try: print("is_behind: %s" % mp.is_behind()) except github.GithubException as e: print("Unable to know if pull request branch is behind: %s" % e) print("mergeable_state: %s" % mp.g_pull.mergeable_state) print("* MERGIFY LAST CHECKS:") checks = list(check_api.get_checks(p)) for c in checks: if c._rawData["app"]["id"] == config.INTEGRATION_ID: print("[%s]: %s | %s" % (c.name, c.conclusion, c.output.get("title"))) print("> " + "\n> ".join(c.output.get("summary").split("\n"))) print("* MERGIFY LIVE MATCHES:") match = pull_request_rules.get_pull_request_rule(mp) summary_title, summary = actions_runner.gen_summary( "refresh", {}, mp, match) print("> %s" % summary_title) print(summary) return g, p
def job_refresh(owner, repo, refresh_ref): LOG.info("%s/%s/%s: refreshing" % (owner, repo, refresh_ref)) integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) installation_id = utils.get_installation_id(integration, owner) if not installation_id: # pragma: no cover LOG.warning("%s/%s/%s: mergify not installed" % (owner, repo, refresh_ref)) return token = integration.get_access_token(installation_id).token g = github.Github(token) r = g.get_repo("%s/%s" % (owner, repo)) try: r.get_contents(".mergify.yml") except github.GithubException as e: # pragma: no cover if e.status == 404: LOG.warning("%s/%s/%s: mergify not configured" % (owner, repo, refresh_ref)) return else: raise if refresh_ref == "full" or refresh_ref.startswith("branch/"): if refresh_ref.startswith("branch/"): branch = refresh_ref[7:] pulls = r.get_pulls(base=branch) else: branch = '*' pulls = r.get_pulls() key = "queues~%s~%s~%s~%s~%s" % (installation_id, owner.lower(), repo.lower(), r.private, branch) utils.get_redis_for_cache().delete(key) else: try: pull_number = int(refresh_ref[5:]) except ValueError: # pragma: no cover LOG.info("%s/%s/%s: Invalid PR ref" % (owner, repo, refresh_ref)) return pulls = [r.get_pull(pull_number)] subscription = utils.get_subscription(utils.get_redis_for_cache(), installation_id) if r.archived: # pragma: no cover LOG.warning("%s/%s/%s: repository archived" % (owner, repo, refresh_ref)) return if not subscription["token"]: # pragma: no cover LOG.warning("%s/%s/%s: not public or subscribed" % (owner, repo, refresh_ref)) return if r.private and not subscription["subscribed"]: # pragma: no cover LOG.warning("%s/%s/%s: mergify not installed" % (owner, repo, refresh_ref)) return for p in pulls: # Mimic the github event format data = { 'repository': r.raw_data, 'installation': { 'id': installation_id }, 'pull_request': p.raw_data, } queue.route(r.full_name, subscription, "events", "refresh", subscription, data)
def status_repo(login, repo="*"): r = get_redis() installation_id = utils.get_installation_id(INTEGRATION, login) return _get_status(r, installation_id, login, repo)
def github_for(repo): integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) install_id = utils.get_installation_id(integration, repo.split("/")[0]) installation_token = integration.get_access_token(install_id).token return github.Github(installation_token)
def report(url): redis = utils.get_redis_for_cache() path = url.replace("https://github.com/", "") owner, repo, _, pull_number = path.split("/") integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) install_id = utils.get_installation_id(integration, owner, repo=repo) print("* INSTALLATION ID: %s" % install_id) cached_sub = sub_utils.get_subscription(redis, install_id) db_sub = sub_utils._retrieve_subscription_from_db(install_id) print("* SUBSCRIBED (cache/db): %s / %s" % (cached_sub["subscription_active"], db_sub["subscription_active"])) print("* SUB DETAIL: %s" % db_sub["subscription_reason"]) print("* NUMBER OF CACHED TOKENS: %d" % len(cached_sub["tokens"])) try: for login, token in cached_sub["tokens"].items(): try: repos = get_repositories_setuped(token, install_id) except github.BadCredentialsException: print("** token for %s invalid" % login) except github.GithubException as e: if e.status != 401: raise print("** token for %s invalid" % login) else: if any((r["full_name"] == owner + "/" + repo) for r in repos): print("* MERGIFY INSTALLED AND ENABLED ON THIS REPOSITORY") else: print("* MERGIFY INSTALLED BUT DISABLED " "ON THIS REPOSITORY") break else: print("* MERGIFY DOESN'T HAVE ANY VALID OAUTH TOKENS") except github.UnknownObjectException: print("* MERGIFY SEEMS NOT INSTALLED") installation_token = integration.get_access_token(install_id).token g = github.Github(installation_token, base_url="https://api.%s" % config.GITHUB_DOMAIN) r = g.get_repo(owner + "/" + repo) print("* REPOSITORY IS %s" % "PRIVATE" if r.private else "PUBLIC") print("* CONFIGURATION:") try: mergify_config_content = rules.get_mergify_config_content(r) except rules.NoRules: # pragma: no cover print(".mergify.yml is missing") print(mergify_config_content.decode()) try: mergify_config = rules.UserConfigurationSchema(mergify_config_content) except rules.InvalidRules as e: # pragma: no cover print("configuration is invalid %s" % str(e)) else: pull_request_rules_raw = mergify_config["pull_request_rules"].as_dict() pull_request_rules_raw["rules"].extend( actions_runner.MERGIFY_RULE["rules"]) pull_request_rules = rules.PullRequestRules(**pull_request_rules_raw) try: p = r.get_pull(int(pull_number)) except github.UnknownObjectException: print("Wrong pull request number") return g, None mp = mergify_pull.MergifyPull(g, p, install_id) print("* PULL REQUEST:") pprint.pprint(mp.to_dict(), width=160) try: print("is_behind: %s" % mp.is_behind()) except github.GithubException as e: print("Unable to know if pull request branch is behind: %s" % e) print("mergeable_state: %s" % mp.g_pull.mergeable_state) print("* MERGIFY LAST CHECKS:") checks = list(check_api.get_checks(p)) for c in checks: if c._rawData["app"]["id"] == config.INTEGRATION_ID: print("[%s]: %s | %s" % (c.name, c.conclusion, c.output.get("title"))) print("> " + "\n> ".join(c.output.get("summary").split("\n"))) print("* MERGIFY LIVE MATCHES:") match = pull_request_rules.get_pull_request_rule(mp) summary_title, summary = actions_runner.gen_summary( "refresh", {}, mp, match) print("> %s" % summary_title) print(summary) return g, p
def report(url): redis = utils.get_redis_for_cache() path = url.replace("https://github.com/", "") owner, repo, _, pull_number = path.split("/") integration = github.GithubIntegration(config.INTEGRATION_ID, config.PRIVATE_KEY) install_id = utils.get_installation_id(integration, owner) print("* INSTALLATION ID: %s" % install_id) cached_sub = sub_utils.get_subscription(redis, install_id) db_sub = sub_utils._retrieve_subscription_from_db(install_id) print("* SUBSCRIBED (cache/db): %s / %s" % (cached_sub["subscription_active"], db_sub["subscription_active"])) print("* SUB DETAIL: %s" % db_sub["subscription_reason"]) print("* NUMBER OF CACHED TOKENS: %d" % len(cached_sub["tokens"])) try: for login, token in cached_sub["tokens"].items(): try: repos = get_repositories_setuped(token, install_id) except github.BadCredentialsException: print("** token for %s invalid" % login) except github.GithubException as e: if e.status != 401: raise print("** token for %s invalid" % login) else: if any((r["full_name"] == owner + "/" + repo) for r in repos): print("* MERGIFY INSTALLED AND ENABLED ON THIS REPOSITORY") else: print("* MERGIFY INSTALLED BUT DISABLED " "ON THIS REPOSITORY") break else: print("* MERGIFY DOESN'T HAVE ANY VALID OAUTH TOKENS") except github.UnknownObjectException: print("* MERGIFY SEEMS NOT INSTALLED") installation_token = integration.get_access_token(install_id).token g = github.Github(installation_token, base_url="https://api.%s" % config.GITHUB_DOMAIN) r = g.get_repo(owner + "/" + repo) print("* REPOSITORY IS %s" % "PRIVATE" if r.private else "PUBLIC") p = r.get_pull(int(pull_number)) print("* CONFIGURATION:") print(r.get_contents(".mergify.yml").decoded_content.decode()) mp = mergify_pull.MergifyPull(g, p, install_id) print("* PULL REQUEST:") pprint.pprint(mp.to_dict(), width=160) try: print("is_behind: %s" % mp.is_behind()) except github.GithubException as e: print("Unable to know if pull request branch is behind: %s" % e) print("mergeable_state: %s" % mp.g_pull.mergeable_state) print("* MERGIFY STATUSES:") commit = p.base.repo.get_commit(p.head.sha) for s in commit.get_combined_status().statuses: if s.context.startswith("mergify"): print("[%s]: %s" % (s.context, s.state)) print("* MERGIFY CHECKS:") checks = list(check_api.get_checks(p)) for c in checks: if c._rawData['app']['id'] == config.INTEGRATION_ID: print("[%s]: %s | %s" % (c.name, c.conclusion, c.output.get("title"))) print("> " + "\n> ".join(c.output.get("summary").split("\n"))) return g, p
def stream_repo(login, repo="*"): installation_id = utils.get_installation_id(INTEGRATION, login) return flask.Response(flask.stream_with_context( stream_generate(installation_id, login, repo) ), mimetype="text/event-stream")