Skip to content

Commit 62014f4

Browse files
committed
release-script: Merge branch 'release/v1.11.6'
2 parents 2eb53cc + dc9507a commit 62014f4

File tree

4 files changed

+113
-10
lines changed

4 files changed

+113
-10
lines changed

PyHEADTAIL/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.11.5'
1+
__version__ = '1.11.6'

PyHEADTAIL/feedback/transverse_damper.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import numpy as np
1010
from scipy.special import k0
1111
from scipy.constants import c, e
12-
import pylab as plt
1312

1413

1514
class TransverseDamper(object):

PyHEADTAIL/feedback/widebandfeedback.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import numpy as np
1010
from scipy.special import k0
1111
from scipy.constants import c, e
12-
import pylab as plt
1312

1413

1514
class TransferFunction(object):

release.py

Lines changed: 112 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
https://github.com/PyCOMPLETE/PyHEADTAIL/wiki/Our-Development-Workflow
66
77
Requires git, hub (the github tool, https://hub.github.com/) and importlib
8-
(included in python >=2.7) installed.
8+
(included in python >=2.7) to be installed.
99
10-
Should be PEP440 conformal.
10+
Conforms with PEP440 (especially the versioning needs to follow this).
1111
1212
@copyright: CERN
1313
@date: 26.01.2017
@@ -18,11 +18,17 @@
1818
import importlib # available from PyPI for Python <2.7
1919
import os, subprocess
2020

21+
# python2/3 compatibility for raw_input/input:
22+
if hasattr(__builtins__, 'raw_input'):
23+
input = raw_input
24+
2125
# CONFIG
2226
version_location = 'PyHEADTAIL._version' # in python relative module notation
2327
# (e.g. PyHEADTAIL._version for PyHEADTAIL/_version.py)
2428
test_script_location = 'prepush' # in python relative module notation
2529
release_branch_prefix = 'release/v' # prepended name of release branch
30+
github_user = 'PyCOMPLETE'
31+
github_repo = 'PyHEADTAIL'
2632

2733

2834
parser = argparse.ArgumentParser(
@@ -125,13 +131,68 @@ def ensure_hub_is_installed():
125131
'''
126132
try:
127133
assert subprocess.call(["hub", "--version"]) == 0
128-
except OSError:
134+
except (OSError, AssertionError):
129135
raise OSError(
130136
'The github command-line tool is needed for '
131137
'opening the pull request for the release. '
132138
'Please install hub from https://hub.github.com/ !'
133139
)
134140

141+
def ensure_gothub_is_installed():
142+
'''Check whether gothub (to draft github releases) is installed.
143+
If not, throw an error with an installation note.
144+
'''
145+
try:
146+
assert subprocess.call(["gothub", "--version"]) == 0
147+
except (OSError, AssertionError):
148+
raise OSError(
149+
'The gothub command-line tool is needed for '
150+
'drafting releases on github. '
151+
'Please install gothub from '
152+
'https://github.com/itchio/gothub !'
153+
)
154+
155+
def ensure_gitpulls_is_installed():
156+
'''Check whether the gem git-pulls (to get github pull requests) is
157+
installed.
158+
If not, throw an error with an installation note.
159+
'''
160+
try:
161+
assert subprocess.call(["git", "pulls"]) == 0
162+
except (OSError, AssertionError):
163+
raise OSError(
164+
'The gothub command-line tool is needed for '
165+
'checking the pull request text from the release. '
166+
'Please install git-pulls '
167+
'from https://github.com/schacon/git-pulls !'
168+
)
169+
170+
def check_release_tools():
171+
'''Return whether git-pulls and gothub are installed (needed for
172+
drafting the github release from CLI). If not, ask whether user
173+
wants to continue and draft the release manually (if this is not
174+
the case, raise exception!).
175+
'''
176+
try:
177+
ensure_gitpulls_is_installed()
178+
ensure_gothub_is_installed()
179+
return True
180+
except OSError:
181+
answer = ''
182+
accept = ['y', 'yes', 'n', 'no']
183+
while answer not in accept:
184+
answer = input(
185+
'!!! You do not have all required tools installed to '
186+
'automatically draft a release. Do you want to continue '
187+
'and manually draft the release on github afterwards?\n'
188+
'[y/N] ').lower()
189+
if not answer:
190+
answer = 'n'
191+
if answer == 'n' or answer == 'no':
192+
raise
193+
else:
194+
return False
195+
135196
def current_branch():
136197
'''Return current git branch name.'''
137198
# get the current branch name, strip trailing whitespaces using rstrip()
@@ -172,14 +233,42 @@ def git_status():
172233
)
173234
print (output)
174235

236+
def get_pullrequest_message(release_version):
237+
'''Fetch message from open pull request corresponding to this
238+
release_version.
239+
'''
240+
fetched = subprocess.check_output(['git', 'pulls', 'update'])
241+
pr_number = None
242+
for line in fetched.split('\n'):
243+
if "PyCOMPLETE:release/v{}".format(release_version) in line:
244+
pr_number = line.split()[0]
245+
break
246+
if pr_number is None:
247+
raise EnvironmentError(
248+
'Could not find open pull request for this release version. '
249+
'Did you properly initiate the release process '
250+
'(step 1 in ./release.py --help)?')
251+
text = subprocess.check_output(['git', 'pulls', 'show', pr_number])
252+
output = []
253+
for line in text.split('\n')[5:]:
254+
if line != '------------':
255+
output.append(line)
256+
else:
257+
break
258+
output[0] = output[0][11:] # remove "Title : "
259+
return '\n'.join(output)
260+
175261

176262
# DEFINE TWO STEPS FOR RELEASE PROCESS:
177263

178264
def init_release(part):
179265
'''Initialise release process.'''
180-
if not current_branch() == 'develop':
266+
if not current_branch() == 'develop' and not (
267+
current_branch()[:7] == 'hotfix/' and
268+
part == 'patch'):
181269
raise EnvironmentError(
182-
'Releases can only be initiated from the develop branch!')
270+
'Releases can only be initiated from the develop branch! '
271+
'(Releasing a patch is allowed from a hotfix/ branch as well.)')
183272
if is_worktree_dirty():
184273
git_status()
185274
raise EnvironmentError('Release process can only be initiated on '
@@ -213,6 +302,11 @@ def finalise_release():
213302
raise EnvironmentError('The PyHEADTAIL tests fail. Please fix '
214303
'the tests first!')
215304
print ('*** The PyHEADTAIL tests have successfully terminated.')
305+
306+
# all tools installed to automatically draft release?
307+
draft_release = check_release_tools()
308+
309+
# bump version file
216310
new_version = establish_new_version(version_location)
217311

218312
# make sure to push any possible release branch commits
@@ -240,12 +334,23 @@ def finalise_release():
240334
assert subprocess.call(["git", "merge", "master"]) == 0
241335
assert subprocess.call(["git", "push", "origin", "develop"]) == 0
242336

243-
# TO DO: publish github release (with text from pull request open in editor)
244-
245337
# delete release branch
246338
assert subprocess.call(["git", "branch", "-d", rbranch]) == 0
247339
assert subprocess.call(["git", "push", "origin", ":" + rbranch]) == 0
248340

341+
# publish github release (with message from pull request)
342+
if draft_release:
343+
message = get_pullrequest_message(new_version)
344+
assert subprocess.call(
345+
['gothub', 'release', '-u', github_user, '-r', github_repo,
346+
'-t', 'v' + new_version,
347+
'-n', '"PyHEADTAIL v{}"'.format(new_version),
348+
'-d', '"{}"'.format(message),
349+
'-c', 'master'])
350+
else:
351+
print ('*** Remember to manually draft this release from the '
352+
'github website.')
353+
249354
# ALGORITHM FOR RELEASE PROCESS:
250355
if __name__ == '__main__':
251356
print ('*** Current working directory:\n' + os.getcwd() + '\n')

0 commit comments

Comments
 (0)