Variables and functions used in a Groovy script

When running Groovy scripts, JMCF makes contextual information available to your script through built-in variables and functions. This document details them. Note that you can also define custom variables in your Groovy script.

On this page:

Variables availability

The variables in JMCF are available on the custom field configuration screen when you write a Groovy script in the Groovy Formula field to return a value expected by a calculated custom field.

Clicking on  provided under the Groovy editor displays the list of available variables.

Available variables

Variable name

Type

Description

Variable name

Type

Description

Variables and functions used in a Groovy script#issue

Issue

The issue variable points to the current issue being processed.

Variables and functions used in a Groovy script#value

String

The value of the calculated field

Variables and functions used in a Groovy script#textutils

TextUtils

textutils is a utility object of class TextUtils providing useful methods to manipulate text and HTML

Variables and functions used in a Groovy script#log

Logger

The log variable is a Logger instance that writes into atlassian-jira.log (useful for debugging)

Variables and functions used in a Groovy script#numberTool

NumberTool

NumberTool instance that can be used to format number values.

 

In JMCF versions prior to 2.0.0, the issue variable was a wrapper around the Issue object that just implemented a get() method to access the value of any field, and the issueObject represented Jira's main Issue object. Now, these two variables are merged into one, issue. This variable now exposes all the methods of Jira's Issue interface as well as additional methods such as get(), getEpic() etc. You can still use the issueObject but it is deprecated and it will be removed in a future version.

issue

The issue variable exposes the methods of the main Issue interface, including methods not native to Jira such as like get()getLinkedIssues() etc. It points to the current issue being processed. You can access the fields of the issue by accessing the properties and methods of this variable.

For example: issue.get("priority").getName() returns the priority of the issue. 

value

The value represents the value of the calculated field returned by the Groovy script in the custom field configuration. This is applicable only while customizing the display of a Calculated (Scripted) Number custom field type to format it using the Variables and functions used in a Groovy script#numberTool variable. The data type of the variable is a Double.  

numberTool

The numberTool variable is a NumberTool instance that can be used to format the value of the calculated field returned by the Groovy script in the custom field configuration. This is applicable only while customizing the display of a Calculated (Scripted) Number custom field type to format it.  

For example: If the value of a calculated number custom field is 22 you can format it using the numberTool variable available in the Groovy editor of the Format Expression field.

To format it to a currency: 

1 numberTool.format('currency',value)

The value is formatted to $40.

To add an IMG tag to display an icon to the left of the number:

1 "<img src='/images/icons/priority_trivial.gif'> "+numberTool.format(value);

So the number is formatted and displayed as 

textutils

The textutils variable is a utility object of class TextUtils providing useful methods to manipulate text and HTML

For example:

textutils.noNull(issue.get("description")) + issue.key returns a text avoiding null in case there is no Description of the issue.

log

The log variable is a Logger instance that is used to output information like errors and warnings into the atlassian-jira.log file located in your Jira home directory. You can also use the log variable to output data to the script tester result panel during script development and debugging. There are five logging levels available in log4j, and they are all output to the script tester result panel. However, by default, only WARN and ERROR level logs are output to the atlassian-jira.log file, so you should only use log.warn(...) and log.error(...) for run-time logging (as opposed to development-time logging). To see other levels in atlassian-jira.log, you can raise the logging level for the com.innovalog package.  

For example: Set a user field with the assignee and be warned when the issue is unassigned.

1 2 3 4 5 6 7 8 9 if(issue?.get("assignee")?.getName()) { return(issue.get("assignee").getName()) } else { log.warn("This issue is unassigned") return null }

So when the issue is unassigned, the warning message is displayed in the atlassian-jira.log file.

Custom variables

In addition to the above variables, you can also define your own variables in the Groovy script.

For example, Condition to check whether the Fix Version/s has a particular version.

1 2 3 4 5 6 7 8 //Define a boolean variable to false boolean isValue = false; //Run a loop on all the current values of the field issue.get("fixVersions").each { if (it.getName == "2.0") isValue = true; } return isValue;

Deprecated variables

Variable name

Type

Description

Variable name

Type

Description

issueObject

Issue

Deprecated. The issueObject variable is a synonym for the issue variable.

Functions

Functions availability

The functions in JMCF are available on the custom field configuration screen when you write a Groovy script in the Groovy Formula field to return a value expected by a calculated custom field.

Available functions

Function Name

Returns

Description

Function Name

Returns

Description

jqlSearch("<JQL expression>", <maxResults>)

List<Issue>

Search for issues using JQL

Variables and functions used in a Groovy script#getComponent(Class interface)

Component/Service

Global function to get a Component/Service from Jira or any loaded add-on


jqlSearch("<JQL expression>", <maxResults>)

jqlSearch("<JQL expression>", <maxResults>)is a simple function that you can use to search for issues using a JQL. The function expects the following:

  • JQL expression: JQL query

  • maxResults: maximum number of issues to return

When you pass a valid JQL query and number of issues, the function returns a List<Issueof issues that match the JQL.

Example: Calculate the Story points of all issues of a specific project and display them on the current issue as Total Story points.

