Closed janosh closed 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)
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.
the trust concern is third parties (hooks are arbitrary code)
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.)
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
@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)
@asottile FWIW, auto-merge is documented for Dependabot.
@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
@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.
noting is stopping you from doing exactly what your link indicates
Exactly the point I was making :) That approach wasn't mentioned anywhere else on this thread that I can see.
your message reads like "anthony you should implement this because dependabot does" you even tagged me?
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 :)
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 optionsmerge
,rebase
,squash
that would automatically merge auto-update PRs once all checks passed.