diff options
Diffstat (limited to 'src/script/build-integration-branch')
-rwxr-xr-x | src/script/build-integration-branch | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/script/build-integration-branch b/src/script/build-integration-branch new file mode 100755 index 000000000..b4f2a6121 --- /dev/null +++ b/src/script/build-integration-branch @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 + +""" +Builds integration branches. Something similar to + $ git checkout -b branch-name + $ for b in $(get-branches-from-github) ; do + > git pull b + > done + +Requires `~/.github_token`. + + +Usage: + build-integration-branch <label> [--no-date] + build-integration-branch -h | --help + +Options: + -h --help Show this screen. + --no-date Don't add `{postfix}` to the branch name. +""" + +import json +import os +import requests +import sys +import time + +from subprocess import call, check_output +from urllib.parse import urljoin + +TIME_FORMAT = '%Y-%m-%d-%H%M' +postfix = "-" + time.strftime(TIME_FORMAT, time.localtime()) + +current_branch = check_output('git rev-parse --abbrev-ref HEAD', + shell=True).strip().decode() +if current_branch in 'mimic nautilus octopus pacific quincy'.split(): + postfix += '-' + current_branch + print(f"Adding current branch name '-{current_branch}' as a postfix") + +repo = "ceph/ceph" + +try: + from docopt import docopt + arguments = docopt(__doc__.format(postfix=postfix)) + label = arguments['<label>'] + branch = label + if not arguments['--no-date']: + branch += postfix +except ImportError: + # Fallback without docopt. + label = sys.argv[1] + assert len(sys.argv) == 2 + branch = label + postfix + + +with open(os.path.expanduser('~/.github_token')) as myfile: + token = myfile.readline().strip() + +# get prs +baseurl = urljoin('https://api.github.com', + ('repos/{repo}/issues?labels={label}' + '&sort=created' + '&direction=asc')) +url = baseurl.format(label=label, + repo=repo) +r = requests.get(url, + headers={'Authorization': 'token %s' % token}) +assert(r.ok) +j = json.loads(r.text or r.content) +print("--- found %d issues tagged with %s" % (len(j), label)) + +prs = [] +prtext = [] +for issue in j: + if 'pull_request' not in issue: + continue + r = requests.get(issue['pull_request']['url'], + headers={'Authorization': 'token %s' % token}) + pr = json.loads(r.text or r.content) + prs.append(pr) + prtext.append(pr['html_url'] + ' - ' + pr['title']) +print("--- queried %s prs" % len(prs)) + +print("branch %s" % branch) + +# assemble +print('--- creating branch %s' % branch) +r = call(['git', 'branch', '-D', branch]) +r = call(['git', 'checkout', '-b', branch]) +assert not r +for pr in prs: + pr_number = pr['number'] + pr_url = pr['head']['repo']['clone_url'] + pr_ref = pr['head']['ref'] + print(f'--- pr {pr_number} --- pulling {pr_url} branch {pr_ref}') + while True: + r = call(['git', 'pull', '--no-ff', '--no-edit', pr_url, pr_ref]) + if r == 0: + break + elif r == 1: + print(f'Unable to access {pr_url}, retrying..') + elif r == 128: + message = f'Unable to resolve conflict when merging PR#{pr_number}' + raise Exception(message) + else: + message = ('Exiting due to an unknown failure when pulling ' + f'PR#{pr_number}') + raise Exception(message) + +print('--- done. these PRs were included:') +print('\n'.join(prtext).encode('ascii', errors='ignore').decode()) +print('--- perhaps you want to: ./run-make-check.sh && git push ci %s' % branch) |