Skip to content

Commit

Permalink
Add initital triage script
Browse files Browse the repository at this point in the history
In an effort to make triaging by the bug wrangler something that can be
done in a single sweep, I'm proposing this set of git extensions to
allow an issue to be triaged without having to remember the set of all
labels/states/projects that need to be touched when doing so from the
web interface
  • Loading branch information
nhorman committed Apr 1, 2024
1 parent 39e3169 commit d595ea2
Show file tree
Hide file tree
Showing 9 changed files with 551 additions and 0 deletions.
14 changes: 14 additions & 0 deletions triage/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Openssl wrangler triage tools


This is a set of tools that will enable individual executing the bug wrangler
role to do their job (hopefully) more efficiently and consistently. It creates
a series of git extension to review bugs on the command line and process them in
such a way that you don't need to remember all the individual steps you need to
take to produce a particular outcome within our process.

INSTALLATION
Just add this directory to your PATH. That will enable access to the following
git extension:
git triage

28 changes: 28 additions & 0 deletions triage/git-triage
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

if [ -z "$1" ]
then
echo "No subcommand provided"
echo "Run git triage help for a list of commands"
exit 0
fi

SUBCOMMAND=$1
shift

which git-triage-$SUBCOMMAND > /dev/null 2>&1
if [ $? -ne 0 ]
then
TCMD=$(which git-triage)
TDIR=$(dirname $TCMD)
echo "Please select from the following subcommands:"
for i in $(ls $TDIR/git-triage-*)
do
CBASE=$(basename $i | sed -e"s/.*git-triage-//")
echo $CBASE
done
exit 1;
fi


exec git-triage-$SUBCOMMAND $*
250 changes: 250 additions & 0 deletions triage/git-triage-evaluate
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
#!/bin/bash

INSTDIR=$(dirname $0)
source $INSTDIR/triage-common.sh


VALID_TYPES=(bug feature documentation cleanup performance refactor question)
TYPE=none

ISSUE=unknown

function parse_options {
# get the other options
while true
do
OPTION=$1
if [ -z "$OPTION" ]
then
return
fi
KEY=$(echo $1 | awk -F'=' '{print $1}')
VALUE=$(echo $1 | awk -F'=' '{print $2}')
case $KEY in
issue)
ISSUE=$VALUE
;;
release)
RELEASE=$VALUE
;;
target)
TARGET=$VALUE
;;
resolution)
RESOLUTION=$VALUE
;;
resolution_id)
RESOLUTION_ID=$VALUE
;;
urgent)
IS_URGENT=$VALUE
;;
important)
IS_IMPORTANT=$VALUE
;;
regression)
IS_REGRESSION=$VALUE
;;
priority)
PRIORITY=$VALUE
;;
type)
TYPE=$VALUE
;;
*)
echo "$KEY is not a valid option"
exit 1
;;
esac
shift
done
}

function validate_target {
#check to ensure target is valid
for item in "${VALID_TARGETS[@]}"
do
if [ "$TARGET" == "$item" ]
then
return
fi
done
echo "please select target from one of [${VALID_TARGETS[@]}]"
exit 1
}

function validate_release {
for item in "${GH_RELEASE_LIST[@]}"
do
if [ "$RELEASE" == "$item" ]
then
return
fi
done
echo "please select a release from one of [${GH_RELEASE_LIST[@]}]"
exit 1
}

function validate_priority {
for item in "${VALID_PRIORITIES[@]}"
do
if [ "$PRIORITY" == "$item" ]
then
return
fi
done
echo "please select a priority from one of [${VALID_PRIORITIES[@]}]"
exit 1
}

function validate_issue {
gh issue view $ISSUE --json id >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo "Unable to find issue $ISSUE"
exit 1;
fi
}

function validate_resolution {
for item in "${VALID_RESOLUTIONS[@]}"
do
if [ "$RESOLUTION" == "$item" ]
then
if [ "$RESOLUTION" == "duplicate" -a $RESOLUTION_ID -eq 0 ]
then
echo "A resolution of duplicate requires a resolution_id value"
exit 1
fi
# map label names
case "$RESOLUTION" in
notabug)
RESOLUTION="not a bug"
;;
wontfix)
RESOLUTION="wont fix"
;;
*)
;;
esac
return
fi
done
echo "$RESOLUTION is an invalid resolution value"
exit 1
}

function validate_type {
for item in "${VALID_TYPES[@]}"
do
if [ "$TYPE" == "$item" ]
then
return
fi
done
echo "please select an issue type from [${VALID_TYPES[@]}]"
exit 1
}

function validate_labels {
if [ "$IS_IMPORTANT" == "unknown" ]
then
echo "Please select important=[yes|no]"
exit 1
fi

if [ "$IS_REGRESSION" == "unknown" ]
then
echo "Please select regression=[yes|no]"
exit 1
fi
}

function validate_options {
validate_issue
validate_target
validate_type
validate_labels
if [ "$TARGET" == "openssl" ]
then
validate_release
validate_priority
fi
if [ "$TARGET" == "resolve" ]
then
validate_resolution
fi
}

function process_issue {
local labels

# Start by determining what label(s) we need
if [ "$TARGET" == "followup" ]
then
echo "Opening issue in a web browser so you can add a comment"
gh issue view $ISSUE -w
exit 0
fi

LABEL_LIST=""
# Add our triage labels
if [ "$IS_REGRESSION" == "yes" ]
then
LABEL_LIST="severity: regression"
fi
if [ "$IS_URGENT" == "yes" ]
then
LABEL_LIST="$LABEL_LIST,severity: urgent"
fi
if [ "$IS_IMPORTANT" == "yes" ]
then
LABEL_LIST="$LABEL_LIST,severity: important"
fi

LABEL_LIST="$LABEL_LIST,triaged: $TYPE"

if [ "$TARGET" == "community" ]
then
echo "Marking this issue as needing community resolution"
LABEL_LIST="$LABEL_LIST,help wanted"
LABEL_LIST=$(echo $LABEL_LIST | sed -e"s/^,\+//" -e"s/,\{2,\}/,/g" -e"s/,\+$//")
gh issue edit $ISSUE --add-label "$LABEL_LIST"
exit 0
fi
if [ "$TARGET" == "resolve" ]
then
echo "Marking this issue as resolved with a resolution status of $RESOLUTION"
if [ "$RESOLUTION" == "duplicate" ]
then
gh issue comment $ISSUE --body "Marking this issue as a duplicate of #$RESOLUTION_ID"
fi
LABEL_LIST="$LABEL_LIST,resolved: $RESOLUTION"
LABEL_LIST=$(echo $LABEL_LIST | sed -e"s/^,\+//" -e"s/,\{2,\}/,/g" -e"s/,\+$//")
gh issue edit $ISSUE --add-label "$LABEL_LIST"
fi
if [ "$TARGET" == "openssl" ]
then
echo "Marking this issue as needing openssl work"
LABEL_LIST=$(echo $LABEL_LIST | sed -e"s/^,\+//" -e"s/,\{2,\}/,/g" -e"s/,\+$//")
gh issue edit $ISSUE --add-label "$LABEL_LIST"
ISSUE_URL=$(gh issue view $ISSUE --json url --jq '.url')
echo "Adding issue to project board"
ISSUE_ID=$(gh project item-add --owner openssl 2 --url $ISSUE_URL --format json --jq '.id')
echo "Gathering project field info"
PROPOSED_RELEASE_ID=$(gh project field-list --owner openssl 2 --format json --jq ".fields[] | select(.name == \"Proposed Release\") | .options[] | select(.name == \"$RELEASE\") | .id")
PRIORITY_ID=$(gh project field-list --owner openssl 2 --format json --jq ".fields[] | select(.name == \"Priority\") | .options[] | select(.name == \"$PRIORITY\") | .id")

echo "Setting proposed release for issue"
gh project item-edit --id $ISSUE_ID --project-id $GH_PROJECT_ID --field-id $GH_PROPOSED_RELEASE_FIELD --single-select-option-id $PROPOSED_RELEASE_ID

echo "Setting priority for issue"
gh project item-edit --id $ISSUE_ID --project-id $GH_PROJECT_ID --field-id $GH_PRIORITY_FIELD --single-select-option-id $PRIORITY_ID
fi
}

tool_startup
load_github_ids
parse_options $*
validate_options
process_issue
88 changes: 88 additions & 0 deletions triage/git-triage-help
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash

TMPFILE=$(mktemp /tmp/gittriage.XXXXXX)

function cleanup {
rm -f $TMPFILE
}

trap cleanup EXIT

cat << EOF > $TMPFILE
.TH git-triage
.SH NAME
git triage \- list and evaluate issues in a repository
.SH SYNOPSIS
.B git triage [subcommand] [options]
.RI
.SH DESCRIPTION
The git triage commands is intended to make the role of the bug wrangler in the
openssl project easier and more consistent. It is meant to isolate the
determined disposition of an issue from the specific labels/states needed in a
given issue to arrive at said disposition. Ideally a user should be able to
use this tool to list untriaged issues, set a determined disposition on an issue
or request more information to make that determination.
.SH SUBCOMMANDS
.TP
\fBhelp\fR
Print this man page
.TP
\fBrefresh\fR
Delete the git config stored project identifiers that are cached
.TP
\fBlist\fR
List the untriaged issues in a repository
.TP
\fBvalues\fR
List the currently available options for various values
.TP
\fBevaluate [options]\fR
set the disposition of a given issue. See options below for valid dispositions
.SH EVALUATE OPTIONS
.TP
\fBissue=<number>\fR
Select the issue to evaluate
.TP
\fBtype=[bug|feature|documentation|cleanup|performance|refactor|question]\fR
Set the type of issue to triage this as
.TP
\fBurgent=[yes|no]\fR
Boolean to indicate the issue is urgent (CI breakage). Defaults to no
.TP
\fBimportant=[yes|no]\fR
Boolean to indicate the issue is important. Required
.TP
\fBregression=[yes|no]\fR
Boolean to mark the issue as a regression. Required
.TP
\fBtarget=[openssl|community|followup|resolve]\fR
.P
Tells triage how to target the issue. If openssl is selected, then the issue
will be placed on the backlog for openssl staff to evaluate further
If community is selected, the issue will be marked as needing community
contributions to complete
If followup is selected, a comment is added to the issue requesting further
input to properly evaluate the issue, and is left on the list of issues to
triage
If resolve is selected, the issues is labeled as resolved, but not closed.
This label can be used in subsequent searches for closing later after a
period of time has passed for the reporter to contest the resolution
.TP
\fBrelease=[<release selection>|future|list]\fR
.P
selects the target release for an issue. Must be any of the defined release
targets. If future is selected, the issue is placed in the general backlog.
If list is selected, the list of available releaes targets is printed and no
action is taken
EOF

man $TMPFILE
8 changes: 8 additions & 0 deletions triage/git-triage-list
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

INSTDIR=$(dirname $0)
source $INSTDIR/triage-common.sh

tool_startup
list_untriaged_issues

0 comments on commit d595ea2

Please sign in to comment.