There are a large number of included functions, as outlined below.

It may be useful to make a request to the Jira Cloud REST API to see which fields you can use inside of the function expressions, e.g. customfield_10024 or priority.id

https://your-jira.atlassian.net/rest/api/2/issue/{issueIdOrKey}?expand=schema

Almost all of the functions require a subquery as a first parameter. If you provide an empty string (e.g. "") your query will be really inefficient because it will match each issue in your Jira instance.

You cannot use the statement below inside of your subqueries, because user-specific data is not supported inside the subqueries:

assignee = currentUser()

Dates

dateCompare

dateCompare(Subquery, date comparison expression)

This function lets you compare two dates on the same issue, for instance to find all issues that were updated later than created:

issueFunction in dateCompare("project = SRCLOUD", "created < updated")

You can use time windows on both side of the expression. Eg to find issues resolved before or up to six days after their due date:

issueFunction in dateCompare("project = SRCLOUD", "resolutiondate +1d < duedate +1w")

You can also use created or updated.

To find issues that were resolved within two weeks of creation, use:

issueFunction in dateCompare("project = SRCLOUD", "created +2w > resolutiondate ")

You can also use date and datetime custom fields. Example:

issueFunction in dateCompare("project = SRCLOUD", "resolutiondate > customfield_10500")

where customfield_10500 is the name of a 'date' custom field.

You can also use the equality operator = to find issues that have been resolved on the same date that’s in a custom field:

issueFunction in dateCompare("project = SRCLOUD", "resolutiondate = customfield_10500")

If your date contains time, equality operator won’t be useful. Use the clearTime() method described below.

You can also use the greater or equal operator >= to find issues that have been resolved on or after the same date that’s in a custom field:

issueFunction in dateCompare("project = SRCLOUD", "resolutiondate >= customfield_10500")

You can also use the smaller or equal operator  to find issues that have been resolved on or before the same date that’s in a custom field:

issueFunction in dateCompare("project = SRCLOUD", "resolutiondate <= customfield_10500")

You can also use the not equal operator != to find issues that have been resolved on a different date than that’s in a custom field:

issueFunction in dateCompare("project = SRCLOUD", "resolutiondate != customfield_10500")

You can use the .clearTime() method to get the date part of a date or datetime field. The date will be converted to the user’s timezone, before the date is extracted:

issueFunction in dateCompare("project = SRCLOUD", "customfield_10500.clearTime() = duedate.clearTime()")

Subtasks

subtasksOf

subtasksOf(Subquery)

Returns the subtasks of issues specified by the subquery, eg:

issueFunction in subtasksOf("project = SRCLOUD")

To find unresolved subtasks of resolved issues you might do:

issueFunction in subtasksOf("resolution IS NOT EMPTY") AND resolution IS EMPTY

To find subtasks that are Open, but their parent issue has a resolution of Fixed, you could use:

issueFunction in subtasksOf("resolution = Fixed") AND status = Open

subtasksOf is analogous to saying "subtasks which have a parent selected by the subquery".

You can leave the subquery as an empty string in all these examples if you want, but it’ll make your query inefficient.

parentsOf

parentsOf(Subquery)

Returns the parents of issues specified by the subquery. For example, to find closed parents with open subtasks in the project SRCLOUD, you could do:

status = Closed AND issueFunction in parentsOf("project = SRCLOUD AND status = open")

To show parent issues that have at least one open subtask, in the SRCLOUD project, you might do:

issueFunction in parentsOf("project = SRCLOUD AND status = Open")

linkedIssuesOf

linkedIssuesOf(Subquery, [link name])

This is similar to parentsOf and subtasksOf, in that it will return the linked issues.

To find all the unresolved issues that are blocked by issues in the Open state you could use:

issueFunction in linkedIssuesOf("status = Open", "blocks") AND resolution IS EMPTY

With no link name argument, this function will search for the linked issues whatever the link type:

issueFunction in linkedIssuesOf("resolution = unresolved")

linkedIssuesOfRecursive

linkedIssuesOfRecursive(Subquery, [Link name])

This is similar to linkedIssuesOf, in that it will return the linked issues, however this function traverses issue links recursively to return all issues that are linked (directly and indirectly) to the results of the initial subquery.

To find all direct and indirectly linked issues of an particular issue you can use:

issueFunction in linkedIssuesOfRecursive("issue = DEMO-1")

So if we have the following setup:

Setup demo example.


Then our query would return: DEMO-1, DEMO-2, DEMO-3, DEMO-4 and DEMO-5.

DEMO-1 is returned by the query above as it has "is blocked by" links from DEMO-2 and DEMO-3.

You can limit the type (and direction) of links that are traversed using the second parameter.

issueFunction in linkedIssuesOfRecursive("issue = DEMO-1", "blocks")

In this instance, if we use the example already mentioned, only DEMO-2, DEMO-3 and DEMO-4 will be returned.

The Link type parameter behaves exactly the same as the Link description parameter for linkedIssuesOf.

If you have 1000s of indirectly linked issues, traversal of all of the links will take a long time.

linkedIssuesOfRecursiveLimited

linkedIssuesOfRecursiveLimited(Subquery, Traversal depth, [Link name])

This function is exactly the same as linkedIssuesOfRecursive but it allows us to limit the depth of traversals along issue links that the function will do.

The following query will follow all links, recursively, from all issues in the DEMO project until it has traversed a maximum of 2 links deep along any link path.

issueFunction in linkedIssuesOfRecursiveLimited("project = DEMO", 2)

Using the following setup:

Our query with the depth parameter would return: DEMO-1, DEMO-2, TEST-1, TEST-2, TEST-4 and TEST-5.

We could specify the link name as well, to get different results:

