Snippets

Adaptavist Adaptavist ScriptRunner for Jira Cloud Example Workflow Validators

Created by Kristian Walker last modified
/*
 * This script provides some example expressions which can be added as 'ScriptRunner Script Validators* inside of ScriptRunner for Jira Cloud'.
 * The conditions must written as a Jira Expression using the expression framework which Atlassian document at: https://developer.atlassian.com/cloud/jira/platform/jira-expressions/
 * All right, title and interest in this code snippet shall remain the exclusive intellectual property of Adaptavist Group Ltd and its affiliates. Customers with a valid ScriptRunner 
 * license shall be granted a  non-exclusive, non-transferable, freely revocable right to use this code snippet only within their own instance of Atlassian products. This licensing notice cannot be removed
 * or amended and must be included in any circumstances where the code snippet is shared by You or a third party." 
*/ 

// Speicify that at least one linked issue must be entered when the issue is created 
issue.links.length >0 // You may also want to set the Error message to have text similar to 'You must specify at least one linked issue in order to be able to create this issue.'

// Specify that at least one Fix Version is added to the issue when it is created
issue.fixVersions.length >0 // You may also want to set the Error message to have text similar to 'You must specify at least one Fix Version in order to be able to create this issue.'

// Specify that at least one Component is added to the issue when it is created
issue.components.length >0 // You may also want to set the Error message to have text similar to 'You must specify at least one Component in order to be able to create this issue.'

// Specify that both select list drop downs in a custom cascading select field must be populated in order to create an issue. 
// Note: You should replace 'customfield_10093' in the example below with the ID of the cascading select list field inside of your instance. 
issue.customfield_10093.child.value.length >0 // You may also want to set the Error message to have text similar to 'You must specify a value in both of the Cascading Select List field drop downs in order to be able to create this issue.'

// Specify that All Sub Tasks must be in the 'In Progress' status before the parent issue can be transitioned
issue.subtasks.filter(subtask => subtask.status.name == 'In Progress').length == issue.subtasks.length // You may also want to set the Error message to have text similar to 'All subtasks must be in the In Progress status before this parent issue can be transitioned.'

// Specify that the description field must contain more than 30 characters
// Note the plainText paramater matches the comment as plain text but you can match it as Rich Text if needed by changing the paramater to RichText
issue.description.plainText.length >30 // You may also want to set the Error message to have text similar to 'The description field must contain more than 30 characters.'

// Specify that the issue must be in an active sprint
issue.sprint.state == 'active' // You may also want to set the Error message to have text similar to 'This issue must be in a valid Sprint.'

// Validate that a set number of new attachments must be uploaded during the transition.  
// The example below mandates that 3 new attachments must be uploaded on the transition screen.  
// This validator will also work on the Create transition as well.
issue.attachments.filter(attachment => attachment.id == null).length ==3 // You may also want to set the Error message to have text similar to 'You must upload 3 attachments.'

// Validate that all issues below an Epic must be in the Done status before the Epic issue itself can be closed.
// The isEpic paramater returns true if the issue is an Epic and false if it is any other issue type
// The stories paramater returns all the issues below the Epic issue to allow there status to be checked. 
issue.isEpic && issue.stories.filter(story => story.status.name == 'Done').length == issue.stories.length //You may also want to set the Error message to have text similar to 'You must ensure all issues inside the Epic are in the Done status before the Epic issue can be closed'

// Validate that only users in a specific project role can create an issue of a certain type
// The first expression mandates the issue type must be a specific issue type.
// The second expression joined by the && operator mandates that the user must be in a specific project role to create the issue type from expression1
// The third expression specifies that all other issue types used by the project can be created. add new issue types by adding them in and seperating them with a | character
issue.issueType.name.match('^(<IssueTypeHere>)$') != null && user.getProjectRoles(project).map(p => p.name).includes("<ProjectRoleHere>") || issue.issueType.name.match('^(<IssueTypeHere>|<IssueTypeHere>)$') != null //You may also want to set the Error message to have text similar to 'You must be in the X Project Role to create the X Issue Type'


// Validate that one of two label fields must have a value 
// Note: You should replace 'customfield_12345' and 'customfield_12346' in the example below with the ID's of the label fields inside of your instance. 
issue.customfield_12345 !=null || issue.customfield_12346 !=null //You may also want to set the Error message to have text similar to 'You must specify a value in one of the label fields'
// Validate that a checkbox custom field only has one value set which is of a specic value
// Note: You should replace 'customfield_12345' in the example below with the ID of the checkbox field and should replace "A" with the option value to validate against
issue.customfield_12345[0].value =="A" && issue.customfield_12345.length ==1 //You may also want to set the Error message to have text similar to 'You must specify the value of <Value Here> only in the checkbox field'

// Validate that a checkbox custom field only has one value set which is of a specic value and that a single line text field is not empty
// Note: You should replace 'customfield_12345' in the example below with the ID of the checkbox field and should replace "A" with the option value to validate against
// Note: You should replace 'customfield_56789' in the example below with the ID of the single line text field that must not be empty
issue.customfield_12345[0].value =="A" && issue.customfield_12345.length ==1 && issue.customfield_56789 != null

// Validate that a checkbox custom field contains a specic value  as an option and that a single line text field is not empty
// Note: You should replace 'customfield_12345' in the example below with the ID of the checkbox field and should replace "A" with the option value to validate against
// Note: You should replace 'customfield_56789' in the example below with the ID of the single line text field that must not be empty
issue.customfield_12345.map(c => c.value).filter(value => value == "A").length > 0 && issue.customfield_56789 != null

// Priority must have a value and must not have the value Highest
//You may also want to set the Error message to have text similar to 'You are not permitted to select the Highest Priority'
issue.priority != null && issue.priority.name != 'Highest'

// All child issues below an epic except for Bugs must be done before the Epic can be transitioned
//You may also want to set the Error message to have text similar to 'All child issues below an epic except for Bugs must be done before the Epic can be transitioned.'
issue.isEpic && issue.stories.every(story => (story.issueType.name == 'Bug' && story.status.name != 'Done') || (story.issueType.name != 'Bug' && story.status.name == 'Done') )

// validate that a select list custom field is required when a sub-task of type'sub-task' is created
// Note: You should replace 'customfield_10138' in the example below with the ID of the single select list field that must not be empty
issue.issueType.name == 'sub-task' ? 
    issue.customfield_10138 != null : 
    true
    
// Validate an issue must have at least one issue blocking it with the 'is blocked by link' and its resolution must not be set
issue.links.some(l => l.type.inward == 'is blocked by' && l.linkedIssue.resolution == null)

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.