provide a tool to import existing stable branch info

Find the versions for which the stable branches were created and update
the deliverable files with the historical info.

Change-Id: Idb233e0ec78f2b7ea0f07d596d6452786f725315
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2016-12-02 14:55:53 -05:00
parent e97e7707d9
commit d4dfecad2f
3 changed files with 208 additions and 2 deletions

View File

@ -15,6 +15,7 @@
"""
import collections
import copy
import glob
import os
@ -188,6 +189,10 @@ class Deliverable(object):
self.series = series
self.name = name
self._data = data
self.repos = set()
for r in self.releases:
for p in r['projects']:
self.repos.add(p['repo'])
@property
def model(self):
@ -205,7 +210,7 @@ class Deliverable(object):
@property
def latest_release(self):
rel = self._data.get('releases', [{}])[0]
rel = (self.releases or [{}])[0]
return rel.get('version')
@property
@ -216,9 +221,13 @@ class Deliverable(object):
def versions(self):
return [
r['version']
for r in self._data.get('releases', [])
for r in self.releases
]
@property
def releases(self):
return copy.deepcopy(self._data.get('releases', []))
def get_branch_location(self, name):
branches = self._data.get('branches', [])
for b in branches:

173
tools/discover_branch_points.py Executable file
View File

@ -0,0 +1,173 @@
#!/usr/bin/env python
#
# 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.
from __future__ import print_function
import argparse
import atexit
import os.path
import shutil
import subprocess
import sys
import tempfile
import openstack_releases
from openstack_releases import deliverable
def _get_current_version(reporoot, branch=None):
"""Return the current version of the repository.
If the repo appears to contain a python project, use setup.py to
get the version so pbr (if used) can do its thing. Otherwise, use
git describe.
"""
cmd = ['git', 'describe', '--tags']
if branch is not None:
cmd.append(branch)
try:
result = subprocess.check_output(cmd, cwd=reporoot).strip()
if '-' in result:
# Descriptions that come after a commit look like
# 2.0.0-1-abcde, and we want to remove the SHA value from
# the end since we only care about the version number
# itself, but we need to recognize that the change is
# unreleased so keep the -1 part.
result, dash, ignore = result.rpartition('-')
except subprocess.CalledProcessError:
# This probably means there are no tags.
result = '0.0.0'
return result
def _get_branch_base(reporoot, branch):
"Return the tag at base of the branch."
# Based on
# http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git
# git rev-list $(git rev-list --first-parent \
# ^origin/stable/newton master | tail -n1)^^!
#
# Determine the list of commits accessible from the branch we are
# supposed to be scanning, but not on master.
cmd = [
'git',
'rev-list',
'--first-parent',
branch, # on the branch
'^master', # not on master
]
try:
parents = subprocess.check_output(
cmd, cwd=reporoot,
# Trap stderr so it isn't dumped into our output.
stderr=subprocess.PIPE,
).strip()
if not parents:
# There are no commits on the branch, yet, so we can use
# our current-version logic.
return _get_current_version(reporoot, branch)
except subprocess.CalledProcessError:
return None
parent = parents.splitlines()[-1]
# Now get the previous commit, which should be the one we tagged
# to create the branch.
cmd = [
'git',
'rev-list',
'{}^^!'.format(parent),
]
try:
sha = subprocess.check_output(cmd, cwd=reporoot).strip()
except subprocess.CalledProcessError:
return None
# Now get the tag for that commit.
cmd = [
'git',
'describe',
'--abbrev=0',
sha,
]
try:
return subprocess.check_output(cmd, cwd=reporoot).strip()
except subprocess.CalledProcessError:
return None
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--deliverables-dir',
default=openstack_releases.deliverable_dir,
help='location of deliverable files',
)
parser.add_argument(
'--no-cleanup',
dest='cleanup',
default=True,
action='store_false',
help='do not remove temporary files',
)
parser.add_argument(
'repository_cache',
help='location of existing copies of repositories',
)
parser.add_argument(
'series',
help='the release series, such as "newton" or "ocata"',
)
args = parser.parse_args()
workdir = tempfile.mkdtemp(prefix='releases-')
def cleanup_workdir():
if args.cleanup:
try:
shutil.rmtree(workdir)
except:
pass
atexit.register(cleanup_workdir)
branch_name = 'origin/stable/' + args.series
all_deliv = deliverable.Deliverables(
root_dir=args.deliverables_dir,
collapse_history=False,
)
for entry in all_deliv.get_deliverables(None, args.series):
deliv = deliverable.Deliverable(*entry)
if deliv.get_branch_location(branch_name) is not None:
# the branch is already defined for this project
sys.stderr.write('{} already has a branch {}\n'.format(
deliv.name, branch_name))
continue
# We're only importing stable branches, and those are
# specified by the version number. We therefore only need one
# repository, and it shouldn't matter which one. That said, we
# might not actually find the branch in the first repo so loop
# until we do.
for r in deliv.repos:
reporoot = os.path.join(args.repository_cache, r)
version = _get_branch_base(reporoot, branch_name)
if version:
print(deliv.name, args.series, version)
break
else:
sys.stderr.write('could not find {} in any repos for {}\n'.format(
branch_name, deliv.name))
if __name__ == '__main__':
main()

24
tools/import_branch_points.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
#
# 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.
TOOLSDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
$TOOLSDIR/discover_branch_points.py $@ \
| while read deliverable series version; do
echo $deliverable $series $version
fname=deliverables/$series/${deliverable}.yaml
sed -i '' -e "/^releases:/ ibranches:\n - name: stable/${series}\n location: $version" $fname
done