add validation rule to check tarball-base

We don't want to take the time to check out all of the source code for
all projects during the documentation build, so add a validation step to
check that the deliverable being modified has the tarball-base value set
properly, if it needs to be overridden from the default.

Change-Id: Id39bdd1e0a9fe771b78a053ba73803c3c095f135
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2016-12-16 15:48:06 -05:00
parent 4305adb190
commit 32e9f4d7cc
3 changed files with 175 additions and 1 deletions

View File

@ -37,6 +37,7 @@ from openstack_releases import defaults
from openstack_releases import gitutils
from openstack_releases import governance
from openstack_releases import project_config
from openstack_releases import pythonutils
from openstack_releases import versionutils
urllib3.disable_warnings()
@ -62,6 +63,8 @@ _VALID_BRANCH_PREFIXES = set([
'feature',
'driverfixes',
])
_PLEASE = ('It is too expensive to determine this value during '
'the site build, please set it explicitly.')
def is_a_hash(val):
@ -224,6 +227,31 @@ def validate_releases(deliverable_info, zuul_layout,
# No point in running extra checks if the SHA just
# doesn't exist.
continue
# Ensure we have a local copy of the repository so we
# can scan for values that are more difficult to get
# remotely.
gitutils.clone_repo(workdir, project['repo'])
# Check that the sdist name and tarball-base name match.
sdist = pythonutils.get_sdist_name(workdir, project['repo'])
if sdist is not None:
expected = project.get(
'tarball-base',
os.path.basename(project['repo']),
)
if sdist != expected:
if 'tarball-base' in deliverable_info:
action = 'is set to'
else:
action = 'defaults to'
mk_error(
('tarball-base for %s %s %s %r '
'but the sdist name is actually %r. ' +
_PLEASE)
% (project['repo'], release['version'],
action, expected, sdist))
# Report if the version has already been
# tagged. We expect it to not exist, but neither
# case is an error because sometimes we want to
@ -232,7 +260,6 @@ def validate_releases(deliverable_info, zuul_layout,
version_exists = gitutils.tag_exists(
project['repo'], release['version'],
)
gitutils.clone_repo(workdir, project['repo'])
if version_exists:
actual_sha = gitutils.sha_for_tag(
workdir,
@ -331,6 +358,7 @@ def validate_releases(deliverable_info, zuul_layout,
def validate_new_releases(deliverable_info, filename,
team_data,
mk_warning, mk_error):
"""Apply validation rules that only apply to the current series.
"""
if not deliverable_info.get('releases'):

View File

@ -0,0 +1,32 @@
# 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.
import os
import os.path
import subprocess
def get_sdist_name(workdir, repo):
"Check out the code."
dest = os.path.join(workdir, repo)
if not os.path.exists(os.path.join(dest, 'setup.py')):
# Not a python project
return None
cmd = ['python', 'setup.py', '--name']
# Run it once and discard the result to ensure any setup_requires
# dependencies are installed.
subprocess.check_output(cmd, cwd=dest)
# Run it again to get a clean version of the name.
name = subprocess.check_output(cmd, cwd=dest).strip()
return name

View File

@ -624,6 +624,120 @@ class TestValidateReleases(base.BaseTestCase):
self.assertEqual(0, len(errors))
class TestValidateTarballBase(base.BaseTestCase):
def setUp(self):
super(TestValidateTarballBase, self).setUp()
self.tmpdir = self.useFixture(fixtures.TempDir()).path
@mock.patch('openstack_releases.pythonutils.get_sdist_name')
def test_default_ok(self, gsn):
deliverable_info = {
'artifact-link-mode': 'none',
'releases': [
{'version': '1.5.0',
'projects': [
{'repo': 'openstack/automaton',
'hash': 'be2885f544637e6ee6139df7dc7bf937925804dd'},
]}
],
}
warnings = []
errors = []
gsn.return_value = 'automaton'
validate.validate_releases(
deliverable_info,
{'validate-projects-by-name': {}},
'ocata',
self.tmpdir,
warnings.append,
errors.append,
)
self.assertEqual(0, len(warnings))
self.assertEqual(0, len(errors))
@mock.patch('openstack_releases.pythonutils.get_sdist_name')
def test_default_invalid(self, gsn):
deliverable_info = {
'artifact-link-mode': 'none',
'releases': [
{'version': '1.5.0',
'projects': [
{'repo': 'openstack/automaton',
'hash': 'be2885f544637e6ee6139df7dc7bf937925804dd'},
]}
],
}
warnings = []
errors = []
gsn.return_value = 'automaton1'
validate.validate_releases(
deliverable_info,
{'validate-projects-by-name': {}},
'ocata',
self.tmpdir,
warnings.append,
errors.append,
)
self.assertEqual(0, len(warnings))
self.assertEqual(1, len(errors))
@mock.patch('openstack_releases.pythonutils.get_sdist_name')
def test_explicit_ok(self, gsn):
deliverable_info = {
'artifact-link-mode': 'none',
'releases': [
{'version': '1.5.0',
'projects': [
{'repo': 'openstack/automaton',
'hash': 'be2885f544637e6ee6139df7dc7bf937925804dd',
'tarball-base': 'automaton1'},
]}
],
}
warnings = []
errors = []
gsn.return_value = 'automaton1'
validate.validate_releases(
deliverable_info,
{'validate-projects-by-name': {}},
'ocata',
self.tmpdir,
warnings.append,
errors.append,
)
self.assertEqual(0, len(warnings))
self.assertEqual(0, len(errors))
@mock.patch('openstack_releases.pythonutils.get_sdist_name')
def test_explicit_invalid(self, gsn):
deliverable_info = {
'artifact-link-mode': 'none',
'releases': [
{'version': '1.5.0',
'projects': [
{'repo': 'openstack/automaton',
'hash': 'be2885f544637e6ee6139df7dc7bf937925804dd',
'tarball-base': 'does-not-match-sdist'},
]}
],
}
warnings = []
errors = []
gsn.return_value = 'automaton'
validate.validate_releases(
deliverable_info,
{'validate-projects-by-name': {}},
'ocata',
self.tmpdir,
warnings.append,
errors.append,
)
print(warnings, errors)
self.assertEqual(0, len(warnings))
self.assertEqual(1, len(errors))
class TestValidateNewReleases(base.BaseTestCase):
team_data_yaml = textwrap.dedent("""