def test_branch_disabled(self): old_rule = { "protection": { "required_status_checks": { "strict": True, "contexts": ["continuous-integration/no-ci"], }, "required_pull_request_reviews": { "dismiss_stale_reviews": True, "require_code_owner_reviews": False, "required_approving_review_count": 1, }, "restrictions": None, "enforce_admins": False, } } branch_protection.protect(self.r_main, "disabled", old_rule) config = rules.get_mergify_config(self.r_main) rule = rules.get_branch_rule(config['rules'], "disabled") self.assertEqual(None, rule) data = branch_protection.get_protection(self.r_main, "disabled") self.assertFalse( branch_protection.is_configured(self.r_main, "disabled", rule, data)) self.create_pr("disabled") self.assertEqual([], self.processor._get_cached_branches()) self.assertEqual([], self._get_queue("disabled")) data = branch_protection.get_protection(self.r_main, "disabled") self.assertTrue( branch_protection.is_configured(self.r_main, "disabled", rule, data))
def test_basic(self): self.create_pr() p2, commits = self.create_pr() # Check we have only on branch registered self.assertEqual( "queues~%s~mergifyio-testing~%s~False~master" % (config.INSTALLATION_ID, self.name), self.processor._get_cache_key("master")) self.assertEqual(["master"], self.processor._get_cached_branches()) # Check policy of that branch is the expected one expected_rule = { "protection": { "required_status_checks": { "strict": True, "contexts": ["continuous-integration/fake-ci"], }, "required_pull_request_reviews": { "dismiss_stale_reviews": True, "require_code_owner_reviews": False, "required_approving_review_count": 1, }, "restrictions": None, "enforce_admins": False, } } data = branch_protection.get_protection(self.r_main, "master") self.assertTrue( branch_protection.is_configured(self.r_main, "master", expected_rule, data)) # Checks the content of the cache pulls = self._get_queue("master") self.assertEqual(2, len(pulls)) for p in pulls: self.assertEqual(0, p.mergify_state) self.create_status_and_push_event(p2, context="not required status check", state="error") self.create_status_and_push_event(p2) self.create_review_and_push_event(p2, commits[0]) pulls = self._get_queue("master") self.assertEqual(2, len(pulls)) self.assertEqual(2, pulls[0].g_pull.number) self.assertEqual(30, pulls[0].mergify_state) self.assertEqual("Will be merged soon", pulls[0].github_description) self.assertEqual(1, pulls[1].g_pull.number) self.assertEqual(0, pulls[1].mergify_state) self.assertEqual("0/1 approvals required", pulls[1].github_description) # Check the merged pull request is gone self.push_events(MERGE_EVENTS) pulls = self._get_queue("master") self.assertEqual(1, len(pulls))
def test_change_mergify_yml(self): config = yaml.load(CONFIG) config["rules"]["branches"]["master"]["protection"][ "required_pull_request_reviews"][ "required_approving_review_count"] = 6 config = yaml.dump(config) p1, commits1 = self.create_pr(files={".mergify.yml": config}, state="failure") pulls = self._get_queue("master") self.assertEqual(1, len(pulls)) self.assertEqual(1, pulls[0]._reviews_required) # Check policy of that branch is the expected one expected_rule = { "protection": { "required_status_checks": { "strict": True, "contexts": ["continuous-integration/fake-ci"], }, "required_pull_request_reviews": { "dismiss_stale_reviews": True, "require_code_owner_reviews": False, "required_approving_review_count": 1, }, "restrictions": None, "enforce_admins": False, } } data = branch_protection.get_protection(self.r_main, "master") self.assertTrue( branch_protection.is_configured(self.r_main, "master", expected_rule, data)) p1 = self.r_main.get_pull(p1.number) commit = p1.base.repo.get_commit(p1.head.sha) ctxts = [ s.raw_data["context"] for s in reversed(list(commit.get_statuses())) ] self.assertIn("mergify/future-config-checker", ctxts)
def test_missing_required_status_check(self): self.create_pr("stable") # Check policy of that branch is the expected one expected_rule = { "protection": { "required_status_checks": None, "required_pull_request_reviews": { "dismiss_stale_reviews": True, "require_code_owner_reviews": False, "required_approving_review_count": 1, }, "restrictions": None, "enforce_admins": False, } } data = branch_protection.get_protection(self.r_main, "stable") self.assertTrue(branch_protection.is_configured(self.r_main, "stable", expected_rule, data))
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, base_url="https://api.%s" % config.GITHUB_DOMAIN) r = g.get_repo(owner + "/" + repo) p = r.get_pull(int(pull_number)) print("* INSTALLATION ID: %s" % install_id) print("* CONFIGURATION:") print(r.get_contents(".mergify.yml").decoded_content.decode()) print("* BRANCH PROTECTION:") pprint.pprint(branch_protection.get_protection(r, p.base.ref), width=160) mp = mergify_pull.MergifyPull(g, p, install_id) print("* PULL REQUEST:") pprint.pprint(mp.to_dict(), width=160) print("is_behind: %s" % mp.is_behind()) 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.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 test_change_mergify_yml(self): config = yaml.load(CONFIG) config["rules"]["branches"]["master"]["protection"][ "required_pull_request_reviews"][ "required_approving_review_count"] = 6 config = yaml.dump(config) p1, commits1 = self.create_pr(files={".mergify.yml": config}, status="failure") pulls = self._get_queue("master") self.assertEqual(1, len(pulls)) self.assertEqual(1, pulls[0]._reviews_required) # Check policy of that branch is the expected one expected_rule = { "protection": { "required_status_checks": { "strict": True, "contexts": ["continuous-integration/fake-ci"], }, "required_pull_request_reviews": { "dismiss_stale_reviews": True, "require_code_owner_reviews": False, "required_approving_review_count": 1, }, "restrictions": None, "enforce_admins": False, } } data = branch_protection.get_protection(self.r_main, "master") self.assertTrue(branch_protection.is_configured(self.r_main, "master", expected_rule, data)) p1 = self.r_main.get_pull(p1.number) checks = list(check_api.get_checks(p1, { "check_name": "future-config-checker"})) assert len(checks) == 1 assert checks[0].name == "future-config-checker"
def test_checks(self): self.create_pr() p2, commits = self.create_pr() # Check we have only on branch registered self.assertEqual("queues~%s~mergify-test1~%s~False~master" % (config.INSTALLATION_ID, self.name), self.processor._get_cache_key("master")) self.assertEqual(["master"], self.processor._get_cached_branches()) # Check policy of that branch is the expected one expected_rule = { "protection": { "required_status_checks": { "strict": True, "contexts": ["continuous-integration/fake-ci"], }, "required_pull_request_reviews": { "dismiss_stale_reviews": True, "require_code_owner_reviews": False, "required_approving_review_count": 1, }, "restrictions": None, "enforce_admins": False, } } data = branch_protection.get_protection(self.r_main, "master") self.assertTrue(branch_protection.is_configured( self.r_main, "master", expected_rule, data)) # Checks the content of the cache pulls = self._get_queue("master") self.assertEqual(2, len(pulls)) for p in pulls: self.assertEqual(0, p.mergify_state) self.create_check_run_and_push_event(p2, "The always broken check", conclusion="failure") # FIXME(sileht): Github looks buggy, if the conclusion of a checksuite # doesn't change, no event are sent. I was expecting Github to send a # new checksuite showing that now we have pending runs. self.create_check_run_and_push_event(p2, 'continuous-integration/fake-ci', conclusion=None, ignore_check_suite_event=True) # FIXME(sileht): Github looks buggy, I just update the previous # check-run, and I don't get any check-run/check-suite events. # That's problematique, because Mergify is not triggered here. self.create_check_run_and_push_event(p2, 'continuous-integration/fake-ci', conclusion="success", ignore_check_run_event=True, ignore_check_suite_event=True) # NOTE(sileht): I create a another check that will trigger Mergify # because of the previous bug... self.create_check_run_and_push_event(p2, 'Another check', conclusion="success", ignore_check_suite_event=True) self.create_review_and_push_event(p2, commits[0]) pulls = self._get_queue("master") self.assertEqual(2, len(pulls)) self.assertEqual(2, pulls[0].g_pull.number) self.assertEqual(30, pulls[0].mergify_state) self.assertEqual("Will be merged soon", pulls[0].github_description) self.assertEqual(1, pulls[1].g_pull.number) self.assertEqual(0, pulls[1].mergify_state) self.assertEqual("0/1 approvals required", pulls[1].github_description) # Check the merged pull request is gone self.push_events(MERGE_EVENTS) pulls = self._get_queue("master") self.assertEqual(1, len(pulls))