Merge "add a validation rule to block new releases based on series status"

This commit is contained in:
Zuul
2018-04-25 20:36:11 +00:00
committed by Gerrit Code Review
4 changed files with 200 additions and 0 deletions

View File

@@ -875,6 +875,51 @@ def validate_new_releases_at_end(deliv, context):
print('OK')
@applies_to_released
def validate_new_releases_in_open_series(deliv, context):
"New releases may only be added to open series."
if deliv.series_info.allows_releases:
print('{} has status {!r} and allows releases'.format(
deliv.series, deliv.series_info.status))
return
LOG.debug('%s has status %r and will not allow releases',
deliv.series, deliv.series_info.status)
# Remember which entries are new so we can verify that they
# appear at the end of the file.
new_releases = {}
for release in deliv.releases:
for project in release.projects:
if not gitutils.safe_clone_repo(context.workdir, project.repo.name,
project.hash, context):
continue
version_exists = gitutils.commit_exists(
context.workdir, project.repo.name, release.version,
)
if version_exists:
print('tag exists, skipping further validation')
continue
LOG.debug('Found new version {} for {}'.format(
release.version, project.repo))
new_releases[release.version] = release
if new_releases:
# The series is closed but there is a new release.
msg = ('series {} has status {!r} '
'and cannot have new releases tagged').format(
deliv.series, deliv.series_info.status)
context.error(msg)
else:
print('OK')
@applies_to_released
def validate_release_branch_membership(deliv, context):
"Commits being tagged need to be on the right branch."
@@ -1471,6 +1516,7 @@ def main():
validate_existing_tags,
validate_version_numbers,
validate_new_releases_at_end,
validate_new_releases_in_open_series,
validate_release_branch_membership,
validate_tarball_base,
validate_new_releases,

View File

@@ -25,6 +25,7 @@ import weakref
import pbr.version
from openstack_releases import governance
from openstack_releases import series_status
from openstack_releases import yamlutils
@@ -330,6 +331,7 @@ class Branch(object):
class Deliverable(object):
_governance_data = None
_series_status_data = None
def __init__(self, team, series, name, data):
self.team = team
@@ -522,6 +524,12 @@ class Deliverable(object):
def cycle_highlights(self):
return self._data.get('cycle-highlights', [])
@property
def series_info(self):
if self._series_status_data is None:
self._series_status_data = series_status.SeriesStatus.default()
return self._series_status_data[self.series]
def __eq__(self, other):
return self.name == other.name

View File

@@ -47,6 +47,10 @@ class Series(object):
def eol_date(self):
return self._data.get('eol-date', None)
@property
def allows_releases(self):
return self.status in ('development', 'maintained')
class SeriesStatus(collections.abc.Mapping):
@@ -59,6 +63,12 @@ class SeriesStatus(collections.abc.Mapping):
raw_data = cls._load_series_status_data(root_dir)
return cls(raw_data)
@classmethod
def default(cls):
module_path = os.path.dirname(__file__)
root_dir = os.path.dirname(module_path)
return cls.from_directory(root_dir)
@staticmethod
def _load_series_status_data(root_dir):
filename = os.path.join(root_dir, 'deliverables', 'series_status.yaml')

View File

@@ -28,6 +28,7 @@ from openstack_releases import defaults
from openstack_releases import deliverable
from openstack_releases import gitutils
from openstack_releases import processutils
from openstack_releases import series_status
from openstack_releases import yamlutils
@@ -1022,6 +1023,141 @@ class TestValidateNewReleasesAtEnd(base.BaseTestCase):
self.assertEqual(1, len(self.ctx.errors))
class TestValidateNewReleasesInOpenSeries(base.BaseTestCase):
_series_status_data = yamlutils.loads(textwrap.dedent('''
- name: rocky
status: development
initial-release: 2018-08-30
- name: queens
status: maintained
initial-release: 2018-02-28
- name: ocata
status: extended maintenance
initial-release: 2017-02-22
- name: newton
status: end of life
initial-release: 2016-10-06
eol-date: 2017-10-25
'''))
def setUp(self):
super().setUp()
self.ctx = validate.ValidationContext()
gitutils.clone_repo(self.ctx.workdir, 'openstack/release-test')
self.series_status = series_status.SeriesStatus(
self._series_status_data)
self.useFixture(fixtures.MockPatch(
'openstack_releases.deliverable.Deliverable._series_status_data',
self.series_status,
))
def test_no_releases(self):
# When we initialize a new series, we won't have any release
# data. That's OK.
deliv = deliverable.Deliverable(
team='team',
series='rocky',
name='name',
data={
'artifact-link-mode': 'none',
'releases': []
}
)
validate.validate_new_releases_in_open_series(deliv, self.ctx)
self.ctx.show_summary()
self.assertEqual(0, len(self.ctx.warnings))
self.assertEqual(0, len(self.ctx.errors))
def test_development(self):
deliv = deliverable.Deliverable(
team='team',
series='rocky',
name='name',
data={
'artifact-link-mode': 'none',
'releases': [
{'version': '10.0.0',
'projects': [
{'repo': 'openstack/release-test',
'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5',
'tarball-base': 'openstack-release-test'},
]},
],
}
)
validate.validate_new_releases_in_open_series(deliv, self.ctx)
self.ctx.show_summary()
self.assertEqual(0, len(self.ctx.warnings))
self.assertEqual(0, len(self.ctx.errors))
def test_maintained(self):
deliv = deliverable.Deliverable(
team='team',
series='queens',
name='name',
data={
'artifact-link-mode': 'none',
'releases': [
{'version': '10.0.0',
'projects': [
{'repo': 'openstack/release-test',
'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5',
'tarball-base': 'openstack-release-test'},
]},
],
}
)
validate.validate_new_releases_in_open_series(deliv, self.ctx)
self.ctx.show_summary()
self.assertEqual(0, len(self.ctx.warnings))
self.assertEqual(0, len(self.ctx.errors))
def test_extended_maintaintenance(self):
deliv = deliverable.Deliverable(
team='team',
series='ocata',
name='name',
data={
'artifact-link-mode': 'none',
'releases': [
{'version': '10.0.0',
'projects': [
{'repo': 'openstack/release-test',
'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5',
'tarball-base': 'openstack-release-test'},
]},
],
}
)
validate.validate_new_releases_in_open_series(deliv, self.ctx)
self.ctx.show_summary()
self.assertEqual(0, len(self.ctx.warnings))
self.assertEqual(1, len(self.ctx.errors))
def test_end_of_life(self):
deliv = deliverable.Deliverable(
team='team',
series='newton',
name='name',
data={
'artifact-link-mode': 'none',
'releases': [
{'version': '10.0.0',
'projects': [
{'repo': 'openstack/release-test',
'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5',
'tarball-base': 'openstack-release-test'},
]},
],
}
)
validate.validate_new_releases_in_open_series(deliv, self.ctx)
self.ctx.show_summary()
self.assertEqual(0, len(self.ctx.warnings))
self.assertEqual(1, len(self.ctx.errors))
class TestValidateVersionNumbers(base.BaseTestCase):
def setUp(self):