I had some troubles to get the changes done in a ScriptRunner listener visible in the issue history. I share in this post my learnings.
- Problem description
- First attempt
- Second attempt
- Final solution
- See also
- Update a Single-Select (Drop Down) Custom Field - Adaptavist Library
- Update the Value of Custom Fields through the Script Console - Adaptavist Library
- Scriptrunner listener updates not showing in Issue...
- Updating a custom field with and without keeping history – JIRA Programming – JIRA Scripting, Plugin and Report Development, ScriptRunner & Tempo tips
Problem description
I wanted to set a custom field in a ScriptRunner listener and have the change documented in the issue history and being able to trigger an email notification (issue updated event).
This is quite a common question (see Solved: Why doesn't Script Listener write to Issue History... and Scriptrunner listener updates not showing in Issue...)
First attempt
My first known approach to set a custom field did not trigger an issue update (it was more like a silent change).
Looking for how to make the issue change visible I have found this solution still based on the issueManager.
I have tried it but couldn't get it to work (no change visible in the issue history).
Second attempt
Then I came to this resource that is based on issueService.
After a test, this works properly i.e. the change is visible in the issue history.
Final solution
Still I needed to change the solution provided in the Script Library.
The structure made it hard to use in my listener script because I was looping on links and had many issues to handle (not only the current one)
I have refactored the original library solution so that the function takes an issue as input argument.
Also one subfunction to get the custom field by name wasn't really needed.
You can see an extract of my final result in this gist:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.atlassian.jira.component.ComponentAccessor | |
import com.atlassian.jira.model.ChangeItem | |
import com.atlassian.jira.issue.Issue | |
import com.atlassian.jira.issue.fields.CustomField | |
import com.atlassian.jira.issue.MutableIssue | |
import com.atlassian.jira.event.type.EventDispatchOption | |
import com.atlassian.jira.issue.ModifiedValue | |
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder | |
def issue = event.issue | |
def issueLinkManager = ComponentAccessor.getIssueLinkManager() | |
def customFieldManager = ComponentAccessor.getCustomFieldManager() | |
def customField = customFieldManager.getCustomFieldObjectByName("FieldName") // write here your FieldName | |
def cfOptions = ComponentAccessor.optionsManager.getOptions(customField.getRelevantConfig(issue)) // there is only one context for this custom field - so one can get the options one time for all | |
def issueManager = ComponentAccessor.getIssueManager() | |
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser | |
def issueService = ComponentAccessor.issueService | |
def issueInputParameters = issueService.newIssueInputParameters() | |
// Define Value to set | |
def FieldValue = "Value" | |
// Set CustomField Value | |
issueInputParameters.with { | |
// set custom fields with options (select lists, checkboxes, radio buttons) | |
addCustomFieldValue(customField.id, *getOptionIds(customField,cfOptions,FieldValue)) | |
} | |
def updateValidationResult = issueService.validateUpdate(loggedInUser, inwardLinkedIssue.id, issueInputParameters) | |
assert updateValidationResult.valid: updateValidationResult.errorCollection | |
def issueUpdateResult = issueService.update(loggedInUser, updateValidationResult, EventDispatchOption.ISSUE_UPDATED, true) | |
assert issueUpdateResult.valid: issueUpdateResult.errorCollection | |
/** | |
* Given a custom field name and option values, retrieve their ids as String | |
* @param customField CustomField | |
* options: ComponentAccessor.optionsManager.getOptions(customField.getRelevantConfig(issue)) | |
* @param values The values in order to get their ids | |
* @return List < String > The ids of the given values | |
*/ | |
List<String> getOptionIds(CustomField customField, options, String... values) { | |
options.findAll { | |
it.value in values.toList() | |
}*.optionId*.toString() | |
} | |