spec2bp v2 -- support in-review specs
New version of spec2bp: - takes the project and blueprint name as arguments, instead of a file - supports not-yet-approved specs (use --in-review to set them "Blocked") - sets series goal as well as milestone targets - if the BP and approved spec names don't match, you can use --specpath to specify the spec location - if --specpath is not provided, but the blueprint URL looks like it points to a spec document, spec2bp will infer path from that instead - if milestone or priority are already set, the --milestone and --priority parameters are optional (current values will be kept if parameter is omitted) - spec2bp will recognize projects from the oslo projectgroup and use oslo-specs for those Example usage: Glance's super-spec.rst was approved and you want to add it to juno-2, with Medium priority: ./spec2bp.py glance super-spec --milestone=juno-2 --priority=Medium Nova's my-awesome-spec.rst is still under review, but you would like to add the my-awesome-spec blueprint to juno-2 (marked Blocked). Since it's located in a non-standard path, we specify it using --specpath parameter: ./spec2bp.py nova --specpath=specs/kilo/approved/my-awesome-spec.rst --in-review --milestone=juno-2 my-awesome-spec is now approved. You want to flip all the approval bits, but also change its priority to High. There is no need to pass --specpath again, spec2bp will infer it from the blueprint URL field: ./spec2bp.py nova my-awesome-spec --priority=High Change-Id: Idba1f042ffb836ac782f50d91802b2a6f4ff44c1
This commit is contained in:
parent
affe11ba77
commit
df2041e4ac
32
README.rst
32
README.rst
|
@ -333,24 +333,32 @@ spec2bp.py
|
|||
----------
|
||||
|
||||
This experimental script facilitates setting blueprint fields for approved
|
||||
specs. You point it to a spec file in a -specs repository, and it will set the
|
||||
Approver, definition status, spec URL, priority and milestone as you specify.
|
||||
By default priority is set to 'Low'.
|
||||
|
||||
In order for this to work, the spec must have the same name as the blueprint.
|
||||
specs. It takes the project and blueprint name as arguments. For specs that
|
||||
are still under review (--in-review) it will set them to "Blocked" (and
|
||||
definition status to Review). For approved specs it will set definition
|
||||
status to Approved, and set Spec URL. In both cases it will set the target
|
||||
milestone, approver name and specified priority (by default, 'Low').
|
||||
|
||||
Examples:
|
||||
|
||||
./spec2bp.py ../oslo-specs/specs/juno/graduate-oslo-i18n.rst juno-3
|
||||
./spec2bp.py glance super-spec --milestone=juno-2 --priority=Medium
|
||||
|
||||
Set the graduate-oslo-i18n oslo blueprint in Launchpad to Approved, set
|
||||
yourself as approver, set the spec URL, priority to Low and milestone to
|
||||
juno-3.
|
||||
Glance's super-spec.rst was approved and you want to add it to juno-2,
|
||||
with Medium priority. This will do it all for you.
|
||||
|
||||
./spec2bp.py warp-speed.rst kilo-1 --priority=High --test
|
||||
./spec2bp.py nova --specpath=specs/kilo/approved/my-awesome-spec.rst
|
||||
--in-review --milestone=juno-2
|
||||
|
||||
Nova's my-awesome-spec.rst is still under review, but you would like to
|
||||
add the my-awesome-spec blueprint to juno-2 (marked Blocked). Since it's
|
||||
located in a non-standard path, we specify it using --specpath parameter.
|
||||
|
||||
./spec2bp.py nova my-awesome-spec --priority=High
|
||||
|
||||
my-awesome-spec is now approved. You want to flip all the approval bits,
|
||||
but also change its priority to High. There is no need to pass --specpath
|
||||
again, spec2bp will infer it from the blueprint URL field.
|
||||
|
||||
On Launchpad test servers, try setting the warp-speed blueprint fields as
|
||||
above (with priority set to High and milestone set to kilo-1).
|
||||
|
||||
stable_freeze.py
|
||||
----------------
|
||||
|
|
152
spec2bp.py
152
spec2bp.py
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Script to set fields in LP blueprint for an approved spec
|
||||
# Script to set fields in LP blueprint for an approved or in-review spec
|
||||
#
|
||||
# Copyright 2014 Thierry Carrez <thierry@openstack.org>
|
||||
# All Rights Reserved.
|
||||
|
@ -18,7 +18,6 @@
|
|||
# under the License.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
from launchpadlib.launchpad import Launchpad
|
||||
|
@ -26,69 +25,120 @@ from launchpadlib.launchpad import Launchpad
|
|||
# Parameters
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Set blueprint fields for an approved spec file")
|
||||
parser.add_argument('specfile', help='spec file (in a -specs git repo)')
|
||||
parser.add_argument('milestone', help='which milestone to target the BP to')
|
||||
parser.add_argument("--test", action='store_const', const='staging',
|
||||
default='production', help='Use LP staging server to test')
|
||||
parser.add_argument("--priority", default='Low',
|
||||
parser.add_argument('project', help='project name')
|
||||
parser.add_argument('blueprint', help='blueprint name')
|
||||
parser.add_argument('--specpath', help='path to spec in specs repository. '
|
||||
'Defaults to blueprint URL or specs/series/blueprint.rst')
|
||||
parser.add_argument('--in-review', action='store_true',
|
||||
help='spec is still under review, mark as Blocked')
|
||||
parser.add_argument('--milestone', help='which milestone to target the BP to')
|
||||
parser.add_argument('--priority',
|
||||
choices=['Essential', 'High', 'Medium', 'Low'],
|
||||
help='which priority to set (default is Low)')
|
||||
parser.add_argument("--lp-project", default='',
|
||||
help=('which Launchpad project to use '
|
||||
'(default is based on spec repo name)'))
|
||||
help='priority to set (default is keep, or set Low)')
|
||||
parser.add_argument('--test', action='store_const', const='staging',
|
||||
default='production', help='Use LP staging server to test')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Validate specfile
|
||||
m = re.match(r".*/(\w+)-specs/(.+)/(.+).rst", os.path.abspath(args.specfile))
|
||||
if m is None:
|
||||
parser.error("%s has not a recognized spec pattern" % args.specfile)
|
||||
projname = m.group(1)
|
||||
specs_repo = '%s-specs' % projname
|
||||
if projname == 'oslo':
|
||||
projname = 'oslo-incubator'
|
||||
if args.lp_project:
|
||||
projname = args.lp_project
|
||||
repoloc = "openstack/%s/plain/%s" % (specs_repo, m.group(2))
|
||||
bpname = m.group(3)
|
||||
|
||||
# Check that spec was approved (merged in specs repository)
|
||||
# Also use this to validate spec link URL
|
||||
cgit = "http://git.openstack.org/cgit"
|
||||
specurl = "%s/%s/%s.rst" % (cgit, repoloc, bpname)
|
||||
try:
|
||||
r = requests.get(specurl)
|
||||
if r.status_code != 200 or not r.text:
|
||||
parser.error("No such confirmed spec in %s-specs" % projname)
|
||||
except requests.exceptions.RequestException as exc:
|
||||
parser.exit(1, "Error trying to confirm spec is valid")
|
||||
|
||||
# Log into Launchpad
|
||||
launchpad = Launchpad.login_with('openstack-releasing', args.test,
|
||||
version='devel')
|
||||
|
||||
# Validate project
|
||||
project = launchpad.projects[projname]
|
||||
project = launchpad.projects[args.project]
|
||||
if not project:
|
||||
parser.error("%s project does not exist in Launchpad" % projname)
|
||||
parser.error("%s project does not exist in Launchpad" % args.project)
|
||||
|
||||
# Validate milestone
|
||||
milestone = project.getMilestone(name=args.milestone)
|
||||
if not milestone:
|
||||
parser.error("%s milestone does not exist in Launchpad" % args.milestone)
|
||||
if not milestone.is_active:
|
||||
parser.error("%s is no longer an active milestone" % args.milestone)
|
||||
# Determine spec repository name
|
||||
oslo = [p.name for p in launchpad.project_groups['oslo'].projects]
|
||||
if args.project in oslo:
|
||||
specrepo = "oslo-specs"
|
||||
else:
|
||||
specrepo = args.project + "-specs"
|
||||
|
||||
# Validate spec
|
||||
bp = project.getSpecification(name=bpname)
|
||||
bp = project.getSpecification(name=args.blueprint)
|
||||
if not bp:
|
||||
parser.exit(1, "Blueprint %s not found for project %s"
|
||||
% (bpname, projname))
|
||||
parser.error("Blueprint %s not found for project %s"
|
||||
% (args.blueprint, args.project))
|
||||
|
||||
# If no milestone is set on blueprint, we must have a milestone argument
|
||||
if not bp.milestone and not args.milestone:
|
||||
parser.error("Blueprint has no milestone, so you must specify one to set "
|
||||
"using the --milestone argument")
|
||||
|
||||
# Validate milestone if provided
|
||||
if args.milestone:
|
||||
milestone = project.getMilestone(name=args.milestone)
|
||||
if not milestone:
|
||||
parser.error("%s milestone does not exist in LP" % args.milestone)
|
||||
if not milestone.is_active:
|
||||
parser.error("%s is no longer an active milestone" % args.milestone)
|
||||
else:
|
||||
milestone = bp.milestone
|
||||
|
||||
# Determine spec URL
|
||||
if args.specpath:
|
||||
path = args.specpath
|
||||
else:
|
||||
if bp.specification_url:
|
||||
m = re.match(r".*openstack.org.*/\w+-specs/(.+)/(.+).rst",
|
||||
bp.specification_url)
|
||||
if m is not None:
|
||||
# Looks like a valid spec link, let's infer path from that
|
||||
if m.group(1).startswith("plain/"):
|
||||
path = "%s/%s.rst" % (m.group(1)[6:], m.group(2))
|
||||
else:
|
||||
path = "%s/%s.rst" % (m.group(1), m.group(2))
|
||||
path = 'specs/%s/%s.rst' % (milestone.series_target.name, args.blueprint)
|
||||
|
||||
site = "http://git.openstack.org/cgit/openstack/%s" % specrepo
|
||||
url = "%s/plain/%s" % (site, path)
|
||||
|
||||
# Set blueprints fields
|
||||
if args.in_review:
|
||||
# Check if the spec is not already approved
|
||||
try:
|
||||
r = requests.get(url)
|
||||
if r.status_code == 200 and r.text:
|
||||
parser.error("The spec you want to set --in-review seems to "
|
||||
"have been approved already!")
|
||||
except requests.exceptions.RequestException as exc:
|
||||
pass
|
||||
bp.definition_status = 'Review'
|
||||
bp.implementation_status = 'Blocked'
|
||||
|
||||
else:
|
||||
# Check that spec was approved (merged in specs repository)
|
||||
# Also use this to validate spec link URL
|
||||
try:
|
||||
r = requests.get(url)
|
||||
if r.status_code != 200 or not r.text:
|
||||
parser.error("""
|
||||
Can't find the spec corresponding to the blueprint in cgit. There are
|
||||
multiple possible causes for that.
|
||||
|
||||
The spec may not be approved yet. If you just wanted to set fields on
|
||||
unapproved BP, don't forget the --in-review parameter.
|
||||
|
||||
The spec may also point to some non-standard URL (not specs/series/bpname.rst).
|
||||
In that case, you can use the --specrepo parameter to point to it.""")
|
||||
except requests.exceptions.RequestException as exc:
|
||||
parser.exit(1, "Error trying to confirm spec is valid")
|
||||
|
||||
# Set approver, definition status, spec URL, priority and milestone
|
||||
bp.definition_status = 'Approved'
|
||||
bp.specification_url = url
|
||||
if bp.implementation_status == 'Blocked':
|
||||
bp.implementation_status = 'Unknown'
|
||||
|
||||
# Set approver, definition status, spec URL, priority and milestone
|
||||
bp.approver = launchpad.me
|
||||
bp.definition_status = 'Approved'
|
||||
bp.specification_url = specurl
|
||||
bp.priority = args.priority
|
||||
bp.milestone = milestone
|
||||
bp.lp_save()
|
||||
if bp.priority == 'Undefined':
|
||||
bp.priority = args.priority or 'Low'
|
||||
if bp.milestone != milestone:
|
||||
bp.milestone = milestone
|
||||
bp.lp_save()
|
||||
bp.proposeGoal(goal=milestone.series_target)
|
||||
else:
|
||||
bp.lp_save()
|
||||
|
|
Loading…
Reference in New Issue