diff --git a/tools/abandon_old_reviews.sh b/tools/abandon_old_reviews.sh new file mode 100644 index 00000000..36a07c4e --- /dev/null +++ b/tools/abandon_old_reviews.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash +# Copyright 2019 Red Hat, Inc. +# +# 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. +# +# WARNING! +# Please do not run this script without talking to the TripleO PTL. Auto +# abandoning people's changes is a good thing, but must be done with care. +# +# before you run this modify your .ssh/config to create a +# review.opendev.org entry: +# +# Host review.opendev.org +# User +# Port 29418 +# + +DRY_RUN=0 +CLEAN_PROJECT="" + +function print_help { + echo "Script to abandon patches without activity for more than 4 weeks." + echo "Usage:" + echo " ./abandon_old_reviews.sh [--dry-run] [--project ] [--help]" + echo " --dry-run In dry-run mode it will only print what patches would be abandoned " + echo " but will not take any real actions in gerrit" + echo " --project Only check patches from if passed." + echo " It must be one of the projects which are a part of the TripleO-group." + echo " If project is not provided, all projects from the TripleO-group will be checked" + echo " --help Print help message" +} + +while [ $# -gt 0 ]; do + key="${1}" + + case $key in + --dry-run) + echo "Enabling dry run mode" + DRY_RUN=1 + shift # past argument + ;; + --project) + CLEAN_PROJECT="project:openstack/${2}" + shift # past argument + shift # past value + ;; + --help) + print_help + exit 2 + esac +done + +set -o errexit +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +function abandon_review { + local gitid=$1 + shift + local msg=$@ + unassign_and_new_bug $gitid + if [ $DRY_RUN -eq 1 ]; then + echo "Would abandon $gitid" + else + echo "Abandoning $gitid" + ssh review.opendev.org gerrit review $gitid --abandon --message \"$msg\" + fi +} + +function unassign_and_new_bug { + # unassign current assignee and set bug to 'new' status + local gitid=$1 + cm=$(ssh review.opendev.org "gerrit query $gitid --current-patch-set --format json" | jq .commitMessage) + for closes in $(echo -e $cm | awk '/[cC]loses-[bB]ug/ {match($0,/[0-9]+/); bug=substr($0,RSTART,RLENGTH); print bug}'); do + if [ $DRY_RUN -eq 1 ]; then + echo "Would unassign and tag 'timeout-abandon' $closes" + else + echo "Attempting to change status of bug $closes to New" + python "$DIR/unassign_bug.py" $closes + fi + done +} + +PROJECTS="($( +python - < 90 days without comment and currently blocked by a +core reviewer with a -2. We are abandoning this for now. +Feel free to reactivate the review by pressing the restore button and +contacting the reviewer with the -2 on this review to ensure you +address their concerns. For more details check policy +https://specs.openstack.org/openstack/tripleo-specs/specs/policy/patch-abandonment.html +EOF +) + +for review in $blocked_reviews; do + echo "Blocked review $review" + abandon_review $review $blocked_msg +done + +# then purge all the reviews that are > 90d with no changes and Zuul has -1ed + +failing_reviews=$(ssh review.opendev.org "gerrit query --current-patch-set --format json $PROJECTS status:open age:90d NOT label:Verified>=1,Zuul" | jq .currentPatchSet.revision | grep -v null | sed 's/"//g') + +failing_msg=$(cat < 90 days without comment, and failed Zuul the last +time it was checked. We are abandoning this for now. +Feel free to reactivate the review by pressing the restore button and +leaving a 'recheck' comment to get fresh test results. +For more details check policy +https://specs.openstack.org/openstack/tripleo-specs/specs/policy/patch-abandonment.html +EOF +) + +for review in $failing_reviews; do + echo "Failing review $review" + abandon_review $review $failing_msg +done + +# then purge all the reviews that are > 180 days with WIP -1 + +very_old_reviews=$(ssh review.opendev.org "gerrit query --current-patch-set --format json $PROJECTS status:open age:180d Workflow<=-1" | jq .currentPatchSet.revision | grep -v null | sed 's/"//g') + +very_old_msg=$(cat < 180 days without comment and WIP -1. We are abandoning this for now. +Feel free to reactivate the review by pressing the restore button and +contacting the reviewers. +For more details check policy +https://specs.openstack.org/openstack/tripleo-specs/specs/policy/patch-abandonment.html +EOF +) + +for review in $very_old_reviews; do + echo "Workflow -1 review $review" + abandon_review $review $very_old_msg +done \ No newline at end of file diff --git a/tools/unassign_bug.py b/tools/unassign_bug.py new file mode 100644 index 00000000..da9043fa --- /dev/null +++ b/tools/unassign_bug.py @@ -0,0 +1,56 @@ +# +# Copyright 2019 Red Hat, Inc. +# +# 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. +"""Unassigns assignee from tripleobug, adds message and tag. +If you get the following exception, you need X11 and python-dbus installed: +'RuntimeError: No recommended backend was available. Install +the keyrings.alt package if you want to use the non-recommended +backends. See README.rst for details.' +or check solutions from: +https://github.com/jaraco/keyring/issues/258 +""" + +import os +import sys + +from launchpadlib.launchpad import Launchpad + + +MSG_BODY = "\ +This bug has had a related patch abandoned and has been automatically \ +un-assigned due to inactivity. Please re-assign yourself if you are \ +continuing work or adjust the state as appropriate if it is no longer valid." + + +def unassign(bug_num): + login = os.environ.get('LAUNCHPAD_LOGIN', 'tripleo') + password = os.environ.get('LAUNCHPAD_PASSWORD', 'production') + launchpad = Launchpad.login_with(login, password) + b = launchpad.bugs[bug_num] + for task in b.bug_tasks: + for tag in task.bug_target_name: + if 'tripleo' not in tag: + # try not to interfere with non-tripleo projects too much + continue + task.assignee = None + if task.status == "In Progress": + task.status = 'New' + task.lp_save() + b.tags = b.tags + ['timeout-abandon'] + b.newMessage(content=MSG_BODY, subject='auto-abandon-script') + b.lp_save() + + +if __name__ == '__main__': + unassign(int(sys.argv[1]))