]> git.proxmox.com Git - ceph.git/blob - ceph/src/script/build-integration-branch
import quincy beta 17.1.0
[ceph.git] / ceph / src / script / build-integration-branch
1 #!/usr/bin/env python3
2
3 """
4 Builds integration branches. Something similar to
5 $ git checkout -b branch-name
6 $ for b in $(get-branches-from-github) ; do
7 > git pull b
8 > done
9
10 Requires `~/.github_token`.
11
12
13 Usage:
14 build-integration-branch <label> [--no-date]
15 build-integration-branch -h | --help
16
17 Options:
18 -h --help Show this screen.
19 --no-date Don't add `{postfix}` to the branch name.
20 """
21
22 import json
23 import os
24 import requests
25 import sys
26 import time
27
28 from subprocess import call, check_output
29 from urllib.parse import urljoin
30
31 TIME_FORMAT = '%Y-%m-%d-%H%M'
32 postfix = "-" + time.strftime(TIME_FORMAT, time.localtime())
33
34 current_branch = check_output('git rev-parse --abbrev-ref HEAD',
35 shell=True).strip().decode()
36 if current_branch in 'mimic nautilus octopus pacific'.split():
37 postfix += '-' + current_branch
38 print(f"Adding current branch name '-{current_branch}' as a postfix")
39
40 repo = "ceph/ceph"
41
42 try:
43 from docopt import docopt
44 arguments = docopt(__doc__.format(postfix=postfix))
45 label = arguments['<label>']
46 branch = label
47 if not arguments['--no-date']:
48 branch += postfix
49 except ImportError:
50 # Fallback without docopt.
51 label = sys.argv[1]
52 assert len(sys.argv) == 2
53 branch = label + postfix
54
55
56 with open(os.path.expanduser('~/.github_token')) as myfile:
57 token = myfile.readline().strip()
58
59 # get prs
60 baseurl = urljoin('https://api.github.com',
61 ('repos/{repo}/issues?labels={label}'
62 '&sort=created'
63 '&direction=asc'))
64 url = baseurl.format(label=label,
65 repo=repo)
66 r = requests.get(url,
67 headers={'Authorization': 'token %s' % token})
68 assert(r.ok)
69 j = json.loads(r.text or r.content)
70 print("--- found %d issues tagged with %s" % (len(j), label))
71
72 prs = []
73 prtext = []
74 for issue in j:
75 if 'pull_request' not in issue:
76 continue
77 r = requests.get(issue['pull_request']['url'],
78 headers={'Authorization': 'token %s' % token})
79 pr = json.loads(r.text or r.content)
80 prs.append(pr)
81 prtext.append(pr['html_url'] + ' - ' + pr['title'])
82 print("--- queried %s prs" % len(prs))
83
84 print("branch %s" % branch)
85
86 # assemble
87 print('--- creating branch %s' % branch)
88 r = call(['git', 'branch', '-D', branch])
89 r = call(['git', 'checkout', '-b', branch])
90 assert not r
91 for pr in prs:
92 pr_number = pr['number']
93 pr_url = pr['head']['repo']['clone_url']
94 pr_ref = pr['head']['ref']
95 print(f'--- pr {pr_number} --- pulling {pr_url} branch {pr_ref}')
96 while True:
97 r = call(['git', 'pull', '--no-ff', '--no-edit', pr_url, pr_ref])
98 if r == 0:
99 break
100 elif r == 1:
101 print(f'Unable to access {pr_url}, retrying..')
102 elif r == 128:
103 message = f'Unable to resolve conflict when merging PR#{pr_number}'
104 raise Exception(message)
105 else:
106 message = ('Exiting due to an unknown failure when pulling '
107 f'PR#{pr_number}')
108 raise Exception(message)
109
110 print('--- done. these PRs were included:')
111 print('\n'.join(prtext).encode('ascii', errors='ignore').decode())
112 print('--- perhaps you want to: ./run-make-check.sh && git push ci %s' % branch)