Automate JIRA Cloud Workflow With Golang
Reduce workload for developers by improving the internal processes for JIRA by automating day to day tours
by Percy Bolmér, August 12, 2021
JIRA is a very popular framework for tracking issues and project management. It allows project leads or scrum masters to set up projects and creates issues that are then assigned to developers. It’s a great framework for working with agile development and tracking the work process of development teams.
JIRA offers a ton of features, but once in a while, the need to control JIRA by backend services can occur. This is a topic that is often forgotten, but sometimes services that help the development team develop faster are great. This can be achieved by creating software that manages JIRA from the backend.
In this article, we will rely on a Cloud-hosted JIRA.
Connecting to JIRA Cloud From a Golang Service
To begin using JIRA, we first need to authenticate and create a connected client. We will need to grab a new API key from the official Atlassian API key management console . You can visit the link and create your API key. At the top, you will see a blue button to create a token. Enter a name so you can relate to the token easily, and remember to save the token. You cannot view it again.
We will be using a Golang package called go-jira. This package will help us easily use the JIRA API but remember you can also use the REST API with regular HTTP. But why reinvent the wheel when somebody has done it for us already?
To connect we need to use three environment variables:
- JIRA_USER = The username of your JIRA user
- JIRA_TOKEN = This is the token that we previously created
- JIRA_URL = The base URL to your JIRA Cloud
I store the environment variables in a .env
file which I load on runtime. This is something I usually do so it’s easy for me to control environment variables for multiple projects. There is a super smooth Golang package called gotdotenv.
Let’s download those packages and then create a new main.go
and a .env
file using the following commands:
mkdir jira-test
cd jira-test
go mod init jira-test
go get github.com/andygrunwald/go-jira
go get github.com/joho/godotenv
touch main.go
touch .env
Update the .env
file with your credentials.
Then open up main.go and make sure the connection works. We will first create a jira.BasicAuthTransport
struct that contains the authentication credentials supplied in the .env file.
The Jira package we use has all domains in the client, so to get user information we use client.User
etc. Here’s the code:
Try executing the program by running and you should see the provided user’s profile.
go run main.go
Listing all Projects and Issues
Simply printing the user profile does not help us. We can do more!
Let’s print all the projects that exist. As I mentioned before, the JIRA client has all domains separated, so just as we used the user domain to perform user queries we will use Project
to perform queries against projects.
We can also search for certain Issues using JQL, which stands for Jira query language. This is a simple query language that is string-based that allows us to narrow down the issues to collect.
Sending the request is done by using the issue domain in the client with the Search function. We begin by using a simple search which we will extend soon.
Let’s update the main.go
to try it out, you will need to change the JQL to match some projects in your own JIRA. We will write a JQL string that filters out only Issues related to a certain project.
project = 'PROJECTNAME'
You can also add more specific filters, like only a certain status or type.
project = 'PROJECTNAME' and Status = 'Done'
project = 'PROJECTNAME' and Type = 'Feature'
Try running it after you’ve changed the JQL, and see if you get proper output. Note that JIRA does limit the number of results that are received to 1,000. So if you have more than 1,000 issues, you might need to apply search options. If you noticed, the Search
function accepts two parameters: one of them is a search option. You can make a simple for loop to drain all issues. The result that is returned from the Search
returns the total amount of issues located, so we can keep searching until we reach the maximum.
The examples of the go-jira
library provide a great example of this, and we will reuse this code. Let’s update the getIssues
to match the example with the following code:
The library offers many more features, such as grabbing all issues from a sprint. Be sure you check the documentation out.
You can also create a new issue by using the client.Issue.Create
. The documentation has a superb example again, and I won’t be creating any issues here. But you can view the list below which is an example made by Andy Grunwald
Transition an Issue
Most of the time. I find that transitioning issues between states is the most common use case. So let’s try moving an issue between one status to another.
JIRA offers great documentation about what a transition is and how it works here.
We will make a function getIssueTransition
that takes in a wanted Status and returns the proper transition to use for that. The transition is important as we do need to ID the transition to move an issue. Here’s the code to do that:
Now that we have the transition needed, we can simply move an issue. Update the filtering so that you get the issue you need, either by updating the JQL or ranging over issues. I’ll make a hardcoded version that searches for a certain issue.
We should implement the transitionIssue
function that is used in the main before you can trigger it. This is a super simple wrapper function around the client.
Execute the program after switching the issue key to the wanted issue and you should see it moved.
Conclusion
You now have the basics of how to integrate with JIRA from a backend service. The JIRA API offers a ton of functionality, and we can’t cover it all here, but you have the basics to get started. The third-party library (go-Jira) is great because it also offers the ability to use unimplemented API endpoints.
Some ideas for automation I’ve seen are all issues that enter a certain state gets filled with information from the Git repository, CI/CD failures get updated automatically, etc.
What you automate is really up to your imagination. There is the ability to modify/change attachments and much more. I hope you find the experience as smooth as I have. You can find the full code for this article on GitHub.
As always, feel free to reach out if there is anything you have questions about.
If you enjoyed my writing, please support future articles by buying me an Coffee