3 min read

Start using scripted fields in JIRA with ScriptRunner

Fri, 21 Aug 2015 Jira
Start using scripted fields in JIRA with ScriptRunner

Start using scripted fields in JIRA with ScriptRunner

We've completely overhauled the documentation for ScriptRunner for JIRA. There are more examples documented and they've been unit tested to ensure they stay compatible. Working with scripted fields in JIRA is one of ScriptRunner's most popular uses, allowing you to calculate values from other fields and even external sources and embed them in issues. In this blog we outline some of the key things you need to know about working with scripted fields in JIRA.

You can use Groovy to display a calculated custom field on an issue. The value for a field is calculated at the time an issue is displayed or updated. You could use this to pull in data from an external system or to show a value that's calculated from the other values in the issue or even other those from other issues.

Meet the searchers

It's also possible to search on these values by setting up one of the four searchers that come with ScriptRunner for JIRA. When using a searcher, the value is calculated and stored in the index at the time that the issue is indexed ie. when it is modified or transitioned or when you do a full reindex.

Calculated fields and caching

You can only reliably use a calculated field to display a value that is based on the issue's fields, or subtasks, fields, or linked issues. This is because the value in the Lucene index is only updated when the issue is updated (or a linked issue or sub-task is updated). If you compute some value based on data outside of the current issue, the value in the index may differ from the value displayed on the issue.

JIRA asks the field for the value eight times just for viewing an issue. This means your script will be executed 8 times. To help manage this, there is a thread local cache. For subsequent requests the computed value is just retrieved from the cache. If the issue has a different last update date the cache is invalidated. If your script relies on data from an external system you can invalidate the cache altogether. You should test first, particularly if you are doing things like running complex JQL queries. To disable the cache, add the following line to your code:

 enableCache = {-> false}

That's an example for disabling it completely, you can use any other variables to return a Boolean. You may have to do this if you are computing data from linked issues, however the indexed value should always be correct. If your field relies on data outside its scope and you want to search on it? You can't, JIRA doesn't have this capabilty ?write your own searcher.

Some examples of scripted fields

Calculate a number based on other fields

Let's imagine we have a number field called Severity and we want to calculate a new value that is the product of the priority and severity.

def severity = getCustomFieldValue("Severity")
if (severity) {
    return severity * Integer.parseInt(issue.priorityObject.id)
else {
    return null

Note that I'm careful to test this against an issue that has no Severity value set.

Total time an issue has been in progress

This will show the duration that an issue has been in the In Progress state summing up multiple times if necessary.  

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.history.ChangeItemBean

def componentManager = ComponentManager.getInstance()
def changeHistoryManager = componentManager.getChangeHistoryManager()

def inProgressName = "In Progress"

def rt = [0]
changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {ChangeItemBean item ->

    def timeDiff = System.currentTimeMillis() - item.created.getTime()
    if (item.fromString == inProgressName) {

Use no searcher, and for the template use Free Text. This brings to light a shortcoming of this tool - what we want to do is store and index a duration and have the template print the output. However, we have no template available for that so we just output a string (eg "6 days"), and therefore there is no point in indexing this. As we used no searcher we can't search for issues in progress longer than a week say. This will be addressed in a future version.

Date of First Transition

This sample script field gets the date that an issue was first transitioned through a particular action. If it undergoes the same transition multiple times, only the first date is shown. This can be useful for support workflows where you want to track when the customer was first responded to. NB. Change In Progress to the action name you are interested in.

package com.onresolve.jira.groovy.test.scriptfields.scripts

import com.atlassian.jira.component.ComponentAccessor

def changeHistoryManager = ComponentAccessor.getChangeHistoryManager()
changeHistoryManager.getChangeItemsForField(issue, "status").find {
    it.toString == "In Progress" 

If you want to start using scripted fields in JIRA yourself, download ScriptRunner for JIRA from the Atlassian Marketplace now.

Stay up to date by signing up for monthly Adaptanews