Files
releases/openstack_releases/cmds/new_release.py
Amrith Kumar bfb12391b7 only generate new release information, if there is a new release
When running new_release, I've found that it'll generate a new entry
with a new release number and the old sha if there are no intervening
changes. This proposed code will change that behavior and not generate
a new project deliverable file if there is no difference from the
previous one.

I find this useful when I run the new release command for multiple
projects and branches in that if there are no changes to tag, it
generates no output file.

I'm not positive that this change is all good; for example, I don't
know for sure that there are not situations where one would want to
tag a new release even if there are no changes.

Change-Id: I351ada42dde757f29094462b10011ec4f375d465
2016-11-22 10:53:55 -05:00

134 lines
4.0 KiB
Python

# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import argparse
import atexit
import shutil
import tempfile
from openstack_releases import gitutils
import yaml
RELEASE_TEMPLATE = '''
- version: {version}
projects:
'''.lstrip('\n')
PROJECT_TEMPLATE = '''
- repo: {repo}
hash: {hash}
'''.lstrip('\n')
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'series',
help='the name of the release series to scan',
)
parser.add_argument(
'deliverable',
help='the base name of the deliverable file',
)
# FIXME(dhellmann): Add milestone and rc types.
parser.add_argument(
'release_type',
choices=('bugfix', 'feature', 'major'),
help='the type of release to generate',
)
parser.add_argument(
'--no-cleanup',
dest='cleanup',
default=True,
action='store_false',
help='do not remove temporary files',
)
args = parser.parse_args()
workdir = tempfile.mkdtemp(prefix='releases-')
print('creating temporary files in %s' % workdir)
def cleanup_workdir():
if args.cleanup:
try:
shutil.rmtree(workdir)
except:
pass
else:
print('not cleaning up %s' % workdir)
atexit.register(cleanup_workdir)
# Allow for independent projects.
series = args.series
if series.lstrip('_') == 'independent':
series = '_independent'
# Load existing deliverable data.
deliverable_filename = 'deliverables/%s/%s.yaml' % (
series, args.deliverable)
try:
with open(deliverable_filename, 'r') as f:
deliverable_info = yaml.safe_load(f)
except (IOError, OSError) as e:
parser.error(e)
# Determine the new version number.
last_release = deliverable_info['releases'][-1]
last_version = last_release['version'].split('.')
increment = {
'bugfix': (0, 0, 1),
'feature': (0, 1, 0),
'major': (1, 0, 0),
}[args.release_type]
new_version_parts = []
for cur, inc in zip(last_version, increment):
new_version_parts.append(str(int(cur) + inc))
new_version = '.'.join(new_version_parts)
print('going from %s to %s' % (last_version, new_version))
projects = []
changes = 0
for project in last_release['projects']:
gitutils.clone_repo(workdir, project['repo'])
branches = gitutils.get_branches(workdir, project['repo'])
version = 'origin/stable/%s' % series
if not any(branch for branch in branches
if branch.endswith(version)):
version = 'master'
sha = gitutils.sha_for_tag(workdir, project['repo'], version)
if project['hash'] != sha:
changes += 1
print('advancing %s from %s to %s' % (project['repo'],
project['hash'],
sha))
projects.append({
'repo': project['repo'],
'hash': sha,
})
# The YAML dump formatter produces results that aren't very nice
# to read, so we format the output ourselves. The file is only
# regenerated if there are in fact changes to be made.
if changes > 0:
with open(deliverable_filename, 'a') as f:
f.write(RELEASE_TEMPLATE.format(version=new_version))
for p in projects:
f.write(PROJECT_TEMPLATE.format(**p))