Create Confluence Page from a JIRA Issue with all the Bells and Whistles

by Garth Leavey on November 2, 2017

Ever wanted to create a Confluence Page with details of a JIRA issue and have it linked back to the JIRA issue?...  This script has an ancestor page configured to nest it under a particular page and also some fields brought in from the JIRA Issue.

This script is being run from aScriptRunner workflow function - Custom script post-function.

You will need the ScriptRunner plugin for this but you already have that! Right?

import com.atlassian.applinks.api.ApplicationLink
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.confluence.ConfluenceApplicationType
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.net.Request
import com.atlassian.sal.api.net.Response
import com.atlassian.sal.api.net.ResponseException
import com.atlassian.sal.api.net.ResponseHandler
import groovy.json.JsonBuilder
import groovy.xml.MarkupBuilder
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.fields.CustomField
import javax.smartcardio.CommandAPDU

def ApplicationLink getPrimaryConfluenceLink() {
def applicationLinkService = ComponentLocator.getComponent(ApplicationLinkService.class)
final ApplicationLink conflLink = applicationLinkService.getPrimaryApplicationLink(ConfluenceApplicationType.class);
conflLink
}
// the issue provided to us in the binding
Issue issue = issue
// if you don't want to create confluence pages based on some criterion like issue type, handle this, eg:
//if (! issue.issueTypeObject.name == "Bug") {
// return
//}
def confluenceLink = getPrimaryConfluenceLink()
assert confluenceLink // must have a working app link set up
def authenticatedRequestFactory = confluenceLink.createAuthenticatedRequestFactory()
// write storage format using an XML builder

//def cField1 = customFieldManager.getCustomFieldObject("customfield_14043")
//def cField1 = customFieldManager.getCustomFieldObject("customfield_10304")
def issueManager = ComponentAccessor.getIssueManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def attachmentManager = ComponentAccessor.getAttachmentManager()
def attachmentPathManager = ComponentAccessor.getAttachmentPathManager().attachmentPath.toString()
def commentMGR = ComponentAccessor.getCommentManager()

//commentMGR.create(issue, ${issue.assignee} ,"This is a test", true)

def attachments = attachmentManager.getAttachments(issue)
def baseURL = ComponentAccessor.getApplicationProperties().getString("jira.baseurl")

def i = 0;

def attachmentURL = [];
//Go through all the attachments on the issue and build the URL's
if (!attachments.isEmpty()){
attachmentManager.getAttachments(issue).each {
attachmentURL[i] = baseURL + "/secure/attachment/" + attachments[i].getId() + "/" + attachments[i].getFilename()
i++
}
}

def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.'ac:structured-macro' ('ac:name': "jira") {
'ac:parameter' ('ac:name': "key", issue.key)
}
// add more paragraphs etc
def x = 0
//xml.p ("Reporter: " + "${issue.reporter}")
xml.table (id: 'Jira Information', border: 1){
tbody {
tr{
th "Completed By:"
td "${issue.assignee}"
}
tr{
th "Requested By:"
td " "
}
tr{
th "Description:"
td "${issue.description}"
}
tr{
th "Methodology:"
td " "
}
tr{
th "Notes:"
td " "
}
tr{
th "Attachments:"
td {
//Add the attachement URLs to the XML.
attachmentURL.each {
a(href:attachmentURL[x], attachments[x].getFilename())
mkp.yieldUnescaped('<br />')
x++
}
}

}
}
}

// print the storage that will be the content of the page
log.debug(writer.toString())
// set the page title - this should be unique in the space or page creation will fail
def pageTitle = issue.key + " " + issue.summary
//def pageBody = ${issue.description}

def params = [
type: "page",
//id: "11599873",
title: pageTitle,
space: [
key: "EEKB" // set the space key - or calculate it from the project or something
],
ancestors: [
[
type: "page",
id: "38363242",
]
],
body: [
storage: [ value: writer.toString(), representation: "storage" ]
//storage: [ value: pageBody, representation: "storage" ]
]
]
authenticatedRequestFactory
.createRequest(Request.MethodType.POST, "rest/api/content")
.addHeader("Content-Type", "application/json")
.setRequestBody(new JsonBuilder(params).toString())
.execute(new ResponseHandler<Response>() {
@Override
void handle(Response response) throws ResponseException {
if(response.statusCode != HttpURLConnection.HTTP_OK) {
throw new Exception(response.getResponseBodyAsString())
}
}
})

 

Topics: JIRA, Confluence, Atlassian Solutions, groovy