def test_get_mergify_config_location_from_cache(): client = mock.Mock() client.auth.owner = "foo" client.item.side_effect = [ http.HTTPNotFound("Not Found", request=mock.Mock(), response=mock.Mock()), http.HTTPNotFound("Not Found", request=mock.Mock(), response=mock.Mock()), { "content": encodebytes("whatever".encode()).decode() }, ] filename, content = rules.get_mergify_config_content(client, "bar") assert client.item.call_count == 3 client.item.assert_has_calls([ mock.call("/repos/foo/bar/contents/.mergify.yml"), mock.call("/repos/foo/bar/contents/.mergify/config.yml"), mock.call("/repos/foo/bar/contents/.github/mergify.yml"), ]) client.item.reset_mock() client.item.side_effect = [ { "content": encodebytes("whatever".encode()).decode() }, ] filename, content = rules.get_mergify_config_content(client, "bar") assert client.item.call_count == 1 client.item.assert_has_calls([ mock.call("/repos/foo/bar/contents/.github/mergify.yml"), ])
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 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 try: installation = github.get_installation(owner, repo) except exceptions.MergifyNotInstalled: print("* Mergify is not installed there") return client = github.get_client(owner, repo, installation) print("* INSTALLATION ID: %s" % client.installation["id"]) cached_sub = sub_utils.get_subscription(redis, client.installation["id"]) db_sub = sub_utils._retrieve_subscription_from_db( client.installation["id"]) print("* SUBSCRIBED (cache/db): %s / %s" % (cached_sub["subscription_active"], db_sub["subscription_active"])) report_sub(client.installation["id"], slug, cached_sub, "ENGINE-CACHE") report_sub(client.installation["id"], slug, db_sub, "DASHBOARD") pull_raw = client.item(f"pulls/{pull_number}") ctxt = mergify_context.MergifyContext(client, pull_raw) print("* REPOSITORY IS %s" % "PRIVATE" if ctxt.pull["base"]["repo"]["private"] else "PUBLIC") print("* CONFIGURATION:") try: mergify_config_content = rules.get_mergify_config_content(ctxt) except rules.NoRules: # pragma: no cover print(".mergify.yml is missing") pull_request_rules = None 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( engine.MERGIFY_RULE["rules"]) pull_request_rules = rules.PullRequestRules( **pull_request_rules_raw) print("* PULL REQUEST:") pprint.pprint(ctxt.to_dict(), width=160) print("is_behind: %s" % ctxt.is_behind) print("mergeable_state: %s" % ctxt.pull["mergeable_state"]) print("* MERGIFY LAST CHECKS:") checks = list(check_api.get_checks(ctxt, mergify_only=True)) for c in checks: print("[%s]: %s | %s" % (c["name"], c["conclusion"], c["output"].get("title"))) print("> " + "\n> ".join(c["output"].get("summary").split("\n"))) if pull_request_rules is not None: print("* MERGIFY LIVE MATCHES:") match = pull_request_rules.get_pull_request_rule(ctxt) summary_title, summary = actions_runner.gen_summary( ctxt, [{ "event_type": "refresh", "data": {} }], match) print("> %s" % summary_title) print(summary) return ctxt
def report( url: str, ) -> typing.Union[context.Context, github.GithubInstallationClient, None]: path = url.replace("https://github.com/", "") pull_number: typing.Optional[str] repo: typing.Optional[str] try: owner, repo, _, pull_number = path.split("/") except ValueError: pull_number = None try: owner, repo = path.split("/") except ValueError: owner = path repo = None try: client = github.get_client(owner) except exceptions.MergifyNotInstalled: print(f"* Mergify is not installed on account {owner}") return None print("* INSTALLATION ID: %s" % client.auth.installation["id"]) cached_sub, db_sub = utils.async_run( subscription.Subscription.get_subscription(client.auth.owner_id), subscription.Subscription._retrieve_subscription_from_db( client.auth.owner_id), ) if repo is None: slug = None else: slug = owner + "/" + repo print("* SUBSCRIBED (cache/db): %s / %s" % (cached_sub.active, db_sub.active)) print("* Features (cache):") for f in cached_sub.features: print(f" - {f.value}") report_sub(client.auth.installation["id"], cached_sub, "ENGINE-CACHE", slug) report_sub(client.auth.installation["id"], db_sub, "DASHBOARD", slug) utils.async_run(report_worker_status(client.auth.owner)) if repo is not None: repo_info = client.item(f"/repos/{owner}/{repo}") print( f"* REPOSITORY IS {'PRIVATE' if repo_info['private'] else 'PUBLIC'}" ) print("* CONFIGURATION:") mergify_config = None try: filename, mergify_config_content = rules.get_mergify_config_content( client, repo) except rules.NoRules: # pragma: no cover print(".mergify.yml is missing") else: print(f"Config filename: {filename}") 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: mergify_config["pull_request_rules"].rules.extend( engine.DEFAULT_PULL_REQUEST_RULES.rules) if pull_number is None: for branch in client.items(f"/repos/{owner}/{repo}/branches"): q = queue.Queue( utils.get_redis_for_cache(), client.auth.installation["id"], client.auth.owner, repo, branch["name"], ) pulls = q.get_pulls() if not pulls: continue print(f"* QUEUES {branch['name']}:") for priority, grouped_pulls in itertools.groupby( pulls, key=lambda v: q.get_config(v)["priority"]): try: fancy_priority = helpers.PriorityAliases(priority).name except ValueError: fancy_priority = priority formatted_pulls = ", ".join( (f"#{p}" for p in grouped_pulls)) print(f"** {formatted_pulls} (priority: {fancy_priority})") else: pull_raw = client.item( f"/repos/{owner}/{repo}/pulls/{pull_number}") ctxt = context.Context( client, pull_raw, cached_sub, [{ "event_type": "mergify-debugger", "data": {} }], ) # FIXME queues could also be printed if no pull number given q = queue.Queue.from_context(ctxt) print("* QUEUES: %s" % ", ".join([f"#{p}" for p in q.get_pulls()])) print("* PULL REQUEST:") pr_data = dict(ctxt.pull_request.items()) pprint.pprint(pr_data, width=160) print("is_behind: %s" % ctxt.is_behind) print("mergeable_state: %s" % ctxt.pull["mergeable_state"]) print("* MERGIFY LAST CHECKS:") for c in ctxt.pull_engine_check_runs: print("[%s]: %s | %s" % (c["name"], c["conclusion"], c["output"].get("title"))) print("> " + "\n> ".join(c["output"].get("summary").split("\n"))) if mergify_config is not None: print("* MERGIFY LIVE MATCHES:") match = mergify_config[ "pull_request_rules"].get_pull_request_rule(ctxt) summary_title, summary = actions_runner.gen_summary( ctxt, match) print("> %s" % summary_title) print(summary) return ctxt return client
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): path = url.replace("https://github.com/", "") try: owner, repo, _, pull_number = path.split("/") except ValueError: print(f"Wrong URL: {url}") return slug = owner + "/" + repo try: client = github.get_client(owner, repo) except exceptions.MergifyNotInstalled: print("* Mergify is not installed there") return print("* INSTALLATION ID: %s" % client.auth.installation["id"]) cached_sub, db_sub = utils.async_run( sub_utils.get_subscription(client.auth.owner_id), sub_utils._retrieve_subscription_from_db(client.auth.owner_id), ) print("* SUBSCRIBED (cache/db): %s / %s" % (cached_sub["subscription_active"], db_sub["subscription_active"])) report_sub(client.auth.installation["id"], slug, cached_sub, "ENGINE-CACHE") report_sub(client.auth.installation["id"], slug, db_sub, "DASHBOARD") utils.async_run(report_worker_status(client.auth.owner)) pull_raw = client.item(f"pulls/{pull_number}") ctxt = context.Context(client, pull_raw, cached_sub, [{ "event_type": "mergify-debugger", "data": {} }]) q = queue.Queue.from_context(ctxt) print("QUEUES: %s" % ", ".join([f"#{p}" for p in q.get_pulls()])) print("* REPOSITORY IS %s" % "PRIVATE" if ctxt.pull["base"]["repo"]["private"] else "PUBLIC") print("* CONFIGURATION:") try: filename, mergify_config_content = rules.get_mergify_config_content( ctxt) except rules.NoRules: # pragma: no cover print(".mergify.yml is missing") pull_request_rules = None else: print(f"Config filename: {filename}") 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 = rules.PullRequestRules.from_list( pull_request_rules_raw["rules"] + engine.MERGIFY_RULE["rules"]) print("* PULL REQUEST:") pr_data = dict(ctxt.pull_request.items()) pprint.pprint(pr_data, width=160) print("is_behind: %s" % ctxt.is_behind) print("mergeable_state: %s" % ctxt.pull["mergeable_state"]) print("* MERGIFY LAST CHECKS:") for c in ctxt.pull_engine_check_runs: print("[%s]: %s | %s" % (c["name"], c["conclusion"], c["output"].get("title"))) print("> " + "\n> ".join(c["output"].get("summary").split("\n"))) if pull_request_rules is not None: print("* MERGIFY LIVE MATCHES:") match = pull_request_rules.get_pull_request_rule(ctxt) summary_title, summary = actions_runner.gen_summary(ctxt, match) print("> %s" % summary_title) print(summary) return ctxt