Merge pull request #6073 from docker/release-tool-improve

Misc improvements to release script
This commit is contained in:
Joffrey F 2018-07-10 15:04:31 -04:00 committed by GitHub
commit 8c4fc4bc2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 9 deletions

View File

@ -4,6 +4,7 @@ from __future__ import unicode_literals
import argparse
import os
import shutil
import sys
import time
from distutils.core import run_setup
@ -27,6 +28,7 @@ from release.utils import ScriptError
from release.utils import update_init_py_version
from release.utils import update_run_sh_version
from release.utils import yesno
from requests.exceptions import HTTPError
from twine.commands.upload import main as twine_upload
@ -128,13 +130,60 @@ def print_final_instructions(args):
"You're almost done! Please verify that everything is in order and "
"you are ready to make the release public, then run the following "
"command:\n{exe} -b {user} finalize {version}".format(
exe=sys.argv[0], user=args.bintray_user, version=args.release
exe='./script/release/release.sh', user=args.bintray_user, version=args.release
)
)
def distclean():
print('Running distclean...')
dirs = [
os.path.join(REPO_ROOT, 'build'), os.path.join(REPO_ROOT, 'dist'),
os.path.join(REPO_ROOT, 'docker-compose.egg-info')
]
files = []
for base, dirnames, fnames in os.walk(REPO_ROOT):
for fname in fnames:
path = os.path.normpath(os.path.join(base, fname))
if fname.endswith('.pyc'):
files.append(path)
elif fname.startswith('.coverage.'):
files.append(path)
for dirname in dirnames:
path = os.path.normpath(os.path.join(base, dirname))
if dirname == '__pycache__':
dirs.append(path)
elif dirname == '.coverage-binfiles':
dirs.append(path)
for file in files:
os.unlink(file)
for folder in dirs:
shutil.rmtree(folder, ignore_errors=True)
def pypi_upload(args):
print('Uploading to PyPi')
try:
twine_upload([
'dist/docker_compose-{}*.whl'.format(args.release),
'dist/docker-compose-{}*.tar.gz'.format(args.release)
])
except HTTPError as e:
if e.response.status_code == 400 and 'File already exists' in e.message:
if not args.finalize_resume:
raise ScriptError(
'Package already uploaded on PyPi.'
)
print('Skipping PyPi upload - package already uploaded')
else:
raise ScriptError('Unexpected HTTP error uploading package to PyPi: {}'.format(e))
def resume(args):
try:
distclean()
repository = Repository(REPO_ROOT, args.repo)
br_name = branch_name(args.release)
if not repository.branch_exists(br_name):
@ -186,6 +235,7 @@ def cancel(args):
bintray_api = BintrayAPI(os.environ['BINTRAY_TOKEN'], args.bintray_user)
print('Removing Bintray data repository for {}'.format(args.release))
bintray_api.delete_repository(args.bintray_org, branch_name(args.release))
distclean()
except ScriptError as e:
print(e)
return 1
@ -194,6 +244,7 @@ def cancel(args):
def start(args):
distclean()
try:
repository = Repository(REPO_ROOT, args.repo)
create_initial_branch(repository, args)
@ -216,6 +267,7 @@ def start(args):
def finalize(args):
distclean()
try:
repository = Repository(REPO_ROOT, args.repo)
img_manager = ImageManager(args.release)
@ -241,10 +293,13 @@ def finalize(args):
run_setup(os.path.join(REPO_ROOT, 'setup.py'), script_args=['sdist', 'bdist_wheel'])
merge_status = pr_data.merge()
if not merge_status.merged:
raise ScriptError('Unable to merge PR #{}: {}'.format(pr_data.number, merge_status.message))
print('Uploading to PyPi')
twine_upload(['dist/*'])
if not merge_status.merged and not args.finalize_resume:
raise ScriptError(
'Unable to merge PR #{}: {}'.format(pr_data.number, merge_status.message)
)
pypi_upload(args)
img_manager.push_images()
repository.publish_release(gh_release)
except ScriptError as e:
@ -263,13 +318,13 @@ ACTIONS = [
EPILOG = '''Example uses:
* Start a new feature release (includes all changes currently in master)
release.py -b user start 1.23.0
release.sh -b user start 1.23.0
* Start a new patch release
release.py -b user --patch 1.21.0 start 1.21.1
release.sh -b user --patch 1.21.0 start 1.21.1
* Cancel / rollback an existing release draft
release.py -b user cancel 1.23.0
release.sh -b user cancel 1.23.0
* Restart a previously aborted patch release
release.py -b user -p 1.21.0 resume 1.21.1
release.sh -b user -p 1.21.0 resume 1.21.1
'''
@ -319,6 +374,10 @@ def main():
'--skip-ci-checks', dest='skip_ci', action='store_true',
help='If set, the program will not wait for CI jobs to complete'
)
parser.add_argument(
'--finalize-resume', dest='finalize_resume', action='store_true',
help='If set, finalize will continue through steps that have already been completed.'
)
args = parser.parse_args()
if args.action == 'start':

View File

@ -81,3 +81,7 @@ class ImageManager(object):
for chunk in logstream:
if 'status' in chunk:
print(chunk['status'])
if 'error' in chunk:
raise ScriptError(
'Error pushing {name}: {err}'.format(name=name, err=chunk['error'])
)