issueFunction in linkedIssuesOfRecursiveLimited("issue = TEST-2", 3, "is blocked by")

which would return: TEST-3, TEST-6 and TEST-5

epicsOf

epicsOf(subquery)

Jira Software users can query on epic links, eg find all Epics that have unresolved stories:

issueFunction in epicsOf("resolution = unresolved")

Jira Software users can also query on epic links to find all epics which do contain any issues.

project = <ProjectKeyHere> and issuetype = Epic and NOT (issueFunction in epicsOf("project = <ProjectKeyHere>")

This function will only return issues of the Epic type.

issuesInEpics

issuesInEpics(subquery)

This function allows you to find issues related to epics found by the subquery e.g. find all stories for open Epics in a project:

issueFunction in issuesInEpics("project = DEMO AND status = 'To Do'")

issueFunction in issuesInEpics("resolution IS NOT EMPTY") AND resolution IS EMPTY

Agile Functions

The board parameter in the three functions below may be either the name of the board, or the board ID. You can find the board ID in the page URL when viewing the board e.g. https://example.atlassian.net/secure/RapidBoard.jspa?rapidView=24&projectKey=EXAMPLE shows the board ID to be 24.

inSprint

inSprint(board, sprint)

Query the issues of a sprint of an agile board.

issueFunction in inSprint("EX Scrum Board", "Sprint 3")

nextSprint

nextSprint(board)

Query the issues of the next active sprint of an agile board.

issueFunction in nextSprint(452) AND assignee = currentUser()

previousSprint

previousSprint(board)

Query the issues of the previous active sprint of an agile board.

issueFunction in previousSprint("Kanban Board") AND fixVersion IS EMPTY

addedAfterSprintStart

addedAfterSprintStart(board, sprint)

Query the issues added after the sprint began for the active sprint of an agile board.

issueFunction in addedAfterSprintStart("EX Scrum Board", "Sprint 3")

Differences with ScriptRunner for Jira Server

The following agile functions are available on ScriptRunner for Jira Server, but not available on ScriptRunner for Jira Cloud:

  • removedAfterSprintStart

  • incompleteInSprint

  • completeInSprint

Others

issueFieldMatch

issueFieldMatch (subquery, fieldname, regexp)

Query on any field by regular expression. Performance will be roughly proportional to the number of issues selected by the subquery, so use the query that selects the smallest set of issues you can, eg just your projects.

To find all issues where the description contains a ABC0000 where 0000 is any number, you could use:

issueFunction in issueFieldMatch("project = SRCLOUD", "description", "ABC\d{4}")

Note - the function searches for the regular expression anywhere within the field. To match the entirety of the field, use ^ and $, e.g. ^ABC\d{4}$

issueFieldExactMatch

issueFieldExactMatch (subquery, fieldname, regexp)

Find issues by matching the text of a field exactly.

projectMatch / componentMatch / versionMatch


projectMatch(reg exp)
componentMatch(reg exp)
versionMatch(reg exp)

These functions provide lists of projects, components, versions respectively that match the provided regular expression.

Example: all issues that have a component beginning with Web:

component in componentMatch("^Web.*")

All issues in the JRA project that have a fix version beginning with RC:

fixVersion in versionMatch("^RC.*")

expression

expression(Subquery, expression)

This is a powerful function that lets you compare attributes of fields. What you can compare are the system estimate and date fields, and any numeric, date, or datetime custom field. It’s probably easiest to explain through some examples, starting from the simple.

Find issues where more work was logged than originally estimated:

issueFunction in expression("project = SRCLOUD", "timespent > timeoriginalestimate")

Note that this could also be done by using plain JQL: workratio > 1.

Search for issues where the work logged exceeded the original estimate by more than 5 days (normalised for timetracking, so > 40 hours work logged):

issueFunction in expression("project = SRCLOUD", "timespent > timeoriginalestimate + 5*wd")

Do use 5*d or 5*w and not 5d as in dateCompare - the syntax is (unfortunately) different.

Notes on Time Tracking

When comparing calendar dates it is useful to think of days as periods of 24 hours. However when working with time estimates we think in terms of working hours, days and weeks where a working day is typically 8 hours (configurable in Jira) and a working week is 5 days.

You can use working day units:

wdNumber of milliseconds in a working day (according to your specification in Admin → Time trackingwwNumer of days in a working week multiplied by the value above.

Or, if you are comparing timetracking fields with non-time tracking fields, for example remaining effort and due date, you need to use the special fromTimeTracking function. For example, search for issues which, if their remaining estimate is valid, are going to miss their due date. You could devote extra resources to these to ensure that doesn’t happen:

issueFunction in expression("resolution is empty", "now() + fromTimeTracking(remainingestimate) > duedate")

When you specify an estimate of 3 days, Jira stores that internally as 24 hours, and renders it as 3 days for estimate fields. The fromTimeTracking function converts that to 72 hours so it can be used to manipulate and compare with other dates.

Find issues where the product of two number custom fields is greater than X:

issueFunction in expression("project = SRCLOUD", "customfield_10026 * customfield_10028 > 100")

Find issues that have a high ratio of votes to complexity (assuming Complexity is a numeric field):

issueFunction in expression("project = SRCLOUD", "votes / Complexity > 100")

Using Functions

You can use Date functions, for instance now(), startOfDay() etc, anywhere you would use a date. Supported functions:

Some arguments will need to be quoted. For example, if you want to say one week before the start of the month you would write startOfMonth('-1w').

Differences with ScriptRunner for Jira Server

  • functions startOfWeek() and endOfWeek() return Monday as a first day of week and they take time in UTC, if you use Sunday instead of Monday, you can use -1d period modificator, e.g. startOfWeek('-1d')