118 lines
3.7 KiB
Text
118 lines
3.7 KiB
Text
|
#!/usr/bin/env python
|
||
|
"""Open a PR from the current branch"""
|
||
|
|
||
|
import sys
|
||
|
import os
|
||
|
import argparse
|
||
|
import requests
|
||
|
import re
|
||
|
from subprocess import check_call, check_output
|
||
|
from os.path import expanduser
|
||
|
|
||
|
usage = """
|
||
|
Example usage:
|
||
|
|
||
|
Open PR against master, with the review label:
|
||
|
|
||
|
./dev-tools/open_pr --remote tsg
|
||
|
|
||
|
Open PR against the 6.0 branch, with the review and in progress labels:
|
||
|
|
||
|
./dev-tools/open_pr --remote tsg --branch 6.0 --wip
|
||
|
|
||
|
Open PR against the 6.0 branch, with the review and docs labels:
|
||
|
|
||
|
./dev-tools/open_pr --remote tsg --labels=review,docs
|
||
|
|
||
|
The title and message of the PR are taken from the _last_ commit in the
|
||
|
PR.
|
||
|
"""
|
||
|
|
||
|
def main():
|
||
|
parser = argparse.ArgumentParser(
|
||
|
description="Creates a PR against a given branch",
|
||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||
|
epilog=usage)
|
||
|
|
||
|
parser.add_argument("--remote", default="origin",
|
||
|
help="Your git remote to push the branch to.")
|
||
|
parser.add_argument("--branch", default="master",
|
||
|
help="Remote branch to open PR against (e.g 5.0)")
|
||
|
parser.add_argument("--wip", action="store_true",
|
||
|
help="Add the `in progress` label")
|
||
|
parser.add_argument("--labels",
|
||
|
help="Extra labels to add (comma separated)")
|
||
|
parser.add_argument("--yes", action="store_true",
|
||
|
help="Assume yes.")
|
||
|
args = parser.parse_args()
|
||
|
local_branch = check_output("git rev-parse --abbrev-ref HEAD", shell=True).strip()
|
||
|
title = check_output("git show -q HEAD --format='%s'", shell=True).strip()
|
||
|
msg = check_output("git show -q HEAD --format='%b'", shell=True).strip()
|
||
|
|
||
|
labels = ["review"]
|
||
|
if args.labels:
|
||
|
labels.extend(args.labels.split(","))
|
||
|
if args.wip:
|
||
|
labels += "in progress"
|
||
|
|
||
|
# get version and set a version label on the original PR
|
||
|
version = get_version(os.getcwd())
|
||
|
if version:
|
||
|
labels.append("v" + version)
|
||
|
|
||
|
print("Branch: {}".format(args.branch))
|
||
|
print("Remote: {}".format(args.remote))
|
||
|
print("Local branch: {}".format(local_branch))
|
||
|
print("Title: {}".format(title))
|
||
|
print("Message: {}".format(msg))
|
||
|
print("Labels: {}".format(labels))
|
||
|
|
||
|
if not args.yes and raw_input("Continue? [Y/n]: ") not in ["y", "Y", ""]:
|
||
|
return 1
|
||
|
|
||
|
# push branch
|
||
|
check_call("git push --set-upstream {} {}"
|
||
|
.format(args.remote, local_branch), shell=True)
|
||
|
|
||
|
|
||
|
# open PR
|
||
|
token = open(expanduser("~/.elastic/github.token"), "r").read().strip()
|
||
|
base = "https://api.github.com/repos/elastic/beats"
|
||
|
session = requests.Session()
|
||
|
session.headers.update({"Authorization": "token " + token})
|
||
|
|
||
|
remote_url = check_output("git remote get-url {}".format(args.remote),
|
||
|
shell=True)
|
||
|
remote_user = re.search("github.com:(.+)/beats", remote_url).group(1)
|
||
|
|
||
|
request = session.post(base + "/pulls", json=dict(
|
||
|
title=title,
|
||
|
head=remote_user + ":" + local_branch,
|
||
|
base=args.branch,
|
||
|
body=msg
|
||
|
))
|
||
|
if request.status_code > 299:
|
||
|
print("Creating PR failed: {}".format(request.json()))
|
||
|
sys.exit(1)
|
||
|
new_pr = request.json()
|
||
|
|
||
|
# add labels
|
||
|
session.post(
|
||
|
base + "/issues/{}/labels".format(new_pr["number"]), json=labels)
|
||
|
|
||
|
print("\nDone. PR created: {}".format(new_pr["html_url"]))
|
||
|
print("Please go and review it for the message and labels.")
|
||
|
|
||
|
|
||
|
def get_version(beats_dir):
|
||
|
pattern = re.compile(r'(const\s|)\w*(v|V)ersion\s=\s"(?P<version>.*)"')
|
||
|
with open(os.path.join(beats_dir, "libbeat/version/version.go"), "r") as f:
|
||
|
for line in f:
|
||
|
match = pattern.match(line)
|
||
|
if match:
|
||
|
return match.group('version')
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
sys.exit(main())
|