try to validate the starting points for branches
Apply rules about where we expect branches to be created, when we know. Also try to report errors in a way that makes it clear that updating the branch settings after a branch has been created is invalid. Change-Id: I04befc1f3b0196ee2693bab5c61c399096c301a9 Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
committed by
Sean McGinnis
parent
1305c6a975
commit
91f5f51f48
@@ -1055,6 +1055,104 @@ def validate_driverfixes_branches(deliverable_info,
|
|||||||
_require_gitreview(workdir, repo, mk_error)
|
_require_gitreview(workdir, repo, mk_error)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_branch_points(deliverable_info,
|
||||||
|
deliverable_name,
|
||||||
|
workdir,
|
||||||
|
mk_warning,
|
||||||
|
mk_error):
|
||||||
|
# Make sure the branch points given are on the expected branches.
|
||||||
|
|
||||||
|
known_releases = {
|
||||||
|
r['version']: r
|
||||||
|
for r in deliverable_info.get('releases', [])
|
||||||
|
}
|
||||||
|
branch_mode = deliverable_info.get('stable-branch-type', 'std')
|
||||||
|
|
||||||
|
for branch in deliverable_info.get('branches', []):
|
||||||
|
header('Validate Branch Points: {}'.format(branch['name']))
|
||||||
|
try:
|
||||||
|
prefix, series = branch['name'].split('/')
|
||||||
|
except ValueError:
|
||||||
|
print('could not parse the branch name, skipping')
|
||||||
|
continue
|
||||||
|
|
||||||
|
if prefix == 'feature':
|
||||||
|
print('rule does not apply to feature branches')
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif prefix == 'stable':
|
||||||
|
expected = set([
|
||||||
|
'master',
|
||||||
|
branch['name'],
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
# driverfixes
|
||||||
|
expected = set([
|
||||||
|
branch['name'],
|
||||||
|
'stable/' + series,
|
||||||
|
])
|
||||||
|
|
||||||
|
if prefix == 'stable' and branch_mode == 'std':
|
||||||
|
# location is a version string, so we need to build the
|
||||||
|
# map ourselves
|
||||||
|
print('using hashes from release {}'.format(branch['location']))
|
||||||
|
release = known_releases[branch['location']]
|
||||||
|
location = {
|
||||||
|
p['repo']: p['hash']
|
||||||
|
for p in release['projects']
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
location = branch['location']
|
||||||
|
|
||||||
|
for repo, hash in sorted(location.items()):
|
||||||
|
print('\n{}'.format(repo))
|
||||||
|
existing_branches = sorted([
|
||||||
|
(b.partition('/origin/')[-1]
|
||||||
|
if b.startswith('remotes/origin/')
|
||||||
|
else b)
|
||||||
|
for b in gitutils.get_branches(workdir, repo)
|
||||||
|
])
|
||||||
|
|
||||||
|
# Remove the remote name prefix if it is present in the
|
||||||
|
# branch name.
|
||||||
|
containing = set(
|
||||||
|
c.partition('/')[-1] if c.startswith('origin/') else c
|
||||||
|
for c in gitutils.branches_containing(
|
||||||
|
workdir, repo, hash)
|
||||||
|
)
|
||||||
|
|
||||||
|
print('found {} on branches {} in {}'.format(
|
||||||
|
hash, containing, repo))
|
||||||
|
|
||||||
|
for missing in expected.difference(containing):
|
||||||
|
if missing not in existing_branches:
|
||||||
|
print('branch {} does not exist in {}, skipping'.format(
|
||||||
|
branch['name'], repo))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if branch['name'] in existing_branches:
|
||||||
|
# The branch already exists but there is something
|
||||||
|
# wrong with the specification. This probably
|
||||||
|
# means someone tried to update the branch setting
|
||||||
|
# after creating the branch, so phrase the error
|
||||||
|
# message to reflect that.
|
||||||
|
mk_error(
|
||||||
|
'{} branch exists in {} and does not seem '
|
||||||
|
'to have been created from {}'.format(
|
||||||
|
branch['name'], repo, hash),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# The branch does not exist and the proposed point
|
||||||
|
# to create it is not on the expected source
|
||||||
|
# branch, so phrase the error message to reflect
|
||||||
|
# that.
|
||||||
|
mk_error(
|
||||||
|
'commit {} is not on the {} branch '
|
||||||
|
'but it is listed as the branch point for '
|
||||||
|
'{} to be created'.format(
|
||||||
|
hash, missing, branch['name']))
|
||||||
|
|
||||||
|
|
||||||
# if the branch already exists, the name is by definition valid
|
# if the branch already exists, the name is by definition valid
|
||||||
# if the branch exists, the data in the map must match reality
|
# if the branch exists, the data in the map must match reality
|
||||||
#
|
#
|
||||||
@@ -1231,6 +1329,13 @@ def main():
|
|||||||
mk_warning,
|
mk_warning,
|
||||||
mk_error,
|
mk_error,
|
||||||
)
|
)
|
||||||
|
validate_branch_points(
|
||||||
|
deliverable_info,
|
||||||
|
deliverable_name,
|
||||||
|
workdir,
|
||||||
|
mk_warning,
|
||||||
|
mk_error,
|
||||||
|
)
|
||||||
|
|
||||||
header('Summary')
|
header('Summary')
|
||||||
|
|
||||||
|
|||||||
@@ -2418,3 +2418,84 @@ class TestGuessDeliverableType(base.BaseTestCase):
|
|||||||
{},
|
{},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestValidateBranchPoints(base.BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestValidateBranchPoints, self).setUp()
|
||||||
|
self.tmpdir = self.useFixture(fixtures.TempDir()).path
|
||||||
|
gitutils.clone_repo(self.tmpdir, 'openstack/release-test')
|
||||||
|
|
||||||
|
def test_branch_does_not_exist(self):
|
||||||
|
deliverable_data = textwrap.dedent('''
|
||||||
|
releases:
|
||||||
|
- version: 0.0.3
|
||||||
|
projects:
|
||||||
|
- repo: openstack/release-test
|
||||||
|
hash: 0cd17d1ee3b9284d36b2a0d370b49a6f0bbb9660
|
||||||
|
branches:
|
||||||
|
- name: stable/ocata
|
||||||
|
location: 0.0.3
|
||||||
|
''')
|
||||||
|
warnings = []
|
||||||
|
errors = []
|
||||||
|
deliverable_info = yamlutils.loads(deliverable_data)
|
||||||
|
validate.validate_branch_points(
|
||||||
|
deliverable_info,
|
||||||
|
'name',
|
||||||
|
self.tmpdir,
|
||||||
|
warnings.append,
|
||||||
|
errors.append,
|
||||||
|
)
|
||||||
|
self.assertEqual(0, len(warnings))
|
||||||
|
self.assertEqual(0, len(errors))
|
||||||
|
|
||||||
|
def test_branch_is_correct(self):
|
||||||
|
deliverable_data = textwrap.dedent('''
|
||||||
|
releases:
|
||||||
|
- version: 0.8.0
|
||||||
|
projects:
|
||||||
|
- repo: openstack/release-test
|
||||||
|
hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
|
||||||
|
branches:
|
||||||
|
- name: stable/newton
|
||||||
|
location: 0.8.0
|
||||||
|
''')
|
||||||
|
warnings = []
|
||||||
|
errors = []
|
||||||
|
deliverable_info = yamlutils.loads(deliverable_data)
|
||||||
|
validate.validate_branch_points(
|
||||||
|
deliverable_info,
|
||||||
|
'name',
|
||||||
|
self.tmpdir,
|
||||||
|
warnings.append,
|
||||||
|
errors.append,
|
||||||
|
)
|
||||||
|
self.assertEqual(0, len(warnings))
|
||||||
|
self.assertEqual(0, len(errors))
|
||||||
|
|
||||||
|
def test_branch_moved(self):
|
||||||
|
deliverable_data = textwrap.dedent('''
|
||||||
|
releases:
|
||||||
|
- version: 0.12.0
|
||||||
|
projects:
|
||||||
|
- repo: openstack/release-test
|
||||||
|
hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
|
||||||
|
branches:
|
||||||
|
- name: stable/meiji
|
||||||
|
location: 0.12.0 # this comes after the meiji branch
|
||||||
|
# was created at 0.0.2
|
||||||
|
''')
|
||||||
|
warnings = []
|
||||||
|
errors = []
|
||||||
|
deliverable_info = yamlutils.loads(deliverable_data)
|
||||||
|
validate.validate_branch_points(
|
||||||
|
deliverable_info,
|
||||||
|
'name',
|
||||||
|
self.tmpdir,
|
||||||
|
warnings.append,
|
||||||
|
errors.append,
|
||||||
|
)
|
||||||
|
self.assertEqual(0, len(warnings))
|
||||||
|
self.assertEqual(1, len(errors))
|
||||||
|
|||||||
Reference in New Issue
Block a user