diff --git a/openstack_releases/cmds/new_release.py b/openstack_releases/cmds/new_release.py index abdb2cde62..1c80cf7874 100644 --- a/openstack_releases/cmds/new_release.py +++ b/openstack_releases/cmds/new_release.py @@ -85,6 +85,30 @@ def increment_milestone_version(old_version, release_type): return new_version_parts +def get_last_release(deliverable_info, series, deliverable, release_type): + try: + last_release = deliverable_info['releases'][-1] + except (KeyError, IndexError): + print('No releases for %s in %s, yet.' % ( + deliverable, series)) + if release_type == 'bugfix': + raise RuntimeError( + 'The first release for a series must ' + 'be at least a feature release to allow ' + 'for stable releases from the previous series.') + # Look for the version of the previous series. + all_series = sorted(os.listdir('deliverables')) + prev_series = all_series[all_series.index(series) - 1] + try: + prev_info = get_deliverable_data( + prev_series, deliverable) + last_release = prev_info['releases'][-1] + except (IOError, OSError, KeyError) as e: + raise RuntimeError( + 'Could not determine previous version: %s' % (e,)) + return last_release + + def main(): parser = argparse.ArgumentParser() parser.add_argument( @@ -144,28 +168,17 @@ def main(): except (IOError, OSError) as e: parser.error(e) - # Determine the new version number. try: - last_release = deliverable_info['releases'][-1] - except KeyError: - print('No releases for %s in %s, yet.' % ( - args.deliverable, series)) - if args.release_type == 'bugfix': - parser.error( - 'The first release for a series must ' - 'be at least a feature release to allow ' - 'for stable releases from the previous series.') - # Look for the version of the previous series. - all_series = sorted(os.listdir('deliverables')) - prev_series = all_series[all_series.index(series) - 1] - try: - prev_info = get_deliverable_data( - prev_series, args.deliverable) - last_release = prev_info['releases'][-1] - deliverable_info['releases'] = [] - except (IOError, OSError, KeyError) as e: - parser.error('Could not determine previous version: %s' % (e,)) + last_release = get_last_release( + deliverable_info, + series, + args.deliverable, + args.release_type, + ) + except RuntimeError as err: + parser.error(err) last_version = last_release['version'].split('.') + first_rc = False if args.release_type in ('milestone', 'rc'): force_tag = True @@ -188,6 +201,9 @@ def main(): new_version_parts = increment_version(last_version, increment) new_version = '.'.join(new_version_parts) + if 'releases' not in deliverable_info: + deliverable_info['releases'] = [] + print('going from %s to %s' % (last_version, new_version)) projects = [] diff --git a/openstack_releases/tests/test_new_release.py b/openstack_releases/tests/test_new_release.py index bfe75fc858..c29cbaeab3 100644 --- a/openstack_releases/tests/test_new_release.py +++ b/openstack_releases/tests/test_new_release.py @@ -18,6 +18,8 @@ from oslotest import base from openstack_releases.cmds import new_release +import fixtures + class TestIncrementVersion(base.BaseTestCase): @@ -113,3 +115,133 @@ class TestIncrementMilestoneVersion(base.BaseTestCase): 'rc', ), ) + + +class TestGetLastRelease(base.BaseTestCase): + + def test_existing_releases(self): + deliverable_info = { + 'releases': [ + {'version': '1.0.0'}, + ], + } + self.assertEqual( + {'version': '1.0.0'}, + new_release.get_last_release( + deliverable_info, + 'anyseries', + 'anydeliverable', + 'bugfix', + ) + ) + + def test_existing_releases2(self): + deliverable_info = { + 'releases': [ + {'version': '1.0.0'}, + {'version': '1.0.1'}, + ], + } + self.assertEqual( + {'version': '1.0.1'}, + new_release.get_last_release( + deliverable_info, + 'anyseries', + 'anydeliverable', + 'bugfix', + ) + ) + + def test_first_bugfix_is_error(self): + deliverable_info = { + 'releases': [], + } + self.assertRaises( + RuntimeError, + new_release.get_last_release, + deliverable_info, + 'anyseries', + 'anydeliverable', + 'bugfix', + ) + + +class TestGetLastReleaseFirstInSeries(base.BaseTestCase): + + def setUp(self): + super(TestGetLastReleaseFirstInSeries, self).setUp() + # Avoid scanning the filesystem to find the release series. + listdir = self.useFixture(fixtures.MockPatch('os.listdir')).mock + listdir.return_value = [ + 'olderseries', + 'anyseries', + 'newerseries', + ] + # When we look for the previous series data, return a valid + # set of info. + gdd = self.useFixture( + fixtures.MockPatchObject(new_release, 'get_deliverable_data') + ).mock + gdd.return_value = { + 'releases': [ + {'version': '1.0.1'}, + ], + } + + def test_empty_release_list(self): + deliverable_info = { + 'releases': [], + } + self.assertEqual( + {'version': '1.0.1'}, + new_release.get_last_release( + deliverable_info, + 'anyseries', + 'anydeliverable', + 'feature', + ) + ) + + def test_first_in_series_keyerror(self): + deliverable_info = { + } + self.assertEqual( + {'version': '1.0.1'}, + new_release.get_last_release( + deliverable_info, + 'anyseries', + 'anydeliverable', + 'feature', + ) + ) + + +class TestGetLastReleaseFirstEver(base.BaseTestCase): + + def setUp(self): + super(TestGetLastReleaseFirstEver, self).setUp() + # Avoid scanning the filesystem to find the release series. + listdir = self.useFixture(fixtures.MockPatch('os.listdir')).mock + listdir.return_value = [ + 'olderseries', + 'anyseries', + 'newerseries', + ] + # When we look for the previous series data, return no + # information. + gdd = self.useFixture( + fixtures.MockPatchObject(new_release, 'get_deliverable_data') + ).mock + gdd.side_effect = IOError('test error') + + def test_no_previous_release(self): + deliverable_info = { + } + self.assertRaises( + RuntimeError, + new_release.get_last_release, + deliverable_info, + 'anyseries', + 'anydeliverable', + 'bugfix', + )