Ejemplo n.º 1
0
 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"],
         )
Ejemplo n.º 2
0
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})
Ejemplo n.º 3
0
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
            },
        )
Ejemplo n.º 4
0
    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
                },
            )
Ejemplo n.º 5
0
    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", "")
Ejemplo n.º 6
0
 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"])
Ejemplo n.º 7
0
    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)