Simplify Current Scripts with HAPI
Learn how to simplify existing ScriptRunner scripts using HAPI, including how to find candidates and what simplified code looks like.
This guidance will include why it's useful to simplify your scripts, how to find scripts that can be simplified, and examples of simplified scripts.
HAPI is an API (application programming interface) for doing common tasks in Jira, including managing issues, searching for issues, updating fields and much more! HAPI is a simple alternative to Jira's regular API and can be used in your Groovy scripts. Go to our main HAPI page to learn more about HAPI.
Why should you simplify your scripts with HAPI?
There are many reasons you should simplify your scripts with HAPI:
- It significantly reduces the complexity of your scripts by abstracting away a lot of the boilerplate code. This ensures your scripts are easier to write and understand.
- Scripts that utilize HAPI are easier to maintain, which means less time troubleshooting when scripts stop working. We maintain HAPI functions, so when Atlassian makes changes to their underlying API, we will ensure that your scripts continue to function correctly without you having to make any changes.
- Scripts that are built using HAPI will be easier to migrate if you decide to move to Jira Cloud. HAPI in ScriptRunner for Jira Cloud works the same as it does in Data Center, however, not all methods that are available in Data Center are available in Cloud (see the Feature Parity page for more details). Scripts that utilize HAPI methods will likely need far fewer modifications to be migrated to ScriptRunner for Jira Cloud.
How to find scripts to simplify
The easiest way to find scripts that can be simplified with HAPI is by using the Script Registry and the HAPI code helper:
Examples of simplifying scripts with HAPI
The examples below illustrate the application of HAPI in script simplification. They demonstrate how HAPI can be utilized to:
- Reduce script length
- Improve code readability
- Enhance script comprehensibility
Validating attachments in a transition (Validator)
The following example is taken from the Validating Attachments/Links In Transitions page.
The following example details how to find properties of attachments added to this transition or on creation, for example the file name:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.attachment.TemporaryWebAttachmentManager
import com.atlassian.jira.issue.fields.AttachmentSystemField
import webwork.action.ActionContext
def temporaryAttachmentManager = ComponentAccessor.getComponent(TemporaryWebAttachmentManager)
def temporaryAttachmentIds = ActionContext.getRequest()?.getParameterValues(AttachmentSystemField.FILETOCONVERT)
temporaryAttachmentIds.each { String attachmentId ->
def attachment = temporaryAttachmentManager.getTemporaryWebAttachment(attachmentId).getOrNull()
if (attachment) {
log.debug "Uploaded attachment name: ${attachment.filename}"
}
}We can simplify the above script with the HAPI attachmentsAddedInTransition method:
issue.attachmentsAddedInTransition.each { attachment ->
log.debug("Uploaded attachment name: ${attachment.filename}")
}Auto close subtask (Custom Post Function)
The following example details how to Resolve all currently open sub-tasks when the parent task is transitioned to Resolved:
import com.atlassian.jira.component.ComponentAccessor
def issueService = ComponentAccessor.getIssueService()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def subTasks = issue.getSubTaskObjects()
subTasks.each {
if (it.statusObject.name == "Open") {
def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.with {
setResolutionId("1") // resolution of "Fixed"
setComment("*Resolving* as a result of the *Resolve* action being applied to the parent.")
setSkipScreenCheck(true)
}
// validate and transition subtask
def validationResult = issueService.validateTransition(user, it.id, 5, issueInputParameters)
if (validationResult.isValid()) {
def issueResult = issueService.transition(user, validationResult)
if (!issueResult.isValid()) {
log.warn("Failed to transition subtask ${it.key}, errors: ${issueResult.errorCollection}")
}
} else {
log.warn("Could not transition subtask ${it.key}, errors: ${validationResult.errorCollection}")
}
}
}We can simplify the above script with the HAPI transition method:
def subTasks = issue.subTaskObjects
subTasks.each { subTask ->
if (subTask.status.name == "Open") {
subTask.transition('Resolve Issue') {
setResolution('Done')
}
}
}Set a custom field value
The following example details how to set the Summary field, and set a custom field called MyCustomFieldType to my value:
issue.summary = 'Cloned issue'
def cf = customFieldManager.getCustomFieldObjects(issue).find {it.name == 'MyCustomFieldType'}
issue.setCustomFieldValue(cf, "my value")We can simplify the above script with the HAPI setCustomFieldValue method:
issue.summary = 'Cloned issue'
issue.setCustomFieldValue('My custom field name', "my value")Related content
Desired data placeholder [DATE_FORMATTED_BY_yyyy-MM-dd]