Skip to content

Commit b352f56

Browse files
authored
Merge pull request ceph#64543 from phlogistonjohn/jjm-bib
src/script/build-integration-branch improvements
2 parents acaa65f + c907049 commit b352f56

File tree

1 file changed

+160
-108
lines changed

1 file changed

+160
-108
lines changed

src/script/build-integration-branch

Lines changed: 160 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,9 @@ OR adding an entry like the following to `~/.netrc`:
1313
machine github.com
1414
password ghp_E7ln0tAR34LtoK3nIsw34RyTve2moM3BvK
1515
```
16-
17-
18-
Usage:
19-
build-integration-branch <label> [--no-date]
20-
build-integration-branch -h | --help
21-
22-
Options:
23-
-h --help Show this screen.
24-
--no-date Don't add `{postfix}` to the branch name.
2516
"""
2617

18+
import argparse
2719
import json
2820
import os
2921
import requests
@@ -35,107 +27,167 @@ from subprocess import call, check_output
3527
from urllib.parse import urljoin
3628

3729
TIME_FORMAT = '%Y-%m-%d-%H%M'
38-
postfix = "-" + time.strftime(TIME_FORMAT, time.localtime())
39-
40-
current_branch = check_output('git rev-parse --abbrev-ref HEAD',
41-
shell=True).strip().decode()
42-
if current_branch in 'mimic nautilus octopus pacific quincy reef squid tentacle'.split():
43-
postfix += '-' + current_branch
44-
print(f"Adding current branch name '-{current_branch}' as a postfix")
45-
46-
repo = "ceph/ceph"
47-
48-
try:
49-
from docopt import docopt
50-
arguments = docopt(__doc__.format(postfix=postfix))
51-
label = arguments['<label>']
52-
branch = label
53-
if not arguments['--no-date']:
54-
branch += postfix
55-
except ImportError:
56-
# Fallback without docopt.
57-
label = sys.argv[1]
58-
assert len(sys.argv) == 2
59-
branch = label + postfix
60-
61-
token = ''
62-
try:
63-
nrc = netrc.netrc()
64-
nrauth = nrc.authenticators("api.github.com")
65-
if nrauth:
66-
token = nrauth[2]
67-
if not token:
68-
nrauth = nrc.authenticators("github.com")
30+
CODENAMES = 'mimic nautilus octopus pacific quincy reef squid tentacle'
31+
REPO = "ceph/ceph"
32+
33+
34+
def get_postfix():
35+
postfix = "-" + time.strftime(TIME_FORMAT, time.localtime())
36+
current_branch = (
37+
check_output('git rev-parse --abbrev-ref HEAD', shell=True)
38+
.strip()
39+
.decode()
40+
)
41+
if current_branch in CODENAMES.split():
42+
postfix += '-' + current_branch
43+
print(f"Adding current branch name '-{current_branch}' as a postfix")
44+
return postfix
45+
46+
47+
def parse_args():
48+
parser = argparse.ArgumentParser(usage=__doc__)
49+
parser.add_argument(
50+
"--no-date",
51+
"--no-postfix",
52+
action="store_true",
53+
help="Don't add `{postfix}` to the branch name.",
54+
)
55+
parser.add_argument(
56+
"--trailer",
57+
action="append",
58+
dest='trailers',
59+
help="Allow user to set arbitrary git trailers on final commit.",
60+
)
61+
parser.add_argument(
62+
'--ceph-build-job',
63+
action="append",
64+
dest='trailers',
65+
type=lambda v: f'CEPH-BUILD-JOB:{v}',
66+
help="Set CEPH-BUILD-JOB trailer on final commit.",
67+
)
68+
parser.add_argument(
69+
'--distros',
70+
action="append",
71+
dest='trailers',
72+
type=lambda v: f'DISTROS:{v}',
73+
help="Set DISTROS trailer on final commit.",
74+
)
75+
parser.add_argument(
76+
'--archs',
77+
action="append",
78+
dest='trailers',
79+
type=lambda v: f'ARCHS:{v}',
80+
help="Set DISTROS trailer on final commit.",
81+
)
82+
parser.add_argument(
83+
"--repo",
84+
default=REPO,
85+
help="GitHub repository (in `<org>/<name>` form)",
86+
)
87+
parser.add_argument(
88+
"label",
89+
help="GitHub label to search for",
90+
)
91+
return parser.parse_args()
92+
93+
94+
def main():
95+
cli = parse_args()
96+
if cli.no_date:
97+
branch = cli.label
98+
else:
99+
branch = cli.label + get_postfix()
100+
label = cli.label
101+
repo = cli.repo
102+
103+
token = ''
104+
try:
105+
nrc = netrc.netrc()
106+
nrauth = nrc.authenticators("api.github.com")
69107
if nrauth:
70108
token = nrauth[2]
71-
except FileNotFoundError:
72-
pass
73-
if not token:
74-
try:
75-
with open(os.path.expanduser('~/.github_token')) as myfile:
76-
token = myfile.readline().strip()
109+
if not token:
110+
nrauth = nrc.authenticators("github.com")
111+
if nrauth:
112+
token = nrauth[2]
77113
except FileNotFoundError:
78114
pass
79-
if not token:
80-
print('No github api access token found')
81-
print(' Add a token to .netrc for [api.]github.com')
82-
print(' OR add a token to $HOME/.github_token')
83-
84-
# get prs
85-
baseurl = urljoin('https://api.github.com',
86-
('repos/{repo}/issues?labels={label}'
87-
'&sort=created'
88-
'&direction=asc'))
89-
url = baseurl.format(label=label,
90-
repo=repo)
91-
r = requests.get(url,
92-
headers={'Authorization': 'token %s' % token})
93-
if not r.ok:
94-
print("Failed to access github api")
95-
print("(Do you have a valid, unexpired github api token?)")
96-
sys.exit(1)
97-
98-
j = json.loads(r.text or r.content)
99-
print("--- found %d issues tagged with %s" % (len(j), label))
100-
101-
prs = []
102-
prtext = []
103-
for issue in j:
104-
if 'pull_request' not in issue:
105-
continue
106-
r = requests.get(issue['pull_request']['url'],
115+
if not token:
116+
try:
117+
with open(os.path.expanduser('~/.github_token')) as myfile:
118+
token = myfile.readline().strip()
119+
except FileNotFoundError:
120+
pass
121+
if not token:
122+
print('No github api access token found')
123+
print(' Add a token to .netrc for [api.]github.com')
124+
print(' OR add a token to $HOME/.github_token')
125+
126+
# get prs
127+
baseurl = urljoin('https://api.github.com',
128+
('repos/{repo}/issues?labels={label}'
129+
'&sort=created'
130+
'&direction=asc'))
131+
url = baseurl.format(label=label,
132+
repo=repo)
133+
r = requests.get(url,
107134
headers={'Authorization': 'token %s' % token})
108-
pr = json.loads(r.text or r.content)
109-
prs.append(pr)
110-
prtext.append(pr['html_url'] + ' - ' + pr['title'])
111-
print("--- queried %s prs" % len(prs))
112-
113-
print("branch %s" % branch)
114-
115-
# assemble
116-
print('--- creating branch %s' % branch)
117-
r = call(['git', 'branch', '-D', branch])
118-
r = call(['git', 'checkout', '-b', branch])
119-
assert not r
120-
for pr in prs:
121-
pr_number = pr['number']
122-
pr_url = pr['head']['repo']['clone_url']
123-
pr_ref = pr['head']['ref']
124-
print(f'--- pr {pr_number} --- pulling {pr_url} branch {pr_ref}')
125-
while True:
126-
r = call(['git', 'pull', '--no-ff', '--no-edit', pr_url, pr_ref])
127-
if r == 0:
128-
break
129-
elif r == 1:
130-
print(f'Unable to access {pr_url}, retrying..')
131-
elif r == 128:
132-
message = f'Unable to resolve conflict when merging PR#{pr_number}'
133-
raise Exception(message)
134-
else:
135-
message = ('Exiting due to an unknown failure when pulling '
136-
f'PR#{pr_number}')
137-
raise Exception(message)
138-
139-
print('--- done. these PRs were included:')
140-
print('\n'.join(prtext).encode('ascii', errors='ignore').decode())
141-
print('--- perhaps you want to: ./run-make-check.sh && git push ci %s' % branch)
135+
if not r.ok:
136+
print("Failed to access github api")
137+
print("(Do you have a valid, unexpired github api token?)")
138+
sys.exit(1)
139+
140+
j = json.loads(r.text or r.content)
141+
print("--- found %d issues tagged with %s" % (len(j), label))
142+
143+
prs = []
144+
prtext = []
145+
for issue in j:
146+
if 'pull_request' not in issue:
147+
continue
148+
r = requests.get(issue['pull_request']['url'],
149+
headers={'Authorization': 'token %s' % token})
150+
pr = json.loads(r.text or r.content)
151+
prs.append(pr)
152+
prtext.append(pr['html_url'] + ' - ' + pr['title'])
153+
print("--- queried %s prs" % len(prs))
154+
155+
print("branch %s" % branch)
156+
157+
# assemble
158+
print('--- creating branch %s' % branch)
159+
r = call(['git', 'branch', '-D', branch])
160+
r = call(['git', 'checkout', '-b', branch])
161+
assert not r
162+
for pr in prs:
163+
pr_number = pr['number']
164+
pr_url = pr['head']['repo']['clone_url']
165+
pr_ref = pr['head']['ref']
166+
print(f'--- pr {pr_number} --- pulling {pr_url} branch {pr_ref}')
167+
while True:
168+
r = call(['git', 'pull', '--no-ff', '--no-edit', pr_url, pr_ref])
169+
if r == 0:
170+
break
171+
elif r == 1:
172+
print(f'Unable to access {pr_url}, retrying..')
173+
elif r == 128:
174+
message = f'Unable to resolve conflict when merging PR#{pr_number}'
175+
raise Exception(message)
176+
else:
177+
message = ('Exiting due to an unknown failure when pulling '
178+
f'PR#{pr_number}')
179+
raise Exception(message)
180+
if cli.trailers:
181+
cmd = ['git', 'commit', '--am', '--no-edit']
182+
cmd.extend(f'--trailer={t}' for t in cli.trailers)
183+
if call(cmd) != 0:
184+
print('Failed to set git trailers!')
185+
sys.exit(1)
186+
187+
print('--- done. these PRs were included:')
188+
print('\n'.join(prtext).encode('ascii', errors='ignore').decode())
189+
print('--- perhaps you want to: ./run-make-check.sh && git push ci %s' % branch)
190+
191+
192+
if __name__ == '__main__':
193+
main()

0 commit comments

Comments
 (0)