Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add images build step and finalize placeholder
Signed-off-by: Joffrey F <[email protected]>
  • Loading branch information
shin- committed Apr 19, 2018
commit e9f6abf8f4c6de2295b28df25dd01a46b60a0741
116 changes: 96 additions & 20 deletions script/release/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

import argparse
import os
import shutil
import sys
import time

import docker
from jinja2 import Template
from release.bintray import BintrayAPI
from release.const import BINTRAY_ORG
Expand Down Expand Up @@ -77,6 +79,15 @@ def monitor_pr_status(pr_data):
raise ScriptError('CI failure detected')


def check_pr_mergeable(pr_data):
if not pr_data.mergeable:
print(
'WARNING!! PR #{} can not currently be merged. You will need to '
'resolve the conflicts manually before finalizing the release.'.format(pr_data.number)
)
return pr_data.mergeable


def create_release_draft(repository, version, pr_data, files):
print('Creating Github release draft')
with open(os.path.join(os.path.dirname(__file__), 'release.md.tmpl'), 'r') as f:
Expand All @@ -97,13 +108,51 @@ def create_release_draft(repository, version, pr_data, files):
return gh_release


def print_final_instructions(gh_release):
print("""
You're almost done! The following steps should be executed after you've
verified that everything is in order and are ready to make the release public:
1.
2.
3.""")
def build_images(repository, files, version):
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)
print('Building docker/compose image')
logstream = docker_client.build(
REPO_ROOT, tag='docker/compose:{}'.format(version), dockerfile='Dockerfile.run',
decode=True
)
for chunk in logstream:
if 'error' in chunk:
raise ScriptError('Build error: {}'.format(chunk['error']))
if 'stream' in chunk:
print(chunk['stream'], end='')

print('Building test image (for UCP e2e)')
logstream = docker_client.build(
REPO_ROOT, tag='docker-compose-tests:tmp', decode=True
)
for chunk in logstream:
if 'error' in chunk:
raise ScriptError('Build error: {}'.format(chunk['error']))
if 'stream' in chunk:
print(chunk['stream'], end='')

container = 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(version))
docker_client.remove_container(container, force=True)
docker_client.remove_image('docker-compose-tests:tmp', force=True)


def print_final_instructions(args):
print(
"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
)
)


def resume(args):
Expand All @@ -117,6 +166,7 @@ def resume(args):
pr_data = repository.find_release_pr(args.release)
if not pr_data:
pr_data = repository.create_release_pull_request(args.release)
check_pr_mergeable(pr_data)
monitor_pr_status(pr_data)
downloader = BinaryDownloader(args.destination)
files = downloader.download_all(args.release)
Expand All @@ -133,11 +183,12 @@ def resume(args):
raise ScriptError('Aborting release')
delete_assets(gh_release)
upload_assets(gh_release, files)
build_images(repository, files, args.release)
except ScriptError as e:
print(e)
return 1

print_final_instructions(gh_release)
print_final_instructions(args)
return 0


Expand All @@ -163,19 +214,50 @@ def start(args):
repository = Repository(REPO_ROOT, args.repo or NAME)
create_initial_branch(repository, args.release, args.base, args.bintray_user)
pr_data = repository.create_release_pull_request(args.release)
check_pr_mergeable(pr_data)
monitor_pr_status(pr_data)
downloader = BinaryDownloader(args.destination)
files = downloader.download_all(args.release)
gh_release = create_release_draft(repository, args.release, pr_data, files)
upload_assets(gh_release, files)
build_images(repository, files, args.release)
except ScriptError as e:
print(e)
return 1

print_final_instructions(args)
return 0


def finalize(args):
try:
raise NotImplementedError()
except ScriptError as e:
print(e)
return 1

print_final_instructions(gh_release)
return 0


ACTIONS = [
'start',
'cancel',
'resume',
'finalize',
]

EPILOG = '''Example uses:
* Start a new feature release (includes all changes currently in master)
release.py -b user start 1.23.0
* Start a new patch release
release.py -b user --patch 1.21.0 start 1.21.1
* Cancel / rollback an existing release draft
release.py -b user cancel 1.23.0
* Restart a previously aborted patch release
release.py -b user -p 1.21.0 resume 1.21.1
'''


def main():
if 'GITHUB_TOKEN' not in os.environ:
print('GITHUB_TOKEN environment variable must be set')
Expand All @@ -189,18 +271,9 @@ def main():
description='Orchestrate a new release of docker/compose. This tool assumes that you have '
'obtained a Github API token and Bintray API key and set the GITHUB_TOKEN and '
'BINTRAY_TOKEN environment variables accordingly.',
epilog='''Example uses:
* Start a new feature release (includes all changes currently in master)
release.py -b user start 1.23.0
* Start a new patch release
release.py -b user --patch 1.21.0 start 1.21.1
* Cancel / rollback an existing release draft
release.py -b user cancel 1.23.0
* Restart a previously aborted patch release
release.py -b user -p 1.21.0 resume 1.21.1''', formatter_class=argparse.RawTextHelpFormatter)
epilog=EPILOG, formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument(
'action', choices=['start', 'resume', 'cancel'],
help='The action to be performed for this release'
'action', choices=ACTIONS, help='The action to be performed for this release'
)
parser.add_argument('release', help='Release number, e.g. 1.9.0-rc1, 2.1.1')
parser.add_argument(
Expand All @@ -227,6 +300,9 @@ def main():
return resume(args)
elif args.action == 'cancel':
return cancel(args)
elif args.action == 'finalize':
return finalize(args)

print('Unexpected action "{}"'.format(args.action), file=sys.stderr)
return 1

Expand Down
5 changes: 5 additions & 0 deletions script/release/release/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ def close_release_pr(self, version):
print('No open PR for this release branch.')
return count

def write_git_sha(self):
with open(os.path.join(REPO_ROOT, 'compose', 'GITSHA'), 'w') as f:
f.write(self.git_repo.head.commit.hexsha[:7])


def get_contributors(pr_data):
commits = pr_data.get_commits()
Expand All @@ -175,6 +179,7 @@ def upload_assets(gh_release, files):
print('Uploading {}...'.format(filename))
gh_release.upload_asset(filedata[0], content_type='application/octet-stream')
gh_release.upload_asset('{}.sha256'.format(filedata[0]), content_type='text/plain')
print('Uploading run.sh...')
gh_release.upload_asset(
os.path.join(REPO_ROOT, 'script', 'run', 'run.sh'), content_type='text/plain'
)
Expand Down