Forums

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

Bulk update Jira issues for a single select custom field option using script runner

vcatl2020
Contributor
August 4, 2021

I'm running into an error when updating bulk Jira issues for a single select custom field with an option value and just for a specific search criteria only. Any suggestions on code tweak here to fix this error?

The reason for avoiding bulk update operation via Jira is that it sets the updated system field value after the load, which affects our tickets aging calculation. The workaround of using this code is to retain the updated field value as before but still setting the custom field value to an option,

error - 

[c.o.s.r.rest.common.UserScriptEndpoint] Script console script failed:
java.lang.ClassCastException: java.lang.String cannot be cast to com.atlassian.jira.issue.customfields.option.Option
at com.atlassian.jira.issue.customfields.impl.SelectCFType.getDbValueFromObject(SelectCFType.java:71)
at com.atlassian.jira.issue.customfields.impl.AbstractSingleFieldType.createValue(AbstractSingleFieldType.java:143)
at com.atlassian.jira.issue.fields.ImmutableCustomField.createValue(ImmutableCustomField.java:693)
at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:410)
at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:396)
at com.atlassian.jira.issue.fields.OrderableField$updateValue.call(Unknown Source)
at Script123$_run_closure1.doCall(Script123.groovy:52)
at Script123.run(Script123.groovy:45)

 

code - 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.ResolutionManager
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.search.SearchException
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import org.apache.log4j.Level
import org.apache.log4j.Category

log.setLevel(Level.INFO)
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// The JQL query you want to search with
final jqlSearch = "filter=22606"

// the name of the custom field (single select list type)
final customFieldName = "Classification Type"

// The new value to set
final newValue = "Projects"

// Get the custom field
def customField = ComponentAccessor.customFieldManager.customFieldObjects.findByName(customFieldName)
assert customField : "Could not find custom field with name ${customFieldName}"

def searchService = ComponentAccessor.getComponentOfType(SearchService)


// Parse the query
def parseResult = searchService.parseQuery(user, jqlSearch)
if (!parseResult.isValid()) {
log.error('Invalid query')
return null
}

try {
// Perform the query to get the issues
def results = searchService.search(user, parseResult.query, PagerFilter.unlimitedFilter)
def issues = results.results
issues.each {
log.info(it.key)
def issue = ComponentAccessor.getIssueManager().getIssueObject(it.key)
def object = ComponentAccessor.getIssueManager().getIssueObject(it.key)

def updated = issue.getUpdated()
customField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(customField), newValue), new DefaultIssueChangeHolder())
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.DO_NOT_DISPATCH, false)
issue.setUpdated(updated)
issue.store()

boolean wasIndexing = ImportUtils.isIndexIssues();
ImportUtils.setIndexIssues(true)
log.warn("Reindex issue ${object.key} ${object.id}")
ComponentAccessor.getComponent(IssueIndexingService).reIndex(ComponentAccessor.getIssueManager().getIssueObject(object.id));
ImportUtils.setIndexIssues(wasIndexing);
}

} catch (SearchException e) {
e.printStackTrace()
null
}

2 answers

1 accepted

2 votes
Answer accepted
Leo
Community Champion
August 5, 2021

Hi @vcatl2020,

you can use below code to convert string into an option before you pass it to update script

def optionsManager = ComponentAccessor.getOptionsManager()

def fieldConfig = customField.getRelevantConfig(issue)
def optionsCF = optionsManager.getOptions(fieldConfig)
def optionToSet = optionsCF.find { it.value == "Projects" } 

//you need to pass optionToSet variable in update method

 

BR,

Leo

vcatl2020
Contributor
August 5, 2021

Thanks @Leo for your help in passing the right code and it worked perfectly.

Siddesh Mahajan February 20, 2023

Hi @vcatl2020 , Kindly help with the complete code.

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.
August 4, 2021

The problem is 

final newValue = "Projects"

This means newValue is a simple string.

You can't just jam strings into select lists - they don't hold strings, they hold "options".  Also, you need to have added the new option to the list of options for the field before you can set it.

vcatl2020
Contributor
August 4, 2021

Just to clarify "Projects" is already an existing option for Single Select custom field. How would I workaround setting this Option value for all issues related to this search filter ID?

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.
August 4, 2021

There's nothing to "work around", you need to give the field the right type of data (as I said already, an option, not a string)

Have a look at library.adaptavist.com for scripts that set select lists, you'll find a number that show you how to work with options.

Suggest an answer

Log in or Sign up to answer