Custom Script Field Examples
This page contains a number of custom script field examples:
- Calculate a number based on other fields
- Show the total time this issue has been In progress
- Show the number of attachments the issue has
- Show all previous versions in a given project
- Display an information message
- Show the component lead
- Show multiple component leads
- Show the work remaining in linked issues
Examples
Don’t forget to reindex if you want your newly created scripted custom field to appear in existing issues.
For the examples below, you must first navigate to the Custom Script Field page:
- From ScriptRunner, select the Fields tab.
- Select Create Script Field.
- Select Custom Script Field.
- Create a custom script field based on the examples provided below.
Calculate a number based on other fields
You can calculate a number based on other fields. In the following example, we already have a number field called Severity, and we want a new value that is the product of the Priority and Severity:
- Enter the name for the custom script field. In this example, we enter Critical Points.
- Optional: enter a description. In this example, we enter Calculate critical points based on Priority and Severity.
- Optional: add a field note.
- Select the Number Field template.
Enter the following script into the script editor:
groovydef severity = getCustomFieldValue("Severity") if (severity) { return severity * Integer.parseInt(issue.priority.id) } else { return null }
- Optional: enter an issue key and select Preview to preview this custom script field
- Select Add.
- Configure the context and screens for this custom script field.
Be careful and test this against an issue with no Severity value set.
Show the total time this issue has been In Progress
You can create a custom field that shows the total time an issue has been in the In Progress
state—summing up multiple times if necessary:
- Enter the name for the custom script field. In this example, we enter Time In Progress.
- Optional: enter a description. In this example, we enter Total time this issue has been In Progress.
- Optional: add a field note.
- Select the Duration template.
Enter the following script into the script editor:
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.history.ChangeItemBean def changeHistoryManager = ComponentAccessor.getChangeHistoryManager() def inProgressName = "In Progress" List<Long> rt = [0L] def changeItems = changeHistoryManager.getChangeItemsForField(issue, "status") changeItems.reverse().each { ChangeItemBean item -> def timeDiff = System.currentTimeMillis() - item.created.getTime() if (item.fromString == inProgressName) { rt << -timeDiff } if (item.toString == inProgressName) { rt << timeDiff } } def total = rt.sum() as Long (total / 1000) as long ?: 0L
- Optional: enter an issue key and select Preview to preview this custom script field
- Select Add.
Make sure the Search Template/Searcher for this custom field is Duration Searcher.
You can edit the Searcher by selecting the configured searcher on the Script Fields page.
- Configure the context and screens for this custom script field.
Show the number of attachments the issue has
This example is superseded by the JQL function hasAttachments
.
You can create a custom script field to show the number of attachments. This could easily be modified to show the number with a specific extension etc.
- Enter the name for the custom script field. In this example, we enter Number of Attachments.
- Optional: enter a description.
- Optional: add a field note.
- Select the Number Field template.
Enter the following script into the script editor:
groovydef numberAttachments = issue.attachments.size() // use the following instead for number of PDFs // def numberAttachments = issue.attachments.findAll {a -> // a.filename.toLowerCase().endsWith(".pdf") // }.size() return numberAttachments ? numberAttachments as Double : null
- Optional: enter an issue key and select Preview to preview this custom script field
- Select Add.
Make sure the Search Template/Searcher for this custom field is Number Searcher.
You can edit the Searcher by selecting the configured searcher on the Script Fields page.
- Configure the context and screens for this custom script field.
Show all previous versions in a given project
You can create a custom script field to display every version in a given project prior to the oldest fix version:
- Enter the name for the custom script field. In this example, we enter Previous Versions.
- Optional: enter a description.
- Optional: add a field note.
- Select the Version Picker template.
Enter the following script into the script editor:
package com.onresolve.jira.groovy.test.scriptfields.scripts import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.comparator.VersionComparator def versionManager = ComponentAccessor.getVersionManager() def versions = versionManager.getVersions(issue.projectObject) def comparator = new VersionComparator() def lowestFixVersion = issue.fixVersions.min(comparator) def returnedVersions = versions.findAll { comparator.compare(it, lowestFixVersion) < 0 } log.debug("All prior versions: ${returnedVersions}") (lowestFixVersion ? returnedVersions : null)
The script returns a list ofVersion
objects.- Optional: enter an issue key and select Preview to preview this custom script field
- Select Add.
Make sure the Search Template/Searcher for this custom field is Version Searcher.
You can edit the Searcher by selecting the configured searcher on the Script Fields page.
- Configure the context and screens for this custom script field.
Display an information message
As an admin, you might want to display extra information about an issue, and not be able to search it. You can create a custom script field where your script can output HTML, and you effectively don’t use a velocity template.
In the following example we want to draw attention to an issue when it is blocked by other issues that are not resolved, and not assigned.
- Enter the name for the custom script field. In this example, we enter Blocking Issues Warning.
- Enter a description.
- Optional: add a field note.
- Select the Text Field template.
Enter the following script into the script editor:
In the code below we use a MarkupBuilder, in order to avoid cross-site forgery attacks. In addition, we return null if there are no blocking issues so the field is not displayed at all.
groovyimport com.atlassian.jira.component.ComponentAccessor import groovy.xml.MarkupBuilder import com.atlassian.jira.config.properties.APKeys def blockingIssues = issue.getInwardLinks() .findAll { issueLink -> issueLink.issueLinkType.name == "Blocks" } .collect { issueLink -> issueLink.sourceObject } .findAll { linkedIssue -> !linkedIssue.assignee && !linkedIssue.resolution } if (blockingIssues) { def baseUrl = ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL) def writer = new StringWriter() def builder = new MarkupBuilder(writer) builder.div(class: "aui-message aui-message-error shadowed") { p(class: "title") { strong("This issue is blocked by the following unresolved, unassigned issue(s):") } ul { blockingIssues.each { anIssue -> li { a(href: "$baseUrl/browse/${anIssue.key}", "${anIssue.key}: ${anIssue.summary} (${anIssue.status.name})") } } } } return writer.toString() } else { return null }
- Optional: enter an issue key and select Preview to preview this custom script field
- Select Add.
Make sure the Search Template/Searcher for this custom field is Free Text Searcher.
You can edit the Searcher by selecting the configured searcher on the Script Fields page.
- Configure the context and screens for this custom script field.
The field appears as follows:
Show the component lead
As an admin, you might want to display the lead for the component selected for an issue, making use of the User display template.
- Enter the name for the custom script field. In this example, we enter Component Lead.
- Enter a description.
- Optional: add a field note.
- Select the User Picker (single user) template.
Enter the following script into the script editor:
groovydef components = issue.components if (components) { return components.first().componentLead }
We return a User object, and use the User Picker template so the user is displayed with a clickable link and mouseover popup.
Make sure you return an
ApplicationUser
object and not aUser
. If you do the latter the template will show Anonymous.- Optional: enter an issue key and select Preview to preview this custom script field
- Select Add.
Make sure the Search Template/Searcher for this custom field is User Picker Searcher.
You can edit the Searcher by selecting the configured searcher on the Script Fields page.
- Configure the context and screens for this custom script field.
The field appears as follows:
Show multiple component leads
As an admin, you might want to display all unique component leads for the component selected for an issue:
- Enter the name for the custom script field. In this example, we enter Component Leads.
- Enter a description.
- Optional: add a field note.
- Select the User Picker (multiple users) template.
Enter the following script into the script editor:
groovyissue.components*.componentLead .unique() .findAll()
Optional: enter an issue key and select Preview to preview this custom script field
Select Add.
Make sure the Search Template/Searcher for this custom field is Multi User Picker Searcher.
You can edit the Searcher by selecting the configured searcher on the Script Fields page.
- Configure the context and screens for this custom script field.
The field appears as follows:
Show the work remaining in linked issues
In this example, we create a custom script field to show the work remaining in all issues of the Composition
link types.
Sometimes you may want to to use a custom Composition
link type to break down large tasks rather than subtasks. However, when you do this you can’t see the rolled up remaining estimate. The following custom field shows the amount of time remaining on all issues that this issue comprises.
The outbound link is comprises
and the inbound link would be is comprised of
. See the Atlassian documentation for Configuring issue linking to create your own custom links.
- Enter the name for the custom script field.
- In this example, we enter Work remaining.
- Enter a description.
- Optional: add a field note.
- Select the Duration (time-tracking) template. This makes the display of the custom field match that of the Estimate field.
Enter the following script into the script editor:
// Sum up the estimates from comprising issues. def sumOfChildIssueEstimates = issue.getOutwardLinks() .sum(0) { link -> def estimate = link.destinationObject.getEstimate() // If there's a link to an issue which does not comprise this issue, // ignore the estimate. link.issueLinkType.name == "Composition" && estimate ? estimate : 0L } as long // If there are no estimates in the comprising tickets, the result is just the // same as the remaining estimate, so let's not display it. if (!sumOfChildIssueEstimates) { return 0L } // Add the estimate from the base ticket. long parentIssueEstimate = issue.getEstimate() ?: 0L sumOfChildIssueEstimates + parentIssueEstimate
Line 7: Change the link type name to suitThe important thing is that this script returns a
Long
, so that we can search on it.Optional: enter an issue key and select Preview to preview this custom script field
Select Add.
Make sure the Search Template/Searcher for this custom field is Duration Searcher.
You can edit the Searcher by selecting the configured searcher on the Script Fields page.
- Configure the context and screens for this custom script field.
The field appears as follows:
Indexing
You may notice a further problem. When work is logged on one of the linked issues, the issues that link to it don’t get reindexed, so a search won’t return the correct results.
To handle this, we use a custom Script Listener to follow is comprised of
links and reindex those issues:
- From ScriptRunner, select the Listeners tab.
- Select Create Listener.
- Select Custom Listener.
- Enter the name for the listener. In this example, we enter Reindex related issues.
- Selec the projects for this listener to be applied to
- Select the Issue Updated, Work Logged On Issue, Issue Worklog Updated, and Issue Worklog Deleted events.
- Enter the following script into the editor:
event.issue.getInwardLinks() // event is an IssueEvent .each { issueLink -> if (issueLink.issueLinkType.name == "Composition") { issueLink.getSourceObject().reindex() } }
Line 3: Change the link type name to suit - Select Add.
Further Examples
Show attachment links in issue navigator: https://answers.atlassian.com/questions/283908/answers/3350560