pre-commit-ci / issues

public issues for https://pre-commit.ci
17 stars 3 forks source link

Add config option to auto-merge #48

Closed janosh closed 3 years ago

janosh commented 3 years ago

Once you have more than 2 or 3 repos using pre-commit.ci, getting a bunch of emails about an auto-update to .pre-commit-config.yaml and then having to click each one to merge the PR becomes a hassle.

Not sure how feasible this is but would be cool if pre-commit.ci had a config option called, say, auto-merge with options merge, rebase, squash that would automatically merge auto-update PRs once all checks passed.

asottile commented 3 years ago

auto-merge is a potential security issue, there will always be a vetting period before automatically integrating branches

you can however configure some other service to auto merge for you. but I won't be implementing it (the same reasons that dependabot does not implement it)

cpsauer commented 2 years ago

Bummer! Just to make sure I'm not missing something, the potential security issue is that we'd be trusting you/pre-commit-ci, right? (And not something about third-party libraries like with dependabot?)

More importantly, thank you for the great set of tools you've made here! We really enjoy using them.

asottile commented 2 years ago

the trust concern is third parties (hooks are arbitrary code)

cpsauer commented 2 years ago

Ah, oh I see. It must also update the third-party hook repos, then too. (We're only currently using your first party ones currently.)

cpsauer commented 1 year ago

If anyone else lands here wanting to automate merging of autoupdates, we ended up using mergify.

Just add the app, add the config (here's ours as a reference), and you're good to go.

You may also want to add PR branch auto-deletion in your repo's GitHub settings (so the branch isn't around when not in use), and you'll need to comment @Mergifyio refresh to get it to run on a preexisting PRs.

Cheers! Chris

janosh commented 1 year ago

@cpsauer I wrote this script using gh CLI to do the merging for me. Maybe useful to others.

import subprocess
from typing import Literal

__author__ = "Janosh Riebesell"
__date__ = "2022-07-04"

description = """
Batch merge bot-created PRs. Uses the GitHub CLI (`brew install gh`) which must be
authenticated (`gh auth status` must exit 0). By default asks for confirmation
before merging each PR. Pass --yes to skip confirmation.

Written to auto-merge green pre-commit.ci auto-update PRs.

Example invocation:
python -m merge_bot_prs --ci-status any

Or to auto-merge all PRs with passing checks (green CI):
python -m merge_bot_prs --yes
"""

def main(
    bot: str,
    owner: str,
    yes: bool = False,
    ci_status: Literal["success", "any"] = "success",
) -> int:

    # make sure gh auth status returns 0 which means user is logged in and hopefully
    # authorized to merge PRs
    if subprocess.run("gh auth status".split(), check=True).returncode != 0:
        raise PermissionError("Please run `gh auth login` and then `gh auth token`")

    search_prs_cmd = f"gh search prs --state=open --app={bot} --owner={owner}"
    if ci_status == "success":
        search_prs_cmd += " --checks=success"
    pr_list = (
        subprocess.run(search_prs_cmd.split(), capture_output=True)
        .stdout.decode("utf-8")
        .split("\n")
    )
    pr_list = list(filter(bool, pr_list))

    if len(pr_list) == 0:
        print("No PRs found")

    for idx, pr_header in enumerate(pr_list, 1):
        try:
            repo_handle, pr_number, *_ = pr_header.split("\t")
            counter = f"{idx}/{len(pr_list)}"

            if not pr_number.isdigit():
                raise ValueError(f"{pr_number=} is not a number")

            pr_url = f"https://github.com/{repo_handle}/pull/{pr_number}"

            if yes:
                print(f"{counter} Merging {pr_url}")

            answer = "yes" if yes else ""
            while answer not in ("y", "n", "yes", "no"):
                answer = input(f"{counter} Merge {pr_url}? [y/n] ").lower()

            if answer in ("y", "yes"):
                merge_pr_cmd = (
                    f"gh pr merge {pr_number} --repo {repo_handle} --squash --delete-branch"
                ).split()
                subprocess.run(merge_pr_cmd, capture_output=True, check=True)
                print(f"✓ {repo_handle}#{pr_number} merged!")
        except ValueError:
            print(f"{pr_header=}")
            raise

    return 0

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description=description)

    parser.add_argument(
        "--bot", default="pre-commit-ci", help="Name of the bot to merge PRs from"
    )
    parser.add_argument(
        "--owner",
        default="@me",
        help="GitHub user handle of the repos' owner. Can be an org handle but you "
        "must be privileged to merge org PRs.",
    )
    parser.add_argument(
        "--yes",
        action="store_true",
        help="Skip confirmation prompt for each PR and automatically merge all "
        "matching PRs.",
    )
    parser.add_argument(
        "--ci-status",
        choices=("success", "any"),
        default="success",
        help="Only merge PRs that have this status. 'success' will only merge green "
        "PRs. 'any' also includes 'failure' and 'pending'.",
    )
    args = parser.parse_args()

    try:
        ret_code = main(**vars(args))
    except KeyboardInterrupt:
        ret_code = 1

    raise SystemExit(ret_code)
michaelmior commented 1 month ago

@asottile FWIW, auto-merge is documented for Dependabot.

asottile commented 1 month ago

@michaelmior you'll notice that's talking about the github auto merge feature (and then they show you how to hook up a github action to approve it and kick off the process). dependabot itself does not get involved there

michaelmior commented 1 month ago

@asottile True, but since Dependabot is a feature developed by GitHub, I don't think that there's a significant difference. My point was that if anyone wants automerge, they should be able to approach it the same way.

asottile commented 1 month ago

noting is stopping you from doing exactly what your link indicates

michaelmior commented 1 month ago

Exactly the point I was making :) That approach wasn't mentioned anywhere else on this thread that I can see.

asottile commented 1 month ago

your message reads like "anthony you should implement this because dependabot does" you even tagged me?

michaelmior commented 1 month ago

I was responding to your earlier comment that Dependabot doesn't implement automerge. I wasn't requesting that you implement anything. My main point is that there is already a way to have pre-commit.ci PRs be automerged without you needing to do anything.

Anyway, sorry for any confusion and thanks for pre-commit.ci :)