#!/usr/bin/bash # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Author: Dusty Mabe # Note this script uses the `bugzilla` CLI to interact with Red Hat's # bugzilla instance. First install it and login before proceeding: # # - dnf install /usr/bin/bugzilla # - bugzilla login # # In order to use it: # - `./bz-sprint-bugs.sh show` will show bugs assigned to you # - `./bz-sprint-bugs.sh update` will modify bugs with keyword/comment # Guidance from the "Every Bug, Every Sprint" email: # # Literally every single bug every single sprint must be reviewed by the team. # The team must leave a comment every sprint if a bug isn’t resolved. # The team must add the keyword ‘UpcomingSprint’ if a bug isn’t resolved. # We don’t have to fix every bug every sprint but we must look at them. # If we have too many bugs, re-evaluate team priorities. # At the beginning of every sprint, ‘UpcomingSprint’ will be removed and teams repeat # # For me I'll use personal tags to indicate what state my bugs are in. # Personal tags in bugzilla are only visible to you as an individual and # can be used for whatever you like. In this case I'm using them to denote # the state of the bug in order to customize the comment. The two I recognize # at this point are: # # - 'waiting_needinfo' - waiting on someone else # - 'waiting_assignee' - waiting on me to schedule/do the work # - 'waiting_workinfo' - in progress, but won't be completed this sprint # Set the comments we want associated with each state. WAITING_NEEDINFO_COMMENT="This bug needs more information. It is not scheduled to be worked on in the current sprint." WAITING_ASSIGNEE_COMMENT="This bug has not been selected for work in the current sprint." WAITING_WORKINFO_COMMENT="This is being worked on, but is currently awaiting more investigation or more information and won't be completed this sprint." # Set some variables used to filter down the returned bugs ASSIGNEE='dustymabe@redhat.com' STATUS='NEW,ASSIGNED' PRODUCT='OpenShift Container Platform' COMPONENT='RHCOS' # Function that will detect bug IDs in text and # convert them into terminal hyperlinks # see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#quick-example addlinks() { sed -E -e 's|#([0-9]+)|\\e]8;;https://bugzilla.redhat.com/show_bug.cgi?id=\1\\e\\\\#\1\\e]8;;\\e\\\\|g' -e 's|$|\\n|' | \ tr -d '\n' } # Go through and set 'UpcomingSprint' label on bugs that are # in a known state (i.e., have the personal tags mentioned above). # After adding the 'UpcomingSprint' label to any bugs then print # out the remaining bugs, which represent what you're working on # this sprint. main() { # Build up a common query command assigned to this user. Use an # array since $PRODUCT has spaces in it. See # http://mywiki.wooledge.org/BashFAQ/050#I.27m_constructing_a_command_based_on_information_that_is_only_known_at_run_time common_query_cmd=(bugzilla --ensure-logged-in query --product "$PRODUCT" \ --component=$COMPONENT --assigned_to=$ASSIGNEE --status=$STATUS) if [ "$1" == 'show' ]; then echo -en $("${common_query_cmd[@]}" | addlinks) exit 0 fi if [ "$1" != 'update' ]; then echo "Must provide 'show' or 'update' as an argument" 1>&2 exit 1 fi # Build up a query url for bugs without the `UpcomingSprint` keyword. # Here we need to use a custom query URL because the bugzilla CLI doesn't # have the ability to do a negative search on a tag. The --from-url is a # catchall for complicated queries. no_upcomingsprint_keyword_query="https://bugzilla.redhat.com/buglist.cgi?" no_upcomingsprint_keyword_query+="&bug_status=${STATUS//,/&bug_status=}" no_upcomingsprint_keyword_query+="&component=${COMPONENT}" no_upcomingsprint_keyword_query+="&email1=${ASSIGNEE//@/%40}&emailassigned_to1=1&emailtype1=substring" no_upcomingsprint_keyword_query+='&f1=tag&keywords=UpcomingSprint%2C%20&keywords_type=nowords&list_id=11131214&o1=nowords' no_upcomingsprint_keyword_query+="&product=${PRODUCT// /%20}" # Grab the list of bugs to operate on declare -A bugs for bug in $(bugzilla --ensure-logged-in query --from-url "${no_upcomingsprint_keyword_query}" --ids); do bugs[$bug]=1 done # Query for my bugs that are waiting on info and add comment/keyword for bug in $("${common_query_cmd[@]}" --ids --tag='waiting_needinfo'); do # Only act if the bug doesn't have the UpcomingSprint keyword already if [ "${bugs[$bug]}" == "1" ]; then echo -en $(echo "Updating bug #${bug}" | addlinks) bugzilla --ensure-logged-in modify --keywords=UpcomingSprint \ --comment "${WAITING_NEEDINFO_COMMENT}" $bug fi done # Query for my bugs that are waiting on me and add comment/keyword for bug in $("${common_query_cmd[@]}" --ids --tag='waiting_assignee'); do # Only act if the bug doesn't have the UpcomingSprint keyword already if [ "${bugs[$bug]}" == "1" ]; then echo -en $(echo "Updating bug #${bug}" | addlinks) bugzilla --ensure-logged-in modify --keywords=UpcomingSprint \ --comment "${WAITING_ASSIGNEE_COMMENT}" $bug fi done # Query for my bugs that are in progress but need info and add comment/keyword for bug in $("${common_query_cmd[@]}" --ids --tag='waiting_workinfo'); do # Only act if the bug doesn't have the UpcomingSprint keyword already if [ "${bugs[$bug]}" == "1" ]; then echo -en $(echo "Updating bug #${bug}" | addlinks) bugzilla --ensure-logged-in modify --keywords=UpcomingSprint \ --comment "${WAITING_WORKINFO_COMMENT}" $bug fi done # Print out what bugs are left so the user can analyze them remaining_bugs="$(bugzilla --ensure-logged-in query --from-url ${no_upcomingsprint_keyword_query})" if [ -z "${remaining_bugs}" ]; then echo "All bugs now have the UpcomingSprint keyword." else output=$(cat <