Release Notes with Groovy and JIRA REST API

JIRA is Atlassian‘s kick-ass issue tracker and in use in many projects I’ve been in. In my current project we use JIRA’s release notes after a certain version has been released, but some departments need the release notes fixed inside the created Maven artefact(s). For this we copy the release notes from JIRA into ReleaseNotes.xml to produce a PDF with the docbkx-maven-plugin – a tedious, manual process.

So, I set out to automate a few things: get the release notes from JIRA and convert to DocBook – all programmatically.

groovy-logo-mediumREST is the recommended and supported remote API since JIRA 5.0 so I decided to create a Groovy script which would pull out needed issues. I decided to use the RESTClient from the HTTP Builder project, so dependency below is needed:

<dependency>
	<groupId>org.codehaus.groovy.modules.http-builder</groupId>
	<artifactId>http-builder</artifactId>
	<version>0.5.2</version>
</dependency>

Finally I came up with the following Groovy script. It queries all standard issues from project MYPROJECT which are Resolved or Closed for a specified fix version.

import groovyx.net.http.RESTClient

final String USAGE =
  "Usage: -Djira.username=xxx
     -Djira.password=xxx -Djira.fixVersion=1.0"

String jiraUsername = project.properties['jira.username']
String jiraPassword = project.properties['jira.password']
String jiraFixVersion = project.properties['jira.fixVersion']

println "Getting issues..."
if (!jiraUsername?.trim()) {
    fail("Empty property: jira.username " + USAGE)
}

if (!jiraPassword?.trim()) {
    fail("Empty property: jira.password " + USAGE)
}

if (!jiraFixVersion?.trim()) {
     fail("Empty property: jira.fixVersion " + USAGE)
}

final String JIRA_SEARCH_URL = "http://jira/rest/api/latest/"
// see JIRA docs about search:
// https://docs.atlassian.com/jira/REST/latest/#idp1389824
String JQL = "project = MYPROJECT"
JQL += " AND issuetype in standardIssueTypes()"
JQL += " AND status in (Resolved, Closed)"
JQL += " AND fixVersion = \"${jiraFixVersion}\""

def jira = new RESTClient(JIRA_SEARCH_URL)

def query = [:]
query['os_username'] = jiraUsername
query['os_password'] = jiraPassword
query['jql'] = JQL
query['startAt'] = 0
query['maxResults'] = 1000

try {
    def resp = jira.get(path: "search",
                        contentType: "application/json",
                        query: query)
    assert resp.status == 200
    assert (resp.data instanceof net.sf.json.JSON)
    resp.data.issues.each { issue ->
        println issue.key
    }
    println "Total issues: " + resp.data.total
} catch (groovyx.net.http.HttpResponseException e) {
    if (e.response.status == 400) {
        // HTTP 400: Bad Request, JIRA JQL error
        fail("JIRA query failed: ${e.response.data}", e)
    } else {
        fail("Failure HTTP status ${e.response.status}", e)
    }

}

I’m kickstarting this script with the gmaven-plugin which allows me to get my JIRA credentials from e.g. settings.xml, or when missing: fail() with an exception. The fix version for the JIRA query can be supplied as a property on the command-line.

Now we should do something interesting with the resulting issue(s) we get from JIRA, but I’ll leave that to a next time. 🙂