update validation to support eol tags
Update the version string validation to allow a series-eol tag. Require that the EOL tag for a deliverable match the series and be applied to all repositories that are part of the deliverable. Extend the Release data object to understand whether its tag is an EOL tag and if so to return the series component from it as eol_series. Story: #2001879 Task: #14344 Change-Id: I40b6822c942b559dc6f18a4b6be6abb5407c4d7c Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
parent
c43e9e483f
commit
be69bc3581
@ -251,6 +251,39 @@ def validate_series_final(deliv, context):
|
||||
print('OK')
|
||||
|
||||
|
||||
@applies_to_released
|
||||
def validate_series_eol(deliv, context):
|
||||
"The EOL tag should be applied to the previous release."
|
||||
|
||||
current_release = deliv.releases[-1]
|
||||
|
||||
if not current_release.is_eol:
|
||||
print('this rule only applies when tagging a series as end-of-life')
|
||||
return
|
||||
|
||||
# The tag should be applied to all of the repositories for the
|
||||
# deliverable.
|
||||
actual_repos = set(p.repo.name for p in current_release.projects)
|
||||
expected_repos = set(r.name for r in deliv.repos)
|
||||
error = False
|
||||
for extra in actual_repos.difference(expected_repos):
|
||||
error = True
|
||||
context.error(
|
||||
'EOL release %s includes repository %s '
|
||||
'that is not in deliverable' %
|
||||
(current_release.version, extra)
|
||||
)
|
||||
for missing in expected_repos.difference(actual_repos):
|
||||
error = True
|
||||
context.error(
|
||||
'release %s is missing %s, '
|
||||
'which appears in the deliverable' %
|
||||
(current_release.version, missing)
|
||||
)
|
||||
if not error:
|
||||
print('OK')
|
||||
|
||||
|
||||
@applies_to_current
|
||||
@applies_to_released
|
||||
@applies_to_cycle
|
||||
@ -786,6 +819,15 @@ def validate_version_numbers(deliv, context):
|
||||
|
||||
LOG.debug('checking {}'.format(release.version))
|
||||
|
||||
if release.is_eol:
|
||||
LOG.debug('Found new EOL tag {} for {}'.format(
|
||||
release.version, deliv.name))
|
||||
if release.eol_series != deliv.series:
|
||||
context.error(
|
||||
'EOL tag {} does not refer to the {} series.'.format(
|
||||
release.version, deliv.series))
|
||||
continue
|
||||
|
||||
for project in release.projects:
|
||||
|
||||
if not gitutils.safe_clone_repo(context.workdir, project.repo.name,
|
||||
@ -958,13 +1000,17 @@ def validate_new_releases_in_open_series(deliv, context):
|
||||
print('tag exists, skipping further validation')
|
||||
continue
|
||||
|
||||
LOG.debug('Found new version {} for {}'.format(
|
||||
release.version, project.repo))
|
||||
new_releases[release.version] = release
|
||||
if release.is_eol:
|
||||
LOG.debug('Found new EOL tag {} for {}'.format(
|
||||
release.version, project.repo))
|
||||
else:
|
||||
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 = ('deliverable {} has status {!r} for {}'
|
||||
msg = ('deliverable {} has status {!r} for {} '
|
||||
'and cannot have new releases tagged').format(
|
||||
deliv.name, deliv.stable_status, deliv.series)
|
||||
context.error(msg)
|
||||
@ -1589,6 +1635,7 @@ def main():
|
||||
validate_series_first,
|
||||
validate_series_final,
|
||||
validate_series_post_final,
|
||||
validate_series_eol,
|
||||
validate_branch_prefixes,
|
||||
validate_stable_branches,
|
||||
validate_feature_branches,
|
||||
|
@ -300,6 +300,16 @@ class Release(object):
|
||||
or 'b' in self.version
|
||||
)
|
||||
|
||||
@property
|
||||
def is_eol(self):
|
||||
return self.version.endswith('-eol')
|
||||
|
||||
@property
|
||||
def eol_series(self):
|
||||
if self.is_eol:
|
||||
return self.version.rpartition('-')[0]
|
||||
return ''
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.version == other.version
|
||||
|
||||
|
@ -79,3 +79,95 @@ class TestReleaseWasForced(base.BaseTestCase):
|
||||
def test_true(self):
|
||||
r = deliverable.Release('version', [], {'flags': ['forced']}, None)
|
||||
self.assertTrue(r.was_forced)
|
||||
|
||||
|
||||
class TestEOLTags(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
def test_is_eol_tag_true(self):
|
||||
deliverable_data = textwrap.dedent('''
|
||||
releases:
|
||||
- version: newton-eol
|
||||
projects:
|
||||
- repo: openstack/release-test
|
||||
hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
|
||||
''')
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='newton',
|
||||
name='name',
|
||||
data=yamlutils.loads(deliverable_data),
|
||||
)
|
||||
self.assertTrue(deliv.releases[-1].is_eol)
|
||||
|
||||
def test_is_eol_tag_false(self):
|
||||
deliverable_data = textwrap.dedent('''
|
||||
releases:
|
||||
- version: 0.3.0
|
||||
projects:
|
||||
- repo: openstack/release-test
|
||||
hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
|
||||
''')
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='newton',
|
||||
name='name',
|
||||
data=yamlutils.loads(deliverable_data),
|
||||
)
|
||||
self.assertFalse(deliv.releases[-1].is_eol)
|
||||
|
||||
def test_is_eol_tag_false_typo(self):
|
||||
deliverable_data = textwrap.dedent('''
|
||||
releases:
|
||||
- version: newton-dol
|
||||
projects:
|
||||
- repo: openstack/release-test
|
||||
hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
|
||||
''')
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='newton',
|
||||
name='name',
|
||||
data=yamlutils.loads(deliverable_data),
|
||||
)
|
||||
self.assertFalse(deliv.releases[-1].is_eol)
|
||||
|
||||
def test_eol_series_for_eol_tag(self):
|
||||
deliverable_data = textwrap.dedent('''
|
||||
releases:
|
||||
- version: newton-eol
|
||||
projects:
|
||||
- repo: openstack/release-test
|
||||
hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
|
||||
''')
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='newton',
|
||||
name='name',
|
||||
data=yamlutils.loads(deliverable_data),
|
||||
)
|
||||
self.assertEqual(
|
||||
'newton',
|
||||
deliv.releases[-1].eol_series,
|
||||
)
|
||||
|
||||
def test_eol_series_for_version_tag(self):
|
||||
deliverable_data = textwrap.dedent('''
|
||||
releases:
|
||||
- version: 0.3.0
|
||||
projects:
|
||||
- repo: openstack/release-test
|
||||
hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
|
||||
''')
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='newton',
|
||||
name='name',
|
||||
data=yamlutils.loads(deliverable_data),
|
||||
)
|
||||
self.assertEqual(
|
||||
'',
|
||||
deliv.releases[-1].eol_series,
|
||||
)
|
||||
|
@ -1157,6 +1157,28 @@ class TestValidateNewReleasesInOpenSeries(base.BaseTestCase):
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(1, len(self.ctx.errors))
|
||||
|
||||
def test_eol_in_end_of_life(self):
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='newton',
|
||||
name='name',
|
||||
data={
|
||||
'artifact-link-mode': 'none',
|
||||
'releases': [
|
||||
{'version': 'newton-eol',
|
||||
'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))
|
||||
|
||||
|
||||
class TestValidateVersionNumbers(base.BaseTestCase):
|
||||
|
||||
@ -1193,6 +1215,69 @@ class TestValidateVersionNumbers(base.BaseTestCase):
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(1, len(self.ctx.errors))
|
||||
|
||||
def test_valid_version(self):
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='ocata',
|
||||
name='name',
|
||||
data={
|
||||
'artifact-link-mode': 'none',
|
||||
'releases': [
|
||||
{'version': '99.5.0',
|
||||
'projects': [
|
||||
{'repo': 'openstack/release-test',
|
||||
'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5'},
|
||||
]}
|
||||
],
|
||||
}
|
||||
)
|
||||
validate.validate_version_numbers(deliv, self.ctx)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(0, len(self.ctx.errors))
|
||||
|
||||
def test_eol_valid_version(self):
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='ocata',
|
||||
name='name',
|
||||
data={
|
||||
'artifact-link-mode': 'none',
|
||||
'releases': [
|
||||
{'version': 'ocata-eol',
|
||||
'projects': [
|
||||
{'repo': 'openstack/release-test',
|
||||
'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5'},
|
||||
]}
|
||||
],
|
||||
}
|
||||
)
|
||||
validate.validate_version_numbers(deliv, self.ctx)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(0, len(self.ctx.errors))
|
||||
|
||||
def test_eol_wrong_branch(self):
|
||||
deliv = deliverable.Deliverable(
|
||||
team='team',
|
||||
series='ocata',
|
||||
name='name',
|
||||
data={
|
||||
'artifact-link-mode': 'none',
|
||||
'releases': [
|
||||
{'version': 'newton-eol',
|
||||
'projects': [
|
||||
{'repo': 'openstack/release-test',
|
||||
'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5'},
|
||||
]}
|
||||
],
|
||||
}
|
||||
)
|
||||
validate.validate_version_numbers(deliv, self.ctx)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(1, len(self.ctx.errors))
|
||||
|
||||
def test_no_releases(self):
|
||||
# When we initialize a new series, we won't have any release
|
||||
# data. That's OK.
|
||||
@ -2926,6 +3011,136 @@ class TestValidateSeriesFinal(base.BaseTestCase):
|
||||
self.assertEqual(1, len(self.ctx.errors))
|
||||
|
||||
|
||||
class TestValidateSeriesEOL(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.tmpdir = self.useFixture(fixtures.TempDir()).path
|
||||
self.ctx = validate.ValidationContext()
|
||||
|
||||
def test_no_releases(self):
|
||||
deliverable_data = yamlutils.loads(textwrap.dedent('''
|
||||
---
|
||||
team: Release Management
|
||||
'''))
|
||||
deliv = deliverable.Deliverable(
|
||||
None,
|
||||
defaults.RELEASE,
|
||||
'test',
|
||||
deliverable_data,
|
||||
)
|
||||
validate.validate_series_eol(
|
||||
deliv,
|
||||
self.ctx,
|
||||
)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(0, len(self.ctx.errors))
|
||||
|
||||
def test_only_normal(self):
|
||||
deliverable_data = yamlutils.loads(textwrap.dedent('''
|
||||
---
|
||||
team: Release Management
|
||||
releases:
|
||||
- version: 1.5.1
|
||||
projects:
|
||||
- repo: openstack/automaton
|
||||
hash: be2885f544637e6ee6139df7dc7bf937925804dd
|
||||
'''))
|
||||
deliv = deliverable.Deliverable(
|
||||
None,
|
||||
defaults.RELEASE,
|
||||
'test',
|
||||
deliverable_data,
|
||||
)
|
||||
validate.validate_series_eol(
|
||||
deliv,
|
||||
self.ctx,
|
||||
)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(0, len(self.ctx.errors))
|
||||
|
||||
def test_no_eol(self):
|
||||
deliverable_data = yamlutils.loads(textwrap.dedent('''
|
||||
---
|
||||
team: Release Management
|
||||
releases:
|
||||
- version: 1.5.1
|
||||
projects:
|
||||
- repo: openstack/automaton
|
||||
hash: be2885f544637e6ee6139df7dc7bf937925804dd
|
||||
- version: 1.5.2
|
||||
projects:
|
||||
- repo: openstack/automaton
|
||||
hash: ce2885f544637e6ee6139df7dc7bf937925804dd
|
||||
'''))
|
||||
deliv = deliverable.Deliverable(
|
||||
None,
|
||||
defaults.RELEASE,
|
||||
'test',
|
||||
deliverable_data,
|
||||
)
|
||||
validate.validate_series_eol(
|
||||
deliv,
|
||||
self.ctx,
|
||||
)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(0, len(self.ctx.errors))
|
||||
|
||||
def test_eol_ok(self):
|
||||
deliverable_data = yamlutils.loads(textwrap.dedent('''
|
||||
---
|
||||
team: Release Management
|
||||
releases:
|
||||
- version: newton-eol
|
||||
projects:
|
||||
- repo: openstack/automaton
|
||||
hash: be2885f544637e6ee6139df7dc7bf937925804dd
|
||||
'''))
|
||||
deliv = deliverable.Deliverable(
|
||||
None,
|
||||
'newton',
|
||||
'test',
|
||||
deliverable_data,
|
||||
)
|
||||
validate.validate_series_eol(
|
||||
deliv,
|
||||
self.ctx,
|
||||
)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(0, len(self.ctx.errors))
|
||||
|
||||
def test_eol_missing_repo(self):
|
||||
deliverable_data = yamlutils.loads(textwrap.dedent('''
|
||||
---
|
||||
team: Release Management
|
||||
releases:
|
||||
- version: newton-eol
|
||||
projects:
|
||||
- repo: openstack/automaton
|
||||
hash: ce2885f544637e6ee6139df7dc7bf937925804dd
|
||||
repository-settings:
|
||||
openstack/automaton: {}
|
||||
openstack/release-test: {}
|
||||
'''))
|
||||
deliv = deliverable.Deliverable(
|
||||
None,
|
||||
'newton',
|
||||
'test',
|
||||
deliverable_data,
|
||||
)
|
||||
validate.validate_series_eol(
|
||||
deliv,
|
||||
self.ctx,
|
||||
)
|
||||
self.ctx.show_summary()
|
||||
self.assertEqual(0, len(self.ctx.warnings))
|
||||
self.assertEqual(1, len(self.ctx.errors))
|
||||
|
||||
|
||||
class TestValidatePostSeriesFinal(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
Loading…
Reference in New Issue
Block a user