release-tools/autokick.py

110 lines
4.3 KiB
Python
Executable File

#!/usr/bin/python
#
# Script to automatically adjust series goal based on target milestone
# in Launchpad blueprints, and possibly remove unprioritized blueprints
#
# Copyright 2013 Thierry Carrez <thierry@openstack.org>
# 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 sys
import launchpadlib.launchpad
# Parse arguments
parser = argparse.ArgumentParser(description="Adjust blueprint series goal/milestones")
parser.add_argument('projectname', help='Project or projectgroup to act on')
parser.add_argument('seriesname', help='Series to act on')
parser.add_argument('--nokick', action='store_true',
help='Do not kick unprioritized BPs out of milestones')
parser.add_argument('--dryrun', action='store_true',
help='Just show what would be done')
args = parser.parse_args()
kickmessage = ("You should not set a milestone target unless the blueprint"
" has been properly prioritized by the project drivers.")
# Log into LP
lp = launchpadlib.launchpad.Launchpad.login_with('adjust-series-goal', 'production', version='devel')
try:
projectgroup = lp.project_groups[args.projectname]
projects = projectgroup.projects
except (KeyError, AttributeError):
try:
projects = [lp.projects[args.projectname], ]
except KeyError:
print("%s: no such project or projectgroup" % args.projectname)
sys.exit(1)
for project in projects:
print("== %s ==" % project.name)
series = project.getSeries(name=args.seriesname)
# Get the milestones for the series
milestones = []
try:
active_milestones = series.active_milestones_collection
except AttributeError:
print("No milestone in series %s for %s, skipping" %
(args.seriesname, project.name))
continue
for ms in series.active_milestones_collection:
milestones.append(ms)
# Get the blueprints with seriesgoal set
accepted = series.valid_specifications
# Find targeted blueprints that are not in the series
for bp in project.valid_specifications:
if bp.milestone in milestones:
if bp.priority in ["Undefined", "Not"]:
# Blueprint is in milestone but has no priority
if not args.nokick:
print("KICK %s (from %s)" % (bp.name, bp.milestone.name))
if not args.dryrun:
bp.proposeGoal(goal=None)
bp.milestone = None
if bp.whiteboard is None:
bp.whiteboard = ""
if kickmessage not in bp.whiteboard:
bp.whiteboard += ("\n\n" + kickmessage + "\n")
bp.whiteboard += "(This is an automated message)\n"
bp.lp_save()
else:
if bp not in accepted:
# BP has milestone & prio, but not accepted for series yet
print("SETGOAL %s" % bp.name)
if not args.dryrun:
bp.proposeGoal(goal=series)
# Get the blueprints in the series
proposed = []
for bp in series.all_specifications:
if not bp.is_complete:
if bp.milestone not in milestones:
# Blueprint is in series, no milestone
print("CLEARGOAL %s" % bp.name)
if not args.dryrun:
bp.proposeGoal(goal=None)
else:
if not bp.has_accepted_goal:
if bp.priority not in ["Undefined", "Not"]:
# BP is proposed/declined in series, has mstone + prio
print("APPROVEGOAL %s" % bp.name)
if not args.dryrun:
bp.acceptGoal()