Skip to content

Commit 4238af3

Browse files
DEVEX-723: fix shell syntax errors in jira-ticket-check (#104)
fix: use env vars for PR body/title to avoid shell syntax errors
1 parent 9babf66 commit 4238af3

1 file changed

Lines changed: 82 additions & 72 deletions

File tree

.github/workflows/jira-ticket-check.yaml

Lines changed: 82 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,25 @@ jobs:
4949

5050
- name: Extract Jira ticket from branch name
5151
id: branch-check
52+
env:
53+
BRANCH_NAME: ${{ github.head_ref }}
54+
JIRA_PROJECT_PATTERN: ${{ inputs.jira-project-pattern }}
5255
run: |
53-
BRANCH_NAME="${{ github.head_ref }}"
54-
JIRA_PROJECT_PATTERN="${{ inputs.jira-project-pattern }}"
55-
if [ -z "$JIRA_PROJECT_PATTERN" ]; then
56-
JIRA_PROJECT_PATTERN="[A-Za-z]+"
56+
PATTERN="$JIRA_PROJECT_PATTERN"
57+
if [ -z "$PATTERN" ]; then
58+
PATTERN="[A-Za-z]+"
5759
else
5860
# Make pattern case-insensitive by adding both cases if it's a simple pattern
59-
# For complex patterns, rely on grep -i flag
60-
JIRA_PROJECT_PATTERN=$(echo "$JIRA_PROJECT_PATTERN" | sed 's/\[A-Z\]\+/[A-Za-z]+/g' | sed 's/\[A-Z\]/[A-Za-z]/g')
61+
PATTERN=$(echo "$PATTERN" | sed 's/\[A-Z\]\+/[A-Za-z]+/g' | sed 's/\[A-Z\]/[A-Za-z]/g')
6162
fi
62-
JIRA_PATTERN="${JIRA_PROJECT_PATTERN}-[0-9]+"
63-
63+
JIRA_PATTERN="${PATTERN}-[0-9]+"
64+
6465
if [ -z "$BRANCH_NAME" ]; then
6566
echo "ticket=" >> $GITHUB_OUTPUT
6667
echo "found_in=" >> $GITHUB_OUTPUT
6768
exit 0
6869
fi
69-
70+
7071
# Case-insensitive search
7172
if echo "$BRANCH_NAME" | grep -qiE "$JIRA_PATTERN"; then
7273
TICKET=$(echo "$BRANCH_NAME" | grep -oiE "$JIRA_PATTERN" | head -1)
@@ -77,31 +78,32 @@ jobs:
7778
echo "✅ Found Jira ticket in branch name: $TICKET"
7879
exit 0
7980
fi
80-
81+
8182
echo "ticket=" >> $GITHUB_OUTPUT
8283
echo "found_in=" >> $GITHUB_OUTPUT
8384
8485
- name: Extract Jira ticket from PR title
8586
id: pr-title-check
8687
if: steps.branch-check.outputs.ticket == ''
88+
env:
89+
PR_TITLE: ${{ github.event.pull_request.title }}
90+
JIRA_PROJECT_PATTERN: ${{ inputs.jira-project-pattern }}
8791
run: |
88-
PR_TITLE="${{ github.event.pull_request.title }}"
89-
JIRA_PROJECT_PATTERN="${{ inputs.jira-project-pattern }}"
90-
if [ -z "$JIRA_PROJECT_PATTERN" ]; then
91-
JIRA_PROJECT_PATTERN="[A-Za-z]+"
92+
PATTERN="$JIRA_PROJECT_PATTERN"
93+
if [ -z "$PATTERN" ]; then
94+
PATTERN="[A-Za-z]+"
9295
else
9396
# Make pattern case-insensitive by adding both cases if it's a simple pattern
94-
# For complex patterns, rely on grep -i flag
95-
JIRA_PROJECT_PATTERN=$(echo "$JIRA_PROJECT_PATTERN" | sed 's/\[A-Z\]\+/[A-Za-z]+/g' | sed 's/\[A-Z\]/[A-Za-z]/g')
97+
PATTERN=$(echo "$PATTERN" | sed 's/\[A-Z\]\+/[A-Za-z]+/g' | sed 's/\[A-Z\]/[A-Za-z]/g')
9698
fi
97-
JIRA_PATTERN="${JIRA_PROJECT_PATTERN}-[0-9]+"
98-
99+
JIRA_PATTERN="${PATTERN}-[0-9]+"
100+
99101
if [ -z "$PR_TITLE" ]; then
100102
echo "ticket=" >> $GITHUB_OUTPUT
101103
echo "found_in=" >> $GITHUB_OUTPUT
102104
exit 0
103105
fi
104-
106+
105107
# Case-insensitive search
106108
if echo "$PR_TITLE" | grep -qiE "$JIRA_PATTERN"; then
107109
TICKET=$(echo "$PR_TITLE" | grep -oiE "$JIRA_PATTERN" | head -1)
@@ -112,85 +114,87 @@ jobs:
112114
echo "✅ Found Jira ticket in PR title: $TICKET"
113115
exit 0
114116
fi
115-
117+
116118
echo "ticket=" >> $GITHUB_OUTPUT
117119
echo "found_in=" >> $GITHUB_OUTPUT
118120
119121
- name: Extract Jira ticket from PR description
120122
id: pr-description-check
121123
if: steps.pr-title-check.outputs.ticket == ''
124+
env:
125+
PR_BODY: ${{ github.event.pull_request.body }}
126+
JIRA_PROJECT_PATTERN: ${{ inputs.jira-project-pattern }}
122127
run: |
123-
# Use printf instead of echo to safely handle special characters
124-
PR_BODY=$(printf '%s' "${{ github.event.pull_request.body }}")
125-
JIRA_PROJECT_PATTERN="${{ inputs.jira-project-pattern }}"
126-
if [ -z "$JIRA_PROJECT_PATTERN" ]; then
127-
JIRA_PROJECT_PATTERN="[A-Za-z]+"
128+
PATTERN="$JIRA_PROJECT_PATTERN"
129+
if [ -z "$PATTERN" ]; then
130+
PATTERN="[A-Za-z]+"
128131
else
129132
# Make pattern case-insensitive by adding both cases if it's a simple pattern
130-
# For complex patterns, rely on grep -i flag
131-
JIRA_PROJECT_PATTERN=$(printf '%s' "$JIRA_PROJECT_PATTERN" | sed 's/\[A-Z\]\+/[A-Za-z]+/g' | sed 's/\[A-Z\]/[A-Za-z]/g')
133+
PATTERN=$(echo "$PATTERN" | sed 's/\[A-Z\]\+/[A-Za-z]+/g' | sed 's/\[A-Z\]/[A-Za-z]/g')
132134
fi
133-
JIRA_PATTERN="${JIRA_PROJECT_PATTERN}-[0-9]+"
134-
135+
JIRA_PATTERN="${PATTERN}-[0-9]+"
136+
135137
if [ -z "$PR_BODY" ]; then
136138
echo "ticket=" >> $GITHUB_OUTPUT
137139
echo "found_in=" >> $GITHUB_OUTPUT
138140
exit 0
139141
fi
140-
141-
# Case-insensitive search - use printf to safely pass content to grep
142-
if printf '%s' "$PR_BODY" | grep -qiE "$JIRA_PATTERN"; then
143-
TICKET=$(printf '%s' "$PR_BODY" | grep -oiE "$JIRA_PATTERN" | head -1)
142+
143+
# Case-insensitive search
144+
if echo "$PR_BODY" | grep -qiE "$JIRA_PATTERN"; then
145+
TICKET=$(echo "$PR_BODY" | grep -oiE "$JIRA_PATTERN" | head -1)
144146
# Normalize to uppercase for Jira API (Jira ticket keys are uppercase)
145-
TICKET=$(printf '%s' "$TICKET" | tr '[:lower:]' '[:upper:]')
147+
TICKET=$(echo "$TICKET" | tr '[:lower:]' '[:upper:]')
146148
echo "ticket=$TICKET" >> $GITHUB_OUTPUT
147149
echo "found_in=pr_description" >> $GITHUB_OUTPUT
148150
echo "✅ Found Jira ticket in PR description: $TICKET"
149151
exit 0
150152
fi
151-
153+
152154
echo "ticket=" >> $GITHUB_OUTPUT
153155
echo "found_in=" >> $GITHUB_OUTPUT
154156
155157
- name: Extract Jira ticket from commits
156158
id: commit-check
157159
if: steps.pr-description-check.outputs.ticket == ''
160+
env:
161+
CHECK_COMMITS: ${{ inputs.check-commits }}
162+
JIRA_PROJECT_PATTERN: ${{ inputs.jira-project-pattern }}
163+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
164+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
158165
run: |
159-
CHECK_COMMITS="${{ inputs.check-commits }}"
160166
if [ "$CHECK_COMMITS" != "true" ]; then
161167
echo "ticket=" >> $GITHUB_OUTPUT
162168
echo "found_in=" >> $GITHUB_OUTPUT
163169
exit 0
164170
fi
165-
166-
JIRA_PROJECT_PATTERN="${{ inputs.jira-project-pattern }}"
167-
if [ -z "$JIRA_PROJECT_PATTERN" ]; then
168-
JIRA_PROJECT_PATTERN="[A-Z]+"
171+
172+
PATTERN="$JIRA_PROJECT_PATTERN"
173+
if [ -z "$PATTERN" ]; then
174+
PATTERN="[A-Z]+"
169175
fi
170-
JIRA_PATTERN="${JIRA_PROJECT_PATTERN}-[0-9]+"
171-
BASE_SHA="${{ github.event.pull_request.base.sha }}"
172-
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
173-
176+
JIRA_PATTERN="${PATTERN}-[0-9]+"
177+
174178
if [ -z "$BASE_SHA" ] || [ -z "$HEAD_SHA" ]; then
175179
echo "ticket=" >> $GITHUB_OUTPUT
176180
echo "found_in=" >> $GITHUB_OUTPUT
177181
exit 0
178182
fi
179-
183+
180184
# Get all commit messages between base and head
181185
COMMIT_MESSAGES=$(git log --pretty=format:"%s" ${BASE_SHA}..${HEAD_SHA} 2>/dev/null || echo "")
182-
183-
# Case-insensitive search - use printf to safely pass content to grep
184-
if [ -n "$COMMIT_MESSAGES" ] && printf '%s' "$COMMIT_MESSAGES" | grep -qiE "$JIRA_PATTERN"; then
185-
TICKET=$(printf '%s' "$COMMIT_MESSAGES" | grep -oiE "$JIRA_PATTERN" | head -1)
186+
187+
# Case-insensitive search
188+
if [ -n "$COMMIT_MESSAGES" ] && echo "$COMMIT_MESSAGES" | grep -qiE "$JIRA_PATTERN"; then
189+
TICKET=$(echo "$COMMIT_MESSAGES" | grep -oiE "$JIRA_PATTERN" | head -1)
186190
# Normalize to uppercase for Jira API (Jira ticket keys are uppercase)
187-
TICKET=$(printf '%s' "$TICKET" | tr '[:lower:]' '[:upper:]')
191+
TICKET=$(echo "$TICKET" | tr '[:lower:]' '[:upper:]')
188192
echo "ticket=$TICKET" >> $GITHUB_OUTPUT
189193
echo "found_in=commits" >> $GITHUB_OUTPUT
190194
echo "✅ Found Jira ticket in commit messages: $TICKET"
191195
exit 0
192196
fi
193-
197+
194198
echo "ticket=" >> $GITHUB_OUTPUT
195199
echo "found_in=" >> $GITHUB_OUTPUT
196200
@@ -216,33 +220,36 @@ jobs:
216220
217221
- name: Fail if no Jira ticket found
218222
if: steps.final-ticket.outputs.ticket == ''
223+
env:
224+
FAIL_ON_MISSING: ${{ inputs.fail-on-missing }}
225+
CHECK_COMMITS: ${{ inputs.check-commits }}
226+
BRANCH_NAME: ${{ github.head_ref }}
227+
PR_TITLE: ${{ github.event.pull_request.title }}
219228
run: |
220-
FAIL_ON_MISSING="${{ inputs.fail-on-missing }}"
221229
if [ "$FAIL_ON_MISSING" != "true" ] && [ -n "$FAIL_ON_MISSING" ]; then
222230
echo "⚠️ No Jira ticket found, but fail-on-missing is disabled"
223231
exit 0
224232
fi
225-
233+
226234
# Default to true if not specified (for direct PR triggers)
227235
if [ -z "$FAIL_ON_MISSING" ]; then
228236
FAIL_ON_MISSING="true"
229237
fi
230-
238+
231239
if [ "$FAIL_ON_MISSING" != "true" ]; then
232240
exit 0
233241
fi
234-
242+
235243
echo "❌ No Jira ticket found in branch name, PR title, PR description"
236-
CHECK_COMMITS="${{ inputs.check-commits }}"
237244
if [ "$CHECK_COMMITS" == "true" ]; then
238245
echo " or commit messages."
239246
else
240247
echo "."
241248
fi
242249
echo ""
243250
echo "Please ensure one of the following contains a Jira ticket key (e.g., DEVEX-600, DEV-123):"
244-
echo " - Branch name: ${{ github.head_ref }}"
245-
echo " - PR title: ${{ github.event.pull_request.title }}"
251+
echo " - Branch name: $BRANCH_NAME"
252+
echo " - PR title: $PR_TITLE"
246253
echo " - PR description"
247254
if [ "$CHECK_COMMITS" == "true" ]; then
248255
echo " - Commit messages"
@@ -254,31 +261,31 @@ jobs:
254261
- name: Verify ticket exists in Jira
255262
id: verify-ticket
256263
if: steps.final-ticket.outputs.ticket != ''
264+
env:
265+
VERIFY_TICKET: ${{ inputs.verify-ticket-exists }}
266+
JIRA_EMAIL: ${{ secrets.JIRA_GITHUB_USER_EMAIL }}
267+
JIRA_TOKEN: ${{ secrets.JIRA_GITHUB_USER_API_TOKEN }}
268+
TICKET: ${{ steps.final-ticket.outputs.ticket }}
269+
JIRA_INSTANCE: ${{ inputs.jira-instance }}
257270
run: |
258-
VERIFY_TICKET="${{ inputs.verify-ticket-exists }}"
259271
# Default to true if not specified (for direct PR triggers or when default is used)
260272
if [ -z "$VERIFY_TICKET" ]; then
261273
VERIFY_TICKET="true"
262274
fi
263-
275+
264276
if [ "$VERIFY_TICKET" = "false" ]; then
265277
echo "⚠️ Ticket verification is disabled, skipping API check"
266278
echo "exists=true" >> $GITHUB_OUTPUT
267279
exit 0
268280
fi
269-
270-
JIRA_EMAIL="${{ secrets.JIRA_GITHUB_USER_EMAIL }}"
271-
JIRA_TOKEN="${{ secrets.JIRA_GITHUB_USER_API_TOKEN }}"
272-
281+
273282
if [ -z "$JIRA_EMAIL" ] || [ -z "$JIRA_TOKEN" ]; then
274283
echo "⚠️ Jira credentials not provided, skipping ticket verification"
275284
echo "⚠️ To enable verification, provide JIRA_GITHUB_USER_EMAIL and JIRA_GITHUB_USER_API_TOKEN secrets"
276285
echo "exists=true" >> $GITHUB_OUTPUT
277286
exit 0
278287
fi
279-
280-
TICKET="${{ steps.final-ticket.outputs.ticket }}"
281-
JIRA_INSTANCE="${{ inputs.jira-instance }}"
288+
282289
if [ -z "$JIRA_INSTANCE" ]; then
283290
JIRA_INSTANCE="revolutionparts.atlassian.net"
284291
fi
@@ -382,9 +389,10 @@ jobs:
382389
383390
- name: Fail if ticket does not exist
384391
if: steps.final-ticket.outputs.ticket != '' && steps.verify-ticket.outputs.exists == 'false'
392+
env:
393+
TICKET: ${{ steps.final-ticket.outputs.ticket }}
394+
JIRA_INSTANCE: ${{ inputs.jira-instance }}
385395
run: |
386-
TICKET="${{ steps.final-ticket.outputs.ticket }}"
387-
JIRA_INSTANCE="${{ inputs.jira-instance }}"
388396
if [ -z "$JIRA_INSTANCE" ]; then
389397
JIRA_INSTANCE="revolutionparts.atlassian.net"
390398
fi
@@ -398,12 +406,14 @@ jobs:
398406
399407
- name: Success message
400408
if: steps.final-ticket.outputs.ticket != '' && (steps.verify-ticket.outputs.exists == 'true' || steps.verify-ticket.outputs.exists == '')
409+
env:
410+
TICKET: ${{ steps.final-ticket.outputs.ticket }}
411+
JIRA_INSTANCE: ${{ inputs.jira-instance }}
412+
FOUND_IN: ${{ steps.final-ticket.outputs.found_in }}
401413
run: |
402-
TICKET="${{ steps.final-ticket.outputs.ticket }}"
403-
JIRA_INSTANCE="${{ inputs.jira-instance }}"
404414
if [ -z "$JIRA_INSTANCE" ]; then
405415
JIRA_INSTANCE="revolutionparts.atlassian.net"
406416
fi
407417
echo "✅ Jira ticket found: $TICKET"
408-
echo " Found in: ${{ steps.final-ticket.outputs.found_in }}"
418+
echo " Found in: $FOUND_IN"
409419
echo " Link: https://${JIRA_INSTANCE}/browse/$TICKET"

0 commit comments

Comments
 (0)