From be324d57a20be9280e8bdbce3eed12f7b9feecfa Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Fri, 12 Oct 2018 06:13:55 -0700 Subject: [PATCH 1/3] Add pypirc check Signed-off-by: Joffrey F --- script/release/release.py | 24 +++---------------- script/release/release/pypi.py | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 21 deletions(-) create mode 100644 script/release/release/pypi.py diff --git a/script/release/release.py b/script/release/release.py index 9a5af3aa5..15c74c775 100755 --- a/script/release/release.py +++ b/script/release/release.py @@ -17,6 +17,8 @@ from release.const import NAME from release.const import REPO_ROOT from release.downloader import BinaryDownloader from release.images import ImageManager +from release.pypi import check_pypirc +from release.pypi import pypi_upload from release.repository import delete_assets from release.repository import get_contributors from release.repository import Repository @@ -28,8 +30,6 @@ 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 def create_initial_branch(repository, args): @@ -170,25 +170,6 @@ def distclean(): shutil.rmtree(folder, ignore_errors=True) -def pypi_upload(args): - print('Uploading to PyPi') - try: - rel = args.release.replace('-rc', 'rc') - twine_upload([ - 'dist/docker_compose-{}*.whl'.format(rel), - 'dist/docker-compose-{}*.tar.gz'.format(rel) - ]) - 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() @@ -277,6 +258,7 @@ def start(args): def finalize(args): distclean() try: + check_pypirc() repository = Repository(REPO_ROOT, args.repo) img_manager = ImageManager(args.release) pr_data = repository.find_release_pr(args.release) diff --git a/script/release/release/pypi.py b/script/release/release/pypi.py new file mode 100644 index 000000000..a40e17544 --- /dev/null +++ b/script/release/release/pypi.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import +from __future__ import unicode_literals + +from configparser import Error +from requests.exceptions import HTTPError +from twine.commands.upload import main as twine_upload +from twine.utils import get_config + +from .utils import ScriptError + + +def pypi_upload(args): + print('Uploading to PyPi') + try: + rel = args.release.replace('-rc', 'rc') + twine_upload([ + 'dist/docker_compose-{}*.whl'.format(rel), + 'dist/docker-compose-{}*.tar.gz'.format(rel) + ]) + 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 check_pypirc(): + try: + config = get_config() + except Error as e: + raise ScriptError('Failed to parse .pypirc file: {}'.format(e)) + + if config is None: + raise ScriptError('Failed to parse .pypirc file') + + if 'pypi' not in config: + raise ScriptError('Missing [pypi] section in .pypirc file') + + if not (config['pypi'].get('username') and config['pypi'].get('password')): + raise ScriptError('Missing login/password pair for pypi repo') From 297bee897b251a791fc3612225bf1e93505fe957 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Fri, 12 Oct 2018 06:14:35 -0700 Subject: [PATCH 2/3] Fix arg checks in release.sh Signed-off-by: Joffrey F --- script/release/release.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/script/release/release.sh b/script/release/release.sh index 7947316e0..c10f8aba5 100755 --- a/script/release/release.sh +++ b/script/release/release.sh @@ -6,10 +6,8 @@ else ./script/release/setup-venv.sh fi -args=$* - -if test -z $args; then +if test -z "$*"; then args="--help" fi -./.release-venv/bin/python ./script/release/release.py $args +./.release-venv/bin/python ./script/release/release.py "$@" From bd67b90869051db4f7fd5c222b538ee07c58ef56 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Fri, 12 Oct 2018 06:39:56 -0700 Subject: [PATCH 3/3] Fix ImageManager inconsistencies Signed-off-by: Joffrey F --- script/release/release.py | 2 +- script/release/release/images.py | 27 ++++++++++++--------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/script/release/release.py b/script/release/release.py index 15c74c775..6574bfddd 100755 --- a/script/release/release.py +++ b/script/release/release.py @@ -266,7 +266,7 @@ def finalize(args): raise ScriptError('No PR found for {}'.format(args.release)) if not check_pr_mergeable(pr_data): raise ScriptError('Can not finalize release with an unmergeable PR') - if not img_manager.check_images(args.release): + if not img_manager.check_images(): raise ScriptError('Missing release image') br_name = branch_name(args.release) if not repository.branch_exists(br_name): diff --git a/script/release/release/images.py b/script/release/release/images.py index e247f596d..df6eeda4f 100644 --- a/script/release/release/images.py +++ b/script/release/release/images.py @@ -27,13 +27,12 @@ class ImageManager(object): def build_images(self, repository, files): print("Building release images...") repository.write_git_sha() - docker_client = docker.APIClient(**docker.utils.kwargs_from_env()) distdir = os.path.join(REPO_ROOT, 'dist') os.makedirs(distdir, exist_ok=True) shutil.copy(files['docker-compose-Linux-x86_64'][0], distdir) os.chmod(os.path.join(distdir, 'docker-compose-Linux-x86_64'), 0o755) print('Building docker/compose image') - logstream = docker_client.build( + logstream = self.docker_client.build( REPO_ROOT, tag='docker/compose:{}'.format(self.version), dockerfile='Dockerfile.run', decode=True ) @@ -44,7 +43,7 @@ class ImageManager(object): print(chunk['stream'], end='') print('Building test image (for UCP e2e)') - logstream = docker_client.build( + logstream = self.docker_client.build( REPO_ROOT, tag='docker-compose-tests:tmp', decode=True ) for chunk in logstream: @@ -53,13 +52,15 @@ class ImageManager(object): if 'stream' in chunk: print(chunk['stream'], end='') - container = docker_client.create_container( + container = self.docker_client.create_container( 'docker-compose-tests:tmp', entrypoint='tox' ) - docker_client.commit(container, 'docker/compose-tests', 'latest') - docker_client.tag('docker/compose-tests:latest', 'docker/compose-tests:{}'.format(self.version)) - docker_client.remove_container(container, force=True) - docker_client.remove_image('docker-compose-tests:tmp', force=True) + self.docker_client.commit(container, 'docker/compose-tests', 'latest') + self.docker_client.tag( + 'docker/compose-tests:latest', 'docker/compose-tests:{}'.format(self.version) + ) + self.docker_client.remove_container(container, force=True) + self.docker_client.remove_image('docker-compose-tests:tmp', force=True) @property def image_names(self): @@ -69,23 +70,19 @@ class ImageManager(object): 'docker/compose:{}'.format(self.version) ] - def check_images(self, version): - docker_client = docker.APIClient(**docker.utils.kwargs_from_env()) - + def check_images(self): for name in self.image_names: try: - docker_client.inspect_image(name) + self.docker_client.inspect_image(name) except docker.errors.ImageNotFound: print('Expected image {} was not found'.format(name)) return False return True def push_images(self): - docker_client = docker.APIClient(**docker.utils.kwargs_from_env()) - for name in self.image_names: print('Pushing {} to Docker Hub'.format(name)) - logstream = docker_client.push(name, stream=True, decode=True) + logstream = self.docker_client.push(name, stream=True, decode=True) for chunk in logstream: if 'status' in chunk: print(chunk['status'])