44
55source " $( dirname " ${BASH_SOURCE[0]} " ) /../shared.bash"
66
7- # Check for required inputs
7+ # Do all the checks up front so we just bail before
8+ # doing any actual work.
9+
810if [ -z " ${ISSUE} " ]; then
911 error " Missing 'issue' input value"
1012 exit 1
@@ -15,6 +17,21 @@ if [ -z "${TRANSITION}" ]; then
1517 exit 1
1618fi
1719
20+ if [ -n " ${FIXED_VERSION} " ] && [ -z " ${RESOLUTION} " ]; then
21+ error " The 'fixed-version' value can only be set if 'resolution' is set"
22+ exit 1
23+ fi
24+
25+ if [ -n " ${FIXED_VERSION} " ] && [ -z " ${PROJECT} " ]; then
26+ error " Missing 'project' input value (must be set if 'fixed-version' is set)"
27+ exit 1
28+ fi
29+
30+ if [ " ${FIXED_VERSION} " == " auto" ] && [ -z " ${TIMELINE_URL} " ]; then
31+ error " Missing 'timeline-url' input value (must be set if 'fixed-version' is 'auto')"
32+ exit 1
33+ fi
34+
1835# Grab the transition ID
1936result=" $( jira-request " ${JIRA_BASE_URL} /rest/api/3/issue/${ISSUE} /transitions" ) " || exit
2037query=" $( printf ' .transitions[] | select(.name == "%s").id' " ${TRANSITION} " ) "
@@ -25,8 +42,15 @@ if [ -z "${transition_id}" ]; then
2542 exit 1
2643fi
2744
28- # If a resolution is set, find it and generate the template
29- # with it included
45+ # Create the initial payload. This will be updated as needed prior
46+ # to sending the request.
47+ template=' {transition: {id: $transition_id}}'
48+ payload=" $( jq -n --arg transition_id " ${transition_id} " " ${template} " ) " || exit
49+
50+ info " Transitioning JIRA issue '%s' to %s (ID: %s)" " ${ISSUE} " \
51+ " ${TRANSITION} " " ${transition_id} "
52+
53+ # If a resolution is set, find it
3054if [ -n " ${RESOLUTION} " ]; then
3155 # Grab the resolution ID
3256 result=" $( jira-request " ${JIRA_BASE_URL} /rest/api/3/resolution" ) " || exit
@@ -38,41 +62,80 @@ if [ -n "${RESOLUTION}" ]; then
3862 exit 1
3963 fi
4064
41- template='
42- {
43- transition: {
44- id: $transition
45- },
46- fields: {
47- resolution: {
48- id: $resolution
49- }
50- }
51- }
52- '
53- issue_transition=" $( jq -n --arg transition " ${transition_id} " --arg resolution " ${resolution_id} " " ${template} " ) " || exit
54- else
55- # No resolution so the template only includes the transition
56- template='
57- {
58- transition: {
59- id: $transition
60- }
61- }
62- '
63- issue_transition=" $( jq -n --arg transition " ${transition_id} " " ${template} " ) " || exit
65+ # Render the data structure for the resolution
66+ template=' {fields: {resolution: {id: $resolution_id}}}'
67+ rendered=" $( jq -n --arg resolution_id " ${resolution_id} " " ${template} " ) " || exit
68+
69+ # Add it to the payload
70+ payload=" $( jq -s ' .[0] * .[1]' <<< " ${payload}${rendered}" ) "
71+
72+ info " Resolving JIRA issue '%s' to %s (ID: %s)" " ${ISSUE} " " ${RESOLUTION} " " ${resolution_id} "
6473fi
6574
66- info " Transitioning JIRA issue '%s' to %s (ID: %s)" " ${ISSUE} " \
67- " ${TRANSITION} " " ${transition_id} "
68- if [ -n " ${resolution_id} " ]; then
69- info " Resolving JIRA issue '%s' as %s (ID: %s)" " ${ISSUE} " \
70- " ${RESOLUTION} " " ${resolution_id} "
75+ # Handle setting fixed versions if set
76+ if [ -n " ${FIXED_VERSION} " ]; then
77+ fixed_versions=()
78+
79+ # First pull the valid versions from jira
80+ project=" $( jira-request " ${JIRA_BASE_URL} /rest/api/3/project/${PROJECT} " ) " || exit
81+ jira_versions=" $( jq -r ' .versions' <<< " ${project}" ) "
82+
83+ # If the fixed version value is auto, attempt to detect versions from pull linked pull request
84+ if [ " ${FIXED_VERSION} " == " auto" ]; then
85+ timeline=" $( curl -sL --show-error --fail-with-body -H " Accept: application/vnd.github+json" " ${TIMELINE_URL} " ) " || exit
86+ filter=' .[] | select(.event == "cross-referenced") | .source.issue.labels.[] | select(.name | startswith("backport")).name'
87+ readarray -t labels < <( jq -r " ${filter} " <<< " ${timeline}" )
88+
89+ for label in " ${labels[@]} " ; do
90+ # start with stripping off the start of the label (backport/ or backport/ent/)
91+ version_prefix=" ${label##*/ } "
92+ # then strip off the end of the label
93+ version_prefix=" ${version_prefix% .x* } "
94+
95+ filter=" $( printf ' .[] | select(.name | contains("%s")).name' " ${version_prefix} " ) "
96+ readarray -t valid_versions < <( jq -r " ${filter} " <<< " ${jira_versions}" )
97+ match=" ${version_prefix} .0"
98+ for v in " ${valid_versions[@]} " ; do
99+ if [ " ${v##* .} " -gt " ${match##* .} " ]; then
100+ match=" ${v} "
101+ fi
102+ done
103+
104+ filter=" $( printf ' .[] | select(.name | endswith("%s")).id' " ${match} " ) "
105+ version_id=" $( jq -r " ${filter} " <<< " ${jira_versions}" ) "
106+ if [ -z " ${version_id} " ]; then
107+ printf " WARNING: Failed to find valid JIRA version to match label: '%s'\n" " ${label} "
108+ continue
109+ fi
110+ fixed_versions+=(jq -n --arg version_id " ${version_id} " ' [{id: $version_id}]' )
111+ done
112+ else
113+ # Match version directly
114+ filter=" $( printf ' .[] | select(.name | endswith("%s")).id' " ${FIXED_VERSION} " ) "
115+ version_id=" $( jq -r " ${filter} " <<< " ${jira_versions}" ) "
116+ if [ -z " ${version_id} " ]; then
117+ printf " WARNING: Failed to find valid JIRA version to match provided version: '%s'\n" " ${FIXED_VERSION} "
118+ else
119+ fixed_versions+=(jq -n --arg version_id " ${version_id} " ' [{id: $version_id}]' )
120+ fi
121+ fi
122+
123+ # If fixed versions are availble, create the data structure
124+ if [ " ${fixed_versions[#]} " -gt " 0" ]; then
125+ template=' {fields: {fixVersions: $versions}}'
126+ # Combine all the versions into a single array
127+ versions=" $( jq -s ' add' <<< " ${fixed_versions[*]}" ) "
128+ # Render the data structure for the fix versions
129+ rendered=" $( jq -n --argjson versions " ${versions} " " ${template} " ) " || exit
130+
131+ # Add it to the payload
132+ payload=" $( jq -s ' .[0] * .[1]' <<< " ${payload}${rendered}" ) "
133+ fi
71134fi
72135
73- info " Transition payload:\n%s" " ${issue_transition } "
136+ info " Transition payload:\n%s" " ${payload } "
74137
75- jira-request --request " POST" --data " ${issue_transition } " \
138+ jira-request --request " POST" --data " ${payload } " \
76139 " ${JIRA_BASE_URL} /rest/api/3/issue/${ISSUE} /transitions" || exit
77140
78141info " JIRA issue '%s' transitioned to %s" " ${ISSUE} " " ${TRANSITION} "
0 commit comments