def _sync_with_base_branch(self, ctxt): # If PR from a public fork but cannot be edited if (ctxt.pull_from_fork and not ctxt.pull["base"]["repo"]["private"] and not ctxt.pull["maintainer_can_modify"]): return ( "failure", "Pull request can't be updated with latest base branch changes", "Mergify needs the permission to update the base branch of the pull request.\n" f"{ctxt.pull['base']['repo']['owner']['login']} needs to " "[authorize modification on its base branch]" "(https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/).", ) # If PR from a private fork but cannot be edited: # NOTE(jd): GitHub removed the ability to configure `maintainer_can_modify` on private fork we which make strict mode broken elif (ctxt.pull_from_fork and ctxt.pull["base"]["repo"]["private"] and not ctxt.pull["maintainer_can_modify"]): return ( "failure", "Pull request can't be updated with latest base branch changes", "Mergify needs the permission to update the base branch of the pull request.\n" "GitHub does not allow a GitHub App to modify base branch for a private fork.\n" "You cannot use strict mode with a pull request from a private fork.", ) elif self.config["strict"] in ("smart+fasttrack", "smart+ordered"): return helpers.get_strict_status(ctxt, need_update=ctxt.is_behind) else: return helpers.update_pull_base_branch( ctxt, self.config["strict_method"], self.config["bot_account"], )
def _handle_first_pull_in_queue(queue, pull): _, installation_id, owner, reponame, branch = queue.split("~") old_checks = [c for c in check_api.get_checks(pull.g_pull) if (c.name.endswith(" (merge)") and c._rawData['app']['id'] == config.INTEGRATION_ID)] merge_output = helpers.merge_report(pull) mergeable_state_output = helpers.output_for_mergeable_state(pull, True) if merge_output or mergeable_state_output: remove_pull(pull) conclusion, title, summary = merge_output or mergeable_state_output else: LOG.debug("updating base branch of pull request", pull=pull) redis = utils.get_redis_for_cache() method = redis.get(_get_update_method_cache_key(pull)) or "merge" conclusion, title, summary = helpers.update_pull_base_branch( pull, installation_id, method) if pull.g_pull.state == "closed": remove_pull(pull) elif conclusion == "failure": _move_pull_at_end(pull) status = "completed" if conclusion else "in_progress" for c in old_checks: check_api.set_check_run( pull.g_pull, c.name, status, conclusion, output={"title": title, "summary": summary})
def _handle_first_pull_in_queue(queue, pull): _, installation_id, owner, reponame, branch = queue.split("~") old_checks = [ c for c in check_api.get_checks(pull.g_pull, mergify_only=True) if c.name.endswith(" (merge)") ] output = helpers.merge_report(pull, True) if output: conclusion, title, summary = output LOG.debug( "pull request closed in the meantime", pull=pull, conclusion=conclusion, title=title, summary=summary, ) remove_pull(pull) else: LOG.debug("updating base branch of pull request", pull=pull) redis = utils.get_redis_for_cache() method = redis.get(_get_update_method_cache_key(pull)) or "merge" conclusion, title, summary = helpers.update_pull_base_branch( pull, installation_id, method) if pull.g_pull.state == "closed": LOG.debug( "pull request closed in the meantime", pull=pull, conclusion=conclusion, title=title, summary=summary, ) remove_pull(pull) elif conclusion == "failure": LOG.debug("base branch update failed", pull=pull, title=title, summary=summary) _move_pull_at_end(pull) status = "completed" if conclusion else "in_progress" for c in old_checks: check_api.set_check_run( pull.g_pull, c.name, status, conclusion, output={ "title": title, "summary": summary }, )
def handle_first_pull_in_queue(self, ctxt): old_checks = [ c for c in ctxt.pull_engine_check_runs if c["name"].endswith(" (merge)") ] output = helpers.merge_report(ctxt, True) if output: conclusion, title, summary = output ctxt.log.info( "pull request closed in the meantime", conclusion=conclusion, title=title, summary=summary, ) self.remove_pull(ctxt.pull["number"]) else: ctxt.log.info("updating base branch of pull request") config = self.get_config(ctxt.pull["number"]) conclusion, title, summary = helpers.update_pull_base_branch( ctxt, config["strict_method"], config["bot_account"], ) if ctxt.pull["state"] == "closed": ctxt.log.info( "pull request closed in the meantime", conclusion=conclusion, title=title, summary=summary, ) self.remove_pull(ctxt.pull["number"]) elif conclusion == "failure": ctxt.log.info("base branch update failed", title=title, summary=summary) self._move_pull_at_end(ctxt.pull["number"]) status = "completed" if conclusion else "in_progress" for c in old_checks: check_api.set_check_run( ctxt, c["name"], status, conclusion, output={ "title": title, "summary": summary }, )
def run(self, installation_id, installation_token, event_type, data, pull, missing_conditions): LOG.debug("process merge", config=self.config, pull=pull) output = helpers.merge_report(pull) if output: return output output = helpers.output_for_mergeable_state(pull, self.config["strict"]) if output: return output if self.config["strict"] and pull.is_behind(): # NOTE(sileht): Almost ready, one last rebase/update if not pull.base_is_modifiable(): return ("failure", "Pull request can't be updated with latest " "base branch changes, owner doesn't allow " "modification", "") elif self.config["strict"] == "smart": queue.add_pull(pull, self.config["strict_method"]) return (None, "Base branch will be updated soon", "The pull request base branch will " "be updated soon, and then merged.") else: return helpers.update_pull_base_branch( pull, installation_id, self.config["strict_method"]) else: # NOTE(sileht): Ready to merge! if self.config["strict"] == "smart": queue.remove_pull(pull) if (self.config["method"] != "rebase" or pull.g_pull.raw_data['rebaseable']): return self._merge(pull, self.config["method"]) elif self.config["rebase_fallback"]: return self._merge(pull, self.config["rebase_fallback"]) else: return ("action_required", "Automatic rebasing is not " "possible, manual intervention required", "")
def _sync_with_base_branch(self, pull): if not pull.base_is_modifiable: return ( "failure", "Pull request can't be updated with latest " "base branch changes, owner doesn't allow " "modification", "", ) elif self.config["strict"] == "smart": queue.add_pull(pull, self.config["strict_method"]) return ( None, "Base branch will be updated soon", "The pull request base branch will " "be updated soon, and then merged.", ) else: return helpers.update_pull_base_branch(pull, self.config["strict_method"])
def handle_first_pull_in_queue(self, ctxt): old_checks = [ c for c in ctxt.pull_engine_check_runs if c["name"].endswith(" (merge)") ] result = helpers.merge_report(ctxt, True) if result: ctxt.log.info( "pull request closed in the meantime", result=result, ) self.remove_pull(ctxt.pull["number"]) else: ctxt.log.info("updating base branch of pull request") config = self.get_config(ctxt.pull["number"]) result = helpers.update_pull_base_branch( ctxt, config["strict_method"], config["update_bot_account"] or config["bot_account"], ) if ctxt.pull["state"] == "closed": ctxt.log.info( "pull request closed in the meantime", result=result, ) self.remove_pull(ctxt.pull["number"]) elif result.conclusion == check_api.Conclusion.FAILURE: ctxt.log.info( "base branch update failed", result=result, ) self._move_pull_at_end(ctxt.pull["number"]) for c in old_checks: check_api.set_check_run(ctxt, c["name"], result)