1 2 3 4 5 6 7 issueCount = ComponentAccessor.getIssueManager().getIssueCountForProject("<Project ID>") issues = jqlSearch("project = TP and cf[10006] >= 0",issueCount.intValue()) storyPoints = 0 issues.each{ storyPoints += it.get("Story Points") } storyPoints

getComponent(Class interface)

getComponent(Class interface) is a global function to get a Component/Service from Jira or any loaded add-on. The function expects a Class interface as the parameter. Importing classes from third-party add-ons or some classes of Jira and its Java dependencies is not easy. You need to get the Class loader and find the class followed by getting the Component/Service. For example, to get the RapidViewServiceInterface you had to write the following code:

1 2 3 4 import com.atlassian.jira.component.ComponentAccessor def classLoader = issue.get("Rank").getClass().getClassLoader() def RapidViewServiceIntf = classLoader.findClass("com.atlassian.greenhopper.service.rapid.view.RapidViewService") def RapidViewService = ComponentAccessor.getOSGiComponentInstanceOfType(RapidViewServiceIntf)

But now you can directly import the class and get the Service, as shown below:

1 2 import com.atlassian.greenhopper.service.rapid.view.RapidViewService def RapidViewService = getComponent(RapidViewService);

Note that you can also access the internal components/services that are registered as private (not "public") using this function. For example to get the DevStatusSummaryService from Jira's development integration plugin (which gives access to builds, commits, etc.)

1 2 import com.atlassian.jira.plugin.devstatus.api.DevStatusSummaryService getComponent(DevStatusSummaryService)

Some more examples:

1 2 def issueManager = getComponent(com.atlassian.jira.issue.IssueManager.class) def SprintService = getComponent(com.atlassian.greenhopper.service.sprint.SprintService.class)

secondsBetween(Date from, Date to)

secondsBetween(<Date from>, <Date to>) is a global function that returns a Long representing the number of seconds between two Date objects. It returnsnullif one of the two parameters isnull. For example:

  • 1 secondsBetween(issue.created, issue.duedate)

    returns the number of seconds between the issue creation and the due date.

  • 1 secondsBetween(issue.created, new Date())

    returns the number of seconds from the issue creation to now.

secondsBetween(Date from, Date to, String roundTo)

secondsBetween(<Date from>, <Date to>, String roundTo) is a global function that returns a Long representing the number of seconds between two Date objects optionally rounding the number of seconds to the nearest minute, hour, day or week. It returnsnullif one of the two parameters isnull.

<roundTo>is either "max" or one of "weeks", "days", "hours", "minutes" (or their equivalent: "w", "d", "h", "m"). If the rounding is "max", it will be rounded to the largest unit reached by the duration. For example:

  • If secondsBetween(issue.created, issue.duedate) returns 2 hours 51 minutes,

    1 secondsBetween(issue.created, issue.duedate, "max")

    will be rounded to 10800 seconds (3*60*60 seconds) and will be displayed as 3 hours.

  • If secondsBetween(issue.created, issue.duedate) returns 65328 seconds

    1 secondsBetween(issue.created, issue.duedate, "h")

    will be rounded and displayed as 64800 seconds

workdaysBetween(Date from, Date to)

workdaysBetween(<Date from>, <Date to>) is a global function that returns aLongrepresenting the number of work days (excluding Saturdays and Sundays) between two Dateobjects. It returnsnullif one of the two parameters isnull. For example:

  • 1 workdaysBetween(issue.created, issue.duedate)

    returns the number of days between the issue creation and the due date

  • 1 workdaysBetween(issue.created, new Date())

    returns the number of days from the issue creation to now.

asUser(String username){codeblock}

asUser() is a simple global function that runs a code impersonating a user. During the execution of the code block, the current user will be set to the user with the specified username. The function expects the following:

  • username: Username of the user to impersonate

  • codeblockCode block to run while impersonating a user

For example:

1 2 3 asUser("jdoe") { ComponentAccessor.jiraAuthenticationContext.loggedInUser.name }

returns jdoe, regardless of who the current user is. 

 Note that the current user will be restored when the code block is exited.

asUser(ApplicationUser user){codeblock}

asUser(ApplicationUser user) is a simple global function that runs a code impersonating a user. During the execution of the code block, the current user will be set to the specified user. The function expects the following:

  • ApplicationUser: User to impersonate

  • codeblockCode block to run while impersonating a user

For example:

1 2 3 asUser(issue.assignee) { ComponentAccessor.jiraAuthenticationContext.loggedInUser?.name }

returns the name of the assignee of the issue, regardless of who the current user is.

 Note that the current user will be restored when the code block is exited.

getOrganization(String organizationNameOrID)

getOrganization is a global function that returns a Jira Service Management Organization from its name or ID.

For example:

1 getOrganization("Appfire")

returns the Organization named “Appfire”.

1 getOrganization("5")

return the Organization with ID 5.

getUsersInOrganization(CustomerOrganization organization)

getUsersInOrganization is a global function that returns the users that belong to an organization. The function returns a Set<ApplicationUser> and expects a CustomerOrganization object.

For example:

1 getUsersInOrganization(getOrganization("Appfire"))

returns the users that belong to the Appfire organization.