Add tools/bulk_review.sh and get-contacts
get-contacts: To extract the PTL/Liaison contact information from the governance data / release team data tools/bulk_review.sh: To manipulate a dirty working-tree and post as a single gerrit topic, one change per team. Changes are unordered so any change can be merged when it's ready/ approved by the appropriate team Also enhance get-deliverable-owner: to detect file paths Story: 2005704 Task: 31028 Change-Id: Ia319e8a7b4da195cb4bc861c51025a41adc43bb3
This commit is contained in:
parent
802661cdb3
commit
60e786d724
@ -576,6 +576,8 @@ easy as ``pip install .`` in this repository directory.
|
|||||||
of the releases that should have been tagged by hand have been
|
of the releases that should have been tagged by hand have been
|
||||||
* ``init-series`` initializes a new deliverable directory with stub
|
* ``init-series`` initializes a new deliverable directory with stub
|
||||||
files based on the previous release.
|
files based on the previous release.
|
||||||
|
* ``get-contacts`` Loads the governance and liaison data to print contact
|
||||||
|
deatils for a given team
|
||||||
|
|
||||||
tools/aclmanager.py
|
tools/aclmanager.py
|
||||||
-------------------
|
-------------------
|
||||||
@ -620,6 +622,25 @@ Example:
|
|||||||
|
|
||||||
tox -e check_approval -- 695375
|
tox -e check_approval -- 695375
|
||||||
|
|
||||||
|
tools/bulk_review.sh
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
A script for taking a working directory and dividing up the modified files into
|
||||||
|
a collection on independent per-team reviews. Each per-team change should be
|
||||||
|
able to be processed in any order. These reviews will request review from the
|
||||||
|
the PTL and all release liaisons.
|
||||||
|
|
||||||
|
This is designed to be used by the release team at key points in the cycle to
|
||||||
|
ease bulk releases.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This tool will commit ultimately commit all modified deliverables and
|
||||||
|
modifies git state. Therefore it is essential that befoer running it
|
||||||
|
the working tree contains only the logical changes appropriate for the
|
||||||
|
stage of the release *and* all changes are saved elsewhere, in case the
|
||||||
|
script encounters a problem.
|
||||||
|
|
||||||
tools/membership_freeze_test.py
|
tools/membership_freeze_test.py
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
80
openstack_releases/cmds/get_contacts.py
Normal file
80
openstack_releases/cmds/get_contacts.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Get the PTL and release liaison information.
|
||||||
|
|
||||||
|
Grab the PTL's contact details from the governance repo; and Liaisons
|
||||||
|
data from release_liaisons.yaml
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from openstack_governance import governance
|
||||||
|
|
||||||
|
from openstack_releases import liaisons
|
||||||
|
|
||||||
|
|
||||||
|
class Contact(object):
|
||||||
|
def __init__(self, contact_data):
|
||||||
|
self.name = contact_data['name']
|
||||||
|
self.irc = contact_data['irc']
|
||||||
|
self.email = contact_data['email']
|
||||||
|
|
||||||
|
|
||||||
|
def print_contact(contact):
|
||||||
|
print('Name : %s' % contact.name)
|
||||||
|
print('IRC Nick : %s' % contact.irc)
|
||||||
|
print('Email : %s' % contact.email)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('team', nargs='+', help='The team(s) to lookup')
|
||||||
|
who_group = parser.add_mutually_exclusive_group()
|
||||||
|
who_group.add_argument('--ptl', action='store_true', default=False,
|
||||||
|
help='Find PTL details')
|
||||||
|
who_group.add_argument('--liaisons', action='store_true', default=False,
|
||||||
|
help='Find Liaisons details')
|
||||||
|
who_group.add_argument('--all', action='store_true', default=True,
|
||||||
|
help='Find Liaisons details')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
gov_data = governance.Governance.from_remote_repo()
|
||||||
|
liaison_data = liaisons.get_liaisons()
|
||||||
|
|
||||||
|
for team_name in args.team:
|
||||||
|
contacts = set()
|
||||||
|
if args.ptl or args.all:
|
||||||
|
team_data = gov_data.get_team(team_name)
|
||||||
|
if not team_data:
|
||||||
|
print('Unable to find team [%s] in governance data' %
|
||||||
|
(args.team),
|
||||||
|
file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
contacts.add(Contact(team_data.ptl))
|
||||||
|
|
||||||
|
if args.liaisons or args.all:
|
||||||
|
for liaison in liaison_data.get(team_name.lower(), []):
|
||||||
|
contacts.add(Contact(liaison))
|
||||||
|
|
||||||
|
team_header = '%s Contacts:' % team_name.title()
|
||||||
|
print()
|
||||||
|
print(team_header)
|
||||||
|
print('%s' % ('-' * len(team_header)))
|
||||||
|
for contact in contacts:
|
||||||
|
print_contact(contact)
|
||||||
|
|
||||||
|
return 0
|
@ -27,12 +27,23 @@ def main():
|
|||||||
default=openstack_releases.deliverable_dir,
|
default=openstack_releases.deliverable_dir,
|
||||||
help='location of deliverable files',
|
help='location of deliverable files',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--file',
|
||||||
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help='deliverable arg is a file path rather than a std. deliverable'
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# If we've been told the 'deliverable' is infact a yaml file *or* the
|
||||||
|
# deliverable contains a '/' just load that file directly
|
||||||
|
if args.file or '/' in args.deliverable:
|
||||||
|
deliv = deliverable.Deliverable.read_file(args.deliverable)
|
||||||
|
else:
|
||||||
all_deliv = deliverable.Deliverables(
|
all_deliv = deliverable.Deliverables(
|
||||||
root_dir=args.deliverables_dir,
|
root_dir=args.deliverables_dir,
|
||||||
collapse_history=False,
|
collapse_history=False,
|
||||||
)
|
)
|
||||||
for deliv in all_deliv.get_deliverable_history(args.deliverable):
|
deliv = next(all_deliv.get_deliverable_history(args.deliverable))
|
||||||
|
|
||||||
print(deliv.team)
|
print(deliv.team)
|
||||||
break
|
|
||||||
|
@ -41,6 +41,7 @@ console_scripts =
|
|||||||
release-notes = openstack_releases.cmds.release_notes:main
|
release-notes = openstack_releases.cmds.release_notes:main
|
||||||
check-schema = openstack_releases.cmds.check_schema:main
|
check-schema = openstack_releases.cmds.check_schema:main
|
||||||
find-gerrit-acl-issues = openstack_releases.cmds.find_gerrit_acl_issues:main
|
find-gerrit-acl-issues = openstack_releases.cmds.find_gerrit_acl_issues:main
|
||||||
|
get-contacts = openstack_releases.cmds.get_contacts:main
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
source-dir = doc/source
|
source-dir = doc/source
|
||||||
|
117
tools/bulk_review.sh
Executable file
117
tools/bulk_review.sh
Executable file
@ -0,0 +1,117 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Tool to take a dirty working tree and create a 'flat' gerrit topic (per team)
|
||||||
|
# for all the changes
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
function usage {
|
||||||
|
echo "Usage: bulk_review.sh -t topic -s subject -b message_body"
|
||||||
|
echo
|
||||||
|
echo " topic: local branch names will be of the form $team-$topic"
|
||||||
|
echo " and gerrit topic will be set to $topic"
|
||||||
|
echo " subject: This will be the subject in the git commit"
|
||||||
|
echo " body: This will be the message body for the git commit"
|
||||||
|
echo
|
||||||
|
echo "This script operates on a dirty repo (such as one created by"
|
||||||
|
echo "running tools/make_missing_releases.sh. It will then create a"
|
||||||
|
echo "local branch per-team of the modified deliverable files and then"
|
||||||
|
echo "submit that branch for review"
|
||||||
|
echo
|
||||||
|
echo "PTLs and liaisons will be CC'd on the review"
|
||||||
|
}
|
||||||
|
|
||||||
|
# NOTE: It might be worth switching getopt but I don't knwo if that is
|
||||||
|
# available and the same on MacOS
|
||||||
|
while getopts "t:s:b:" arg ; do
|
||||||
|
case "$arg" in
|
||||||
|
t)
|
||||||
|
topic=$OPTARG
|
||||||
|
;;
|
||||||
|
s)
|
||||||
|
subject=$OPTARG
|
||||||
|
;;
|
||||||
|
b)
|
||||||
|
body=$OPTARG
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$topic" -o -z "$subject" -o -z "$body" ] ; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'This script will modifiy git branches and and submit reviews.'
|
||||||
|
echo 'It relies on master being a safe/clean branch.'
|
||||||
|
echo
|
||||||
|
echo 'If master contains private changes, abort now'
|
||||||
|
echo 'If you have any unrelated work, abort now'
|
||||||
|
echo 'If you have not saved the modified deliverables somewhere, abort now'
|
||||||
|
echo
|
||||||
|
echo 'Press return to continue or <ctrl>-C to abort'
|
||||||
|
|
||||||
|
read _continue
|
||||||
|
|
||||||
|
declare -A files_by_team_release=()
|
||||||
|
|
||||||
|
# Find the team associated with each modified deliverable file
|
||||||
|
declare -a deliverables=($(git ls-files -m deliverables))
|
||||||
|
for file in "${deliverables[@]}" ; do
|
||||||
|
team="$(get-deliverable-owner --file $file)"
|
||||||
|
files_by_team_release["$team"]+=" $file"
|
||||||
|
done
|
||||||
|
|
||||||
|
#for x in "${!files_by_team_release[@]}"; do printf "[%q]=%q\n" "$x" "${files_by_team_release[$x]}" ; done
|
||||||
|
|
||||||
|
for team in "${!files_by_team_release[@]}" ; do
|
||||||
|
branch_name=${team/ /_}-${topic}
|
||||||
|
echo "[$team] :: [$branch_name] ${files_by_team_release[$team]}"
|
||||||
|
|
||||||
|
git checkout -b $branch_name -t origin/master
|
||||||
|
|
||||||
|
git add ${files_by_team_release[$team]}
|
||||||
|
git commit \
|
||||||
|
-m "[$team] $subject" \
|
||||||
|
-m "$body"
|
||||||
|
|
||||||
|
git stash
|
||||||
|
git checkout master
|
||||||
|
git stash pop
|
||||||
|
done
|
||||||
|
|
||||||
|
git checkout master
|
||||||
|
git stash list
|
||||||
|
git branch -va | grep -E "$topic"
|
||||||
|
|
||||||
|
for team in "${!files_by_team_release[@]}" ; do
|
||||||
|
declare -a emails=(
|
||||||
|
$(get-contacts --all "$team"| awk -F': ' '/Email/ {print $2}')
|
||||||
|
)
|
||||||
|
review_args=''
|
||||||
|
for email in ${emails[@]} ; do
|
||||||
|
review_args+=" --reviewers $email"
|
||||||
|
done
|
||||||
|
|
||||||
|
branch_name=${team/ /_}-${topic}
|
||||||
|
git checkout $branch_name
|
||||||
|
git review -y -t $topic $review_args
|
||||||
|
done
|
||||||
|
git checkout master
|
Loading…
x
Reference in New Issue
Block a user