How to extract jira issue ticket in bash script?

gulam abbas
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
April 19, 2022

I am trying to atomatize my git commits with bash functions so that they add a text before each commit if they detect that they are on a branch with a jira ticket.

For example I am working on a new issue and the branch is called bugfix/MR2-71-sidebar-modification where MR2-71 is the jira ticket number. I would like to find a general way to find as many cases as possible.

The bash functions I have are as follows

function getIssueName() {
local string="$(git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')"

# Extract the issue name from the branch name with regex without perl
# For example extract MR2-16 of the string feature/MR2-16-requests-list
# string variable will be feature/MR2-16-requests-list
# issueName variable will be MR2-123 only
local issueName="$(echo "$string" | sed -e 's/feature\/\(.*\)-.*/\1/' -e 's/bugfix\/\(.*\)-.*/\1/' -e 's/hotfix\/\(.*\)-.*/\1/' -e 's/release\/\(.*\)-.*/\1/' -e 's/\(.*\)-.*/\1/')"

# if issueName is empty or equal to string then return empty
if [ -z "$issueName" ] || [ "$issueName" = "$string" ]; then
echo ""
else
echo "$issueName"
fi
}
but issueName variable does not seem to have the ticket number correctly, as it sometimes brings extra string. for example MR2-71-sidebar-mod or MR2-75-table

Example content of the string variable (one for each line):

bugfix/MR2-38-refactor-routes-for-requests-list
bugfix/MR2-39-default-sorting-order-in-requests-list
feature/MR2-17-feature-clients-list
feature/MR2-34-laravel-9-upgrade


Example of the result that the function getIssueName should return (one for each line):

MR2-38
MR2-39
MR2-17
MR2-34

Any idea how to extract the issue number and make the function work in any case?

For example something like [aA-zZZ]-[0-9] (sorry I know almost nothing about regex)

3 answers

1 vote
Phill Pafford
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 6, 2023

I took a slightly different approach, find all jira tickets between two tags

https://gist.github.com/phillpafford/6081ee928762b1200722af499dab0418

 

#!/usr/bin/env bash

set -e


## https://confluence.atlassian.com/adminjiraserver/configuring-jira-application-options-938847824.html
## Project Key Length: Default: 10

JIRA_REGEX='[A-Z]{2,10}-[0-9]{1,7}'
JIRA_TICKET=()

# Set the tags
TAG_LATEST=$(git tag --sort=taggerdate | tail -1)
TAG_PREVIOUS=$(git tag --sort=taggerdate | tail -2 | head -n 1)

echo "TAG_LATEST: $TAG_LATEST"
echo "TAG_PREVIOUS: $TAG_PREVIOUS"

# Print the commits between the two tags
GIT_LOG=$(git log --pretty=format:%s $TAG_LATEST...$TAG_PREVIOUS)

while IFS= read -r line; do

## check for jira ticket regex in comment message
if [[ "$line" =~ $JIRA_REGEX ]]; then

## match found
if [[ ${BASH_REMATCH[0]} ]]; then

## push to array
JIRA_MATCH="${BASH_REMATCH[0]}"
JIRA_TICKET+=($JIRA_MATCH)
fi

fi

done <<< "$GIT_LOG"

## unique JIRA_TICKET
JIRA_TICKET=($(for jt in "${JIRA_TICKET[@]}"; do echo "${jt}"; done | sort -u))

FOUND_JIRA_TICKET=${#JIRA_TICKET[@]}
echo "FOUND_JIRA_TICKET: $FOUND_JIRA_TICKET"

if [ $FOUND_JIRA_TICKET -gt 0 ]; then
echo "Jira Tickets"
printf '%s\n' "${JIRA_TICKET[@]}"
fi

## end
1 vote
hamish fleming
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
June 9, 2022

Hey Here is my pre-commit git hook to do exactly that, it's not perfect by any means, as it appends the ticket id in '[]' at the end of every line this isn't an issue for me as most of my commits are one-liners and anything more complex can be ran with the --skip-validation hooks

BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)

# Ensure BRANCH_NAME is not empty and is not in a detached HEAD state (i.e. rebase).
# SKIP_PREPARE_COMMIT_MSG may be used as an escape hatch to disable this hook,
# while still allowing other githooks to run.
if [ ! -z "$BRANCH_NAME" ] && [ "$BRANCH_NAME" != "HEAD" ] && [ "$SKIP_PREPARE_COMMIT_MSG" != 1 ]; then

PREFIX_PATTERN='[A-Z]{2,5}-[0-9]{1,4}'

[[ $BRANCH_NAME =~ $PREFIX_PATTERN ]]

PREFIX=${BASH_REMATCH[0]}

PREFIX_IN_COMMIT=$(grep -c "\[$PREFIX\]" $1)

# Ensure PREFIX exists in BRANCH_NAME and is not already present in the commit message
if [[ -n "$PREFIX" ]] && ! [[ $PREFIX_IN_COMMIT -ge 1 ]]; then
sed -i.bak -e " s/$/ $PREFIX/" $1
fi

fi

and an assortment of references that helped me along the way

# - https://stackoverflow.com/questions/34213120/find-branch-name-during-git-rebase
# - https://github.com/typicode/husky/issues/311#issuecomment-580237182
# - https://gmurphey.github.io/2013/02/02/ignoring-git-hooks-when-rebasing.html#.XkK1AhNKjOQ
# - https://mikemadisonweb.github.io/2018/12/18/git-hook-prepending-commit-message/
# - https://stackoverflow.com/questions/5894946/how-to-add-gits-branch-name-to-the-commit-message

0 votes
paulypopex
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
September 20, 2023
#!/usr/bin/env bash

# based on Hamish's super helpful script, some small tweaks

# 1. pass "1" to sed to only edit the first line
# 2. try sed with and without the .back, for osx or linux
# 3. strip comments before looking for jira number, as branch always appears in comments for me

BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD 2> /dev/null)
# Ensure BRANCH_NAME is not empty and is not in a detached HEAD state (i.e. rebase).
# SKIP_PREPARE_COMMIT_MSG may be used as an escape hatch to disable this hook,
# while still allowing other githooks to run.
if [ ! -z "$BRANCH_NAME" ] && [ "$BRANCH_NAME" != "HEAD" ] && [ "$SKIP_PREPARE_COMMIT_MSG" != 1 ]; then
JIRA_PATTERN='[A-Z]{3,4}-[0-9]{2,5}'
  [[ $BRANCH_NAME =~ $JIRA_PATTERN ]]
  JIRA=${BASH_REMATCH[0]}
  JIRA_IN_COMMIT=$(grep "$JIRA" $1 | grep -v ^# -c)
  # Ensure JIRA exists in BRANCH_NAME and is not already present in the commit message
  if [[ -n "$JIRA" ]] && ! [[ $JIRA_IN_COMMIT -ge 1 ]]; then
    sed -i "1 s/^/$JIRA: \n/" $1 2> /dev/null || sed -i .bak "1 s/$/ $JIRA/" $1
  fi
fi

 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events