if both tag and sha exist, make sure they match

Update the validate command to compare the actual SHA of a tag with the
one in the file to ensure they match.

Change-Id: I5c04667cbb43cda548c3cc05a47d5a5830b32951
This commit is contained in:
Doug Hellmann
2015-08-04 17:15:08 +00:00
parent 11efe9f296
commit 17ad4a9bd3
2 changed files with 85 additions and 10 deletions

View File

@@ -19,8 +19,11 @@
from __future__ import print_function
import argparse
import atexit
import glob
import re
import shutil
import tempfile
import requests
import yaml
@@ -40,6 +43,13 @@ def is_a_hash(val):
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--no-cleanup',
dest='cleanup',
default=True,
action='store_false',
help='do not remove temporary files',
)
parser.add_argument(
'input',
nargs='*',
@@ -56,6 +66,19 @@ def main():
errors = []
workdir = tempfile.mkdtemp(prefix='releases-')
print('creating temporary files in %s' % workdir)
def cleanup_workdir():
if args.cleanup:
try:
shutil.rmtree(workdir)
except:
pass
else:
print('not cleaning up %s' % workdir)
atexit.register(cleanup_workdir)
for filename in filenames:
print('\nChecking %s' % filename)
with open(filename, 'r') as f:
@@ -78,9 +101,8 @@ def main():
for release in deliverable_info['releases']:
for project in release['projects']:
print('%s %s %s ' % (project['repo'],
release['version'],
project['hash']),
print('%s SHA %s ' % (project['repo'],
project['hash']),
end='')
if not is_a_hash(project['hash']):
@@ -90,15 +112,45 @@ def main():
'%(hash)r, which is not a hash') % project
)
else:
exists = gitutils.commit_exists(
# Report if the SHA exists or not (an error if it
# does not).
sha_exists = gitutils.commit_exists(
project['repo'], project['hash'],
)
if not exists:
print('MISSING')
if not sha_exists:
print('MISSING', end='')
errors.append('No commit %(hash)r in %(repo)r'
% project)
else:
print('found')
print('found ', end='')
# 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
# import history and sometimes we want to make new
# releases.
print('version %s ' % release['version'], end='')
version_exists = gitutils.commit_exists(
project['repo'], release['version'],
)
if version_exists:
actual_sha = gitutils.sha_for_tag(
workdir,
project['repo'],
release['version'],
)
if actual_sha == project['hash']:
print('found and matches SHA')
else:
print('found DIFFERENT %r' % actual_sha)
errors.append(
('Version %s in %s is on '
'commit %s instead of %s') %
(release['version'],
project['repo'],
actual_sha,
project['hash']))
else:
print('NEW')
if errors:
print('\n%s errors found' % len(errors))

View File

@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import os.path
import subprocess
import requests
@@ -36,18 +37,40 @@ def find_modified_deliverable_files():
return filenames
def commit_exists(repo, hash):
"""Return boolean specifying whether the hash exists in the repository.
def commit_exists(repo, ref):
"""Return boolean specifying whether the reference exists in the repository.
Uses a cgit query instead of looking locally to avoid cloning a
repository or having Depends-On settings in a commit message allow
someone to fool the check.
"""
url = CGIT_TEMPLATE % (repo, hash)
url = CGIT_TEMPLATE % (repo, ref)
response = requests.get(url)
missing_commit = (
(response.status_code // 100 != 2)
or 'Bad object id' in response.text
)
return not missing_commit
def sha_for_tag(workdir, repo, version):
"""Return the SHA for a given tag
"""
# Check out the code.
subprocess.check_call(
['zuul-cloner',
'--workspace', workdir,
'git://git.openstack.org',
repo]
)
# git log 2.3.11 -n 1 --pretty=format:%H
try:
actual_sha = subprocess.check_output(
['git', 'log', str(version), '-n', '1', '--pretty=format:%H'],
cwd=os.path.join(workdir, repo),
)
actual_sha = actual_sha.strip()
except subprocess.CalledProcessError:
actual_sha = ''
return actual_sha