Skip to content

Instantly share code, notes, and snippets.

@StevenACoffman
Last active August 20, 2021 04:11
Show Gist options
  • Save StevenACoffman/b2f4d5782586161712a9e0d8a9d645cf to your computer and use it in GitHub Desktop.
Save StevenACoffman/b2f4d5782586161712a9e0d8a9d645cf to your computer and use it in GitHub Desktop.
Create Github pull request from JIRA and git

Create Github Pull Request from commmand line using git and JIRA information

This script will use the git topic branch name to look up the JIRA story. It will pull the summary and description from JIRA assuming the topic branch name matches the JIRA issue. It converts the Jira flavored markdown to github flavored markdown. It will create a github pull request with github flavored markdown description.

NOTE: Change the JIRA_URL to match your own!

Installation

$ npm install -g j2m
$ brew install jq curl hub
$ source git_jira_github_pull_request.sh

Usage

$ make_pull

Caveats

  • Adding JIRA_LOGIN and/or JIRA_PASSWORD to the environment will mean you won't be prompted for them.
  • If you have local changes that have not been pushed to origin, you get a horrible error message Unprocessable Entity (HTTP 422) Invalid value for "head". Just push first and you're ok.
  • Hub requires an access token, and if you don't have one, on first invocation it will ask for your github userid and password to generate one for you. You can avoid this by doing it manually:
    1. Create a Personal Access Token on Github. This acts as an OAuth token
    2. Save the following information (substitute ACCESS_TOKEN with the real value) in ~/.config/hub:
github.com:
- user: StevenACoffman
  oauth_token: ACCESS_TOKEN
  protocol: https
  • If you don't have j2m installed, it falls back to just using the Jira markdown
#!/bin/bash
function safe_curl() {
# call this with a url argument, e.g.
# safecurl.sh "http://eureka.test.cirrostratus.org:8080/eureka/v2/apps/"
# separating the (verbose) curl options into an array for readability
hash curl 2>/dev/null || { echo >&2 "I require curl but it's not installed. Aborting."; exit 1; }
hash jq 2>/dev/null || { echo >&2 "I require jq but it's not installed. Aborting."; exit 1; }
hash sed 2>/dev/null || { echo >&2 "I require sed but it's not installed. Aborting."; exit 1; }
curl_args=(
-H 'Accept:application/json'
-H 'Content-Type:application/json'
--write '\n%{http_code}\n'
--fail
--silent
)
#echo "${curl_args[@]}"
# prepend some headers, but pass on whatever arguments this script was called with
output=$(curl "${curl_args[@]}" "$@")
return_code=$?
if [ 0 -eq $return_code ]; then
# remove the "http_code" line from the end of the output, and parse it
echo "$output" | sed '$d' | jq .
else
# echo to stderr so further piping to jq will process empty output
>&2 echo "Failure: code=$output"
fi
}
function wti() {
# What The Issue: Find the Jira issue from the topic
JIRA_URL="https://jira.atlassian.com"
JIRA_API_URI="/rest/api/2/"
# getting login fo JIRA
if [[ -z $JIRA_LOGIN ]]; then
read -p "Enter your login for JIRA: " JIRA_LOGIN
fi
# getting password fo JIRA
if [[ -z $JIRA_PASSWORD ]]; then
read -p "Enter your login for JIRA: " JIRA_PASSWORD
fi
# e.g. CORE-5339
RESULT=$(safe_curl -u "$JIRA_LOGIN:$JIRA_PASSWORD" -X GET "${JIRA_URL}${JIRA_API_URI}issue/${1}" | jq '{"key": .key, "summary": .fields.summary, "description": .fields.description}')
KEY=$(echo $RESULT | jq -r '.key')
SUMMARY=$(echo $RESULT | jq -r '.summary')
DESCRIPTION=$(echo $RESULT | jq -r '.description')
}
function jira_pull() {
# Formats a nice pull request message from a JIRA ticket
# NOTE: requires jq
# brew install jq
# NOTE: Does not currently use j2m to convert jira markdown to github
# npm install -g j2m
hash curl 2>/dev/null || { echo >&2 "I require curl but it's not installed. Run 'brew install curl' and try again. Aborting."; exit 1; }
hash jq 2>/dev/null || { echo >&2 "I require jq but it's not installed. Run 'brew install jq' and try again. Aborting."; exit 1; }
JIRA_URL="https://jira.atlassian.com"
# getting login fo JIRA
if [[ -z $JIRA_LOGIN ]]; then
read -p "Enter your login for JIRA: " JIRA_LOGIN
fi
# getting password fo JIRA
if [[ -z $JIRA_PASSWORD ]]; then
read -p "Enter your login for JIRA: " JIRA_PASSWORD
fi
JIRA_API_URI="/rest/api/2/"
curl_args=(
-u "$JIRA_LOGIN:$JIRA_PASSWORD"
-X GET
--write '\n%{http_code}\n'
--fail
--silent
"${JIRA_URL}${JIRA_API_URI}issue/${1}"
)
#echo "${curl_args[@]}"
# prepend some headers, but pass on whatever arguments this script was called with
output=$(curl "${curl_args[@]}" "$@")
# Warning: Curl is weird about escaping special characters in passwords
RESULT=$(safe_curl "${curl_args[@]}" | jq '{"key": .key, "summary": .fields.summary, "description": .fields.description}')
# Preserve whitespace
IFS='🍔'
KEY=$(echo "${RESULT}" | jq -r '.key')
SUMMARY=$(echo "${RESULT}" | jq -r '.summary')
# JIRA numbered lists converted to Github numbered lists with sed
JIRA_DESCRIPTION=$(echo "${RESULT}" | jq -r '.description' | sed -E 's/^([\t| ]*)(# )([-\w]*)?/\11. \3/p')
if hash j2m 2>/dev/null; then
GITHUB_DESCRIPTION=$(echo "${JIRA_DESCRIPTION}" | j2m --toM --stdin)
else
GITHUB_DESCRIPTION="${JIRA_DESCRIPTION}"
fi
echo "${KEY}: ${SUMMARY}"
echo ""
echo "Resolves [${KEY}](https://jira.jstor.org/browse/${KEY})"
echo ""
echo "###### Description"
echo "${GITHUB_DESCRIPTION}"
echo ""
echo "###### Notify these people"
echo "@ithaka/cypress"
unset IFS
}
function make_pull() {
# NOTE: Your topic branch must match jira issue e.g. CORE-5339
# Opens a pull request on GitHub for the project that the "origin"
# The description will be lifted from JIRA
# This command will abort operation if it detects that
# the current topic branch has local commits that are not yet pushed
# to its upstream branch on the remote.
# ALSO NOTE: requires hub. Install it with:
# brew install hub curl jq
hash git 2>/dev/null || { echo >&2 "I require git but it's not installed. Run 'brew install git' and try again. Aborting."; exit 1; }
hash hub 2>/dev/null || { echo >&2 "I require hub but it's not installed. Run 'brew install hub' and try again. Aborting."; exit 1; }
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
# Preserve whitespace by setting IFS to something unlikely
IFS='🍔'
MESSAGE="$(jira_pull "${CURRENT_BRANCH}")"
# If when you execute the next line (hub) you get the error:
# Unprocessable Entity (HTTP 422) Invalid value for "head"
# Then you forgot to push. Yeah. Non-obvious
hub pull-request -o -m "${MESSAGE}"
RETVAL=$?
[ $RETVAL -ne 0 ] && echo "You forgot to push if you got Unprocessable Entity (HTTP 422)"
unset IFS
}
@DTrejo
Copy link

DTrejo commented Aug 20, 2021

I just added another one you might like too: https://github.com/DTrejo/dotfiles/blob/main/bin/issue

It adds an issue to an existing PR

cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment