Even after years of developing and deploying software to environments, we took some time to put in place the right tools and integrations in order to manage efficiently our deployments in Atlassian ecosystem.
I am a real big fan of the Deployments timeline (and its underlying API) provided by Jira Software Cloud. In this highly practical post, I want to share our findings and some of our recipes with you.
Deployment is a vast area. Depending of the context it may serve different purposes. Atlassian provides very cool tools to share deployment information in Jira Software:
This gives you a global view of the tickets that have been recently deployed to your various environments on very handy timeline:
This view is really useful to find the tickets that have been recently deployed to your various environments.
Jira Software provides also an easy way to access the deployment status of an issue from its “Development” information tab:
The last deployments of an issue can now also be accessed directly from the “Releases” page:
All these views rely on the Jira Software Cloud Deployment API: https://developer.atlassian.com/cloud/jira/software/rest/api-group-deployments/#api-rest-deployments-0-1-bulk-post that you need to integrate with your deployment pipelines and scripts.
You may have already think: “Well, cool views! but how can I get such accurate deployment information in Jira?”
Tools used to perform deployments are specific to your applications: it may be executed by any kind of combination of custom, esoteric and third party tools. This means that there is no magic/universal way to push deployment information to Jira.
Hopefully Atlassian is providing a Deployment API and a bunch of integrations with major tools used to trigger deployment jobs:
➙ https://support.atlassian.com/jira-cloud-administration/docs/integrate-your-deployments-with-jira/
In our case, we use Jenkins to build and deploy our applications. When certain branches are updated, a Jenkins job is automatically triggered to perform an automatic deployment to our CI/CD test environments. In order to do that properly, we have just followed instructions given here: https://support.atlassian.com/jira-cloud-administration/docs/integrate-jenkins-with-jira/
Here is an extract of our jenkinsfile pipeline that shows the step used to push deployment information to Jira:
// the deployment will be automatically triggered:
// 1) when merging into the 'develop' branch
// 2) if the job is manually launched with the "DEPLOY" param set to true
if (params.DEPLOY || (env.BRANCH_NAME.contains("develop"))) {
stage('deploy to CI environment') {
try {
// Deployment context information
def environmentId = 222 // unique id of your environment
def environmentName = "dev.ci.golive-data-center" // name of your environment
def environmentType = "testing" // check deployment API doc if you want to change it
def jiraSite = "your-jira-software-site.atlassian.net" // url of your Jira Software Cloud
jiraSendDeploymentInfo(
environmentId: environmentId,
environmentName: environmentName,
environmentType: environmentType,
site: jiraSite,
state: 'in_progress'
)
// ...
// do the deployment here
// ...
jiraSendDeploymentInfo(
environmentId: environmentId,
environmentName: environmentName,
environmentType: environmentType,
site: jiraSite,
state: 'successful'
)
} catch (error) {
echo "Not able to deploy to CI environment"
jiraSendDeploymentInfo(
environmentId: environmentId,
environmentName: environmentName,
environmentType: environmentType,
site: jiraSite,
state: 'failed'
)
}
}
}
Now, each time Jenkins performs a deployment, the deployment status as well as the list of deployed tickets are now automatically updated in Jira!
Great News 👍 !!
Have you already asked to your developers to manually update the Jira tickets they worked on once they are deployed? Well… for many reasons you can guess, this is an error prone process and it does not really work well…
It is better, for developers, to push this information when they are done, just before switching to their next task. At this point of time, each developer usually takes some time to summarize what he has done in a clean commit message before pushing and sharing it with the rest of the team. We are now asking to each developer to include the reference of the linked Jira tickets in the commit message. This will automatically create links between Jira tickets and the commits pushed to the central repository. More information here: https://support.atlassian.com/jira-software-cloud/docs/reference-issues-in-your-development-work/
Example of commit message including references of Jira tickets:
git commit -m "TEM-1234 TEM-5677 CS-345: Fix timeline visualization bug"
You can enforce the commit messages to contain a reference to a Jira ticket when pushing their code to Bitbucket Cloud using a git hook. Atlassian has written a nice tutorial about git hooks: https://www.atlassian.com/git/tutorials/git-hooks
In our case, we also wanted to standardize the format of our commit messages using the Conventional Commits format: https://www.conventionalcommits.org/en/v1.0.0/
Here is our .git/hooks/pre-push file that enforces both link to Jira issues and Conventional Commits format:
#!/bin/bash
# install this hook
# run at the root of the git project (-N to avoid recursive build):
# atlas-mvn install -N
#set -e
if [[ "$CI" != "" ]]; then
echo "No pre-push hook for Jenkins, he is not human, he does not need rules."
exit 0
fi
cat <<EOF
★★★ Checking for mandatory tickets ★★★
✎ only chores do not require a ticket in the commit description
✎ an exception can be made by using TEM-0 as ticket.
Let's start !
EOF
upstream=$(git rev-parse --abbrev-ref HEAD@{upstream})
if [[ $? == 0 ]]; then
upstream=origin/develop
fi
hashes=$(git log ${upstream}..HEAD --pretty=oneline | cut -f1 -d' ')
errors=0
function check_for_ticket {
local hash=$1
subject=$(git log -n 1 --pretty=format:%s ${i})
if [[ "$subject" =~ 'chore' ]]; then
echo " ✔ chore has no need for a ticket."
else
regex="([A-Z]{1,3}-[0-9]+)"
if [[ "$(git log -n 1 --pretty=format:%s%b "${hash}")" =~ $regex ]]; then
ticket="${BASH_REMATCH[1]}"
echo " ✔ $ticket was referenced"
else
echo " ✘ MISSING TICKET: no ticket found in commit message!"
errors=$((errors + 1))
fi
fi
}
function check_for_subject_format {
local hash=$1
subject=$(git log -n 1 --pretty=format:%s "${i}")
echo "${subject}"
regex="^(feat|fix|chore|doc|style)(\([a-zA-Z0-9-]*\))?:\s.*$"
if [[ "${subject}" =~ $regex ]]; then
echo ' ✔ commit message looks good.'
else
echo ' ✘ FORMAT: commit message format should follow https://www.conventionalcommits.org/en/v1.0.0/'
errors=$((errors + 1))
fi
}
for i in ${hashes}; do
print_hash=$(echo "${i}" | cut -c-6)
echo -n "⚡ Checking ${print_hash}: "
check_for_subject_format ${i}
check_for_ticket ${i}
done
if [[ ! $errors -eq 0 ]]; then
if [[ $errors -eq 1 ]]; then
echo "There is one error (✘) to fix before pushing this code, exiting."
else
echo "There are ${errors} errors (✘) to fix before pushing this code, exiting."
fi
exit 1
else
echo -e "✔ Good to go !\n"
fi
Example of properly formatted Conventional Commit message including references to Jira tickets:
git commit --all -m "feat(event-scheme): UI enhancements
>
> - correct usage of tabs
> - remove fixed-height (might need further work)
>
> TEM-2800
> "
Never ending questions are now answered in JIRA!
These are really great views and should answer to some recurrent question like these:
can I test the bug fix of TEM-2566 on integration environment?
may you tell me when the feature TEM-3434 will be available in Stage environment?
is the TEM-666 now deployed to Production?
And there are many other variants of such questions that should now be easily answered, just by browsing Jira 😉 !
We love what we have thanks to the integration of the Jira Software Cloud Deployment API but a few use cases cannot natively be addressed by it. Hopefully we found really good alternative solutions that I will share with you in a second part of this article: stay tuned! 😉
Thanks in advance for your comments, we would love getting your own feedback regarding your utilization of this Deployment API.
Enjoy your day! 😉
Guillaume _Apwide_
2 comments