Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Automated subtasks not created due to if-statement in Groovy script

Sander Spoelstra
Contributor
November 2, 2022

I've got a script that automatically creates a subtask for each value of the field Environment. This works out great.

However, I want that script to only do it's job if the value of another field (Release) equals 'yes'. And here is where it goes wrong. The value of the field 'Release' is retrieved and it does equal 'yes', but it does not actually create the subtasks anymore.

What am I missing here?

In order below:

  1. The original script 
  2. The addition that doesn't work
  3. The log

 

Original script:

// Imports

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.priority.Priority

// import for debug only
import org.apache.log4j.Logger
import org.apache.log4j.Level
log = Logger.getLogger("com.acme.CreateSubtask")
log.setLevel(Level.DEBUG)

//Current issue - uncomment for post-function
Issue parentIssue = issue

//Get Value of Environment
CustomFieldManager cFM = ComponentAccessor.getCustomFieldManager()
String Environment = 'customfield_12090'
CustomField customfield_Env = customFieldManager.getCustomFieldObject(Environment)
Object customfieldIDValue_Env = (ArrayList) parentIssue.getCustomFieldValue(customfield_Env)

//Pre-define JQL Parser functions
def queryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService)
def activeUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

//Pre-define Sub-Task Generation functions
def issueFactory = ComponentAccessor.getIssueFactory()
def subTaskManager = ComponentAccessor.getSubTaskManager()
def constantManager = ComponentAccessor.getConstantsManager()
def issueManager = ComponentAccessor.getIssueManager()
def dueDate = parentIssue.getDueDate()
def project = parentIssue.getProjectObject()
def description = parentIssue.getDescription()
def priority = parentIssue.getPriority()
def component = parentIssue.getComponents()
def reporter = parentIssue.getReporter()

//Iterate through and create subtasks
    for (int i = 0; i < customfieldIDValue_Env.size(); i++){
    def summary = "Release subtask - " + customfieldIDValue_Env.get(i)
    def environment = customfieldIDValue_Env.get(i)

//Create core Sub-Task Values
MutableIssue newSubTask = issueFactory.getIssue()
newSubTask.setProjectObject(project)
newSubTask.setReporter(reporter)
if (issue.projectObject.key == 'CICD') {
    newSubTask.setIssueTypeId(constantManager.getAllIssueTypeObjects().find{it.getName() == "Simplified Release"}.id)
} else {
     newSubTask.setIssueTypeId(constantManager.getAllIssueTypeObjects().find{it.getName() == "Release subtask"}.id)
}
newSubTask.setParentObject(parentIssue)
newSubTask.setSummary(summary)
newSubTask.setDescription(description)
newSubTask.setDueDate(dueDate)
newSubTask.setComponent(component)
newSubTask.setPriority(priority)
newSubTask.setReporter(activeUser)

//Create Sub-Task
def newIssueParams = ["issue" : newSubTask] as Map
def createdSubTask = issueManager.createIssueObject(activeUser, newIssueParams)
subTaskManager.createSubTaskIssueLink(parentIssue, createdSubTask, activeUser)
}

 This works really well.

If I add this to the script above, it fails:

//Get Value of Release
def release =  ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_17205")
def releaseValue = issue.getCustomFieldValue(release)
log.warn(releaseValue)

//Iterate through and create subtasks
if(releaseValue == "Yes"){
    for (int i = 0; i < customfieldIDValue_Env.size(); i++){
    def summary = "Release subtask - " + customfieldIDValue_Env.get(i)
    def environment = customfieldIDValue_Env.get(i)

...

}

Value of the Release field:

release-value.png

2 answers

1 accepted

2 votes
Answer accepted
Sander Spoelstra
Contributor
November 2, 2022

Found the solution, though I don't understand why.

 

First of all, I need to explicitly add .toString() to the releaseValue variable (even though it should already be a string, and in earlier iterations, it did not allow for def releaseValue = (String) issue.getC.... either.

Also had accidental double quotes in the if-statement.

//Get Value of Release
def release =  ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_17205")
def releaseValue = issue.getCustomFieldValue(release).toString()
log.warn(releaseValue)

//Iterate through and create subtasks
if(releaseValue == 'Yes'){
Nic Brough -Adaptavist-
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 2, 2022

Ah, hang on, that means the field is a multi-select - you're not getting an option from it, you're getting an array of options.

You do not need to "to String it", my original answer still stands.  You should iterate through the results the releaseValue object (without toString-ing it), and use the "if" I gave to detect when one of them is "yes".

There are cases when your code will match your "if" when the release field does not contain "Yes"

Sander Spoelstra
Contributor
November 2, 2022

It's a single-choice select list, so there will never be situations in which it can be both 'yes' and not-yes at the same time I think.

With that in mind, how could the if-statement evaluate wrongly if there can only be 1 value for the field?

 

Edit: your code wasnt valid, I got the error below.

[Static type checking] - Cannot find matching method com.atlassian.jira.issue.customfields.option.Option#getName(). Please check if the declared type is correct and if the method exists.
Possible solutions: getClass(), getAt(java.lang.String)
Instead I went for:
if("Yes" == releaseValue.getValue()){
And that is allowed and works as well. Still don't see how this is better / worse than .toString()
Nic Brough -Adaptavist-
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 2, 2022

Argh, walked into my own warning about getName not being right for Option objects, it's getValue() as per https://docs.atlassian.com/software/jira/docs/api/7.6.1/index.html?com/atlassian/jira/issue/customfields/option/Option.html

Like Sander Spoelstra likes this
0 votes
Nic Brough -Adaptavist-
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 2, 2022

I think it's down to the field type.

I suspect your "Release" is a select-type list field (select, multiselect, version, user-picker, component, radio buttons etc).

Select-type fields do not contain plain text, they hold "options".  So your "if" statement is comparing an object with a string.  They will never be equal.

If this is the case, then you'll want to be comparing the name of the object in the field, not the whole object, so try something like:

if ("Yes" == ( releaseValue.getName() ) )

Your "log" line is outputting "yes" because the log command asks the object what text representation it wants to output, and options hand it the same as getName()

Sander Spoelstra
Contributor
November 2, 2022

Actually that clarifies a lot and even explains why the solution I found earlier (cast the value of Release to a string) indeed works!

 

But I'll keep this in mind, thank you very much!

Suggest an answer

Log in or Sign up to answer