I've built a workflow that has a transition from Closed to Closed called 'Clone' that creates a clone of the ticket into a different project and as a different issue type. I'm accomplishing this through a ScriptRunner post function, 'Clones an issue and links'. (In case it becomes important, it is currently the first post function in that transition.) Within the clone post function, I've set the new target project and target issue type. All gravy. ScriptRunner is the best.
Here is where I need help.
In the 'Additional issue actions' of that post function I want to replace the clone's Watcher field with users from a custom user-picker field (multi user field, called "Team"). This is important for us because there is often a dozen or more watchers on the original ticket whereas the clone will only have 2-3 watchers. And those populations don't overlap.
I don't know groovy, but I've used this community forum and lots of testing to hobble together enough so that this post function already (a) strips attachments, (b) gives the clone a name based on the original ticket, and (c) sets the clone's assignee based on a custom field ("Manager").
Any ideas on how to replace the Watchers field with information from the "Team" custom user-picker field? Thanks for any and all help!
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest
// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())
// remove attachments
checkAttachment = {attachment -> false}
// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser
// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}
Hi Becky,
Something like this should work:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest
// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def watcherManager = ComponentAccessor.getWatcherManager()
def groupManager = ComponentAccessor.getGroupManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def locale = ComponentAccessor.getLocaleManager().getLocaleFor(user)
// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())
// remove attachments
checkAttachment = {attachment -> false}
// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser
// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}
// Remove all watchers from issue
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}
// Add all users from Team group as watchers
def teamGroup = groupManager.getGroup("Team")
teamGroup.each { teamMember ->
watcherManager.startWatching(teamMember, issue)
}
Thank you for responding! I used the script above. In the 'Additional issue actions' it is flagging this piece:
watcherManager.startWatching(teamMember, issue)
saying:
Cannot find the matching method com.atlassian.jira.issue.watchers.WatcherManager#startWatching(java.lang.Object,com.atlassian.jira.issue.MutableIssue). Please check if the declared type is right an if the method exists.
I went ahead and ran a ticket through the workflow to get a log:
2018-03-13 10:27:09,681 ERROR [workflow.ScriptWorkflowFunction]: ************************************************************************************* 2018-03-13 10:27:09,690 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: OGC-1175, actionId: 41, file: null java.lang.NullPointerException at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210) at com.google.common.cache.LocalCache.get(LocalCache.java:3936) at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941) at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824) at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4830) at com.atlassian.jira.issue.watchers.DefaultWatcherManager.getWatcherUserKeys(DefaultWatcherManager.java:150) at com.atlassian.jira.issue.watchers.DefaultWatcherManager.getWatchers(DefaultWatcherManager.java:136) at com.atlassian.jira.issue.watchers.WatcherManager$getWatchers.call(Unknown Source) at Script822.run(Script822.groovy:30)
Do you see the issue?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Becky,
There was a small error in the code. It should have been groupManager.getUsersInGroup
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def watcherManager = ComponentAccessor.getWatcherManager()
def groupManager = ComponentAccessor.getGroupManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def locale = ComponentAccessor.getLocaleManager().getLocaleFor(user)
// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())
// remove attachments
//checkAttachment = {attachment -> false}
// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser
// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}
// Remove all watchers from issue
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}
// Add all users from Team group as watchers
def teamGroup = groupManager.getUsersInGroup("Team")
teamGroup.each { teamMember ->
watcherManager.startWatching(teamMember, issue)
}
I tested it in my instance and it seems to work now with new watchers added to my cloned issue:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
It's strange -- the post function is still not working in my instance. I'm getting the same log error as before.
It seems to be this part that is causing the error. Do you have an idea why this is failing?
// Remove all watchers from issue
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}
Thanks very much for your help with this.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Becky,
Which version of ScriptRunner are you running? You can find it on the manage add-ons page in JIRA.
Thanks,
Josh
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Becky,
In that case you have to make use of the doAfterCreate callback (closure).
So in your case will be something like
doAfterCreate = {
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}
}
Let us know if that worked for you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Many thanks, Thanos. I tried the doAfterCreate suggestion. No luck. The clone is created but the Watcher field is not wiped. No error log reported. I also tried moving the post-function that's creating the clone to be the last post-function -- it had been the first. No luck there either.
Let me know if there is anything I can try to help troubleshoot.
Here is the full script:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest
// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def watcherManager = ComponentAccessor.getWatcherManager()
def groupManager = ComponentAccessor.getGroupManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def locale = ComponentAccessor.getLocaleManager().getLocaleFor(user)
// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())
// remove attachments
checkAttachment = {attachment -> false}
// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser
// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}
// remove all watchers of clone
doAfterCreate = {
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}
}
Also, do you think a listener be better? I haven't created a listener before but know that they can modify tickets. If so, would I use your doAfterCreate script suggestion above or do listeners require different scripting?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey Becky,
This should have worked ,
import com.atlassian.jira.component.ComponentAccessor
doAfterCreate = {
ComponentAccessor.watcherManager.getWatchersUnsorted(issue)?.each {
ComponentAccessor.watcherManager.stopWatching(it, issue)
}
}
Can I ask you where is your post function ? Which step and in what order ?
Also can you please check your application logs for any errors ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
It is the first post function in a transition called 'Clone' that goes from Closed back to Closed. The idea is that after a ticket is closed, you press a button and make a clone into a new Project / Issue Type. Attaching a screenshot of the post function ordering and the workflow.
I'll ask another one of our admins for the application logs.
Static checking on the script above says it cannot find the matching method for the ComponentAccessor lines. When I pushed a ticket through the transition to see what would happen, it provided this log:
2018-03-20 16:02:16,787 ERROR [workflow.ScriptWorkflowFunction]: ************************************************************************************* 2018-03-20 16:02:16,787 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: OGC-1175, actionId: 41, file: null groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.issue.watchers.DefaultWatcherManager.getWatchersUnsorted() is applicable for argument types: (com.atlassian.jira.issue.IssueImpl) values: [BMS-133] at Script944$_run_closure2.doCall(Script944.groovy:31) at Script944$_run_closure2.doCall(Script944.groovy) at com.onresolve.scriptrunner.canned.jira.utils.AbstractCloneIssue.doScript(AbstractCloneIssue.groovy:125) at com.onresolve.scriptrunner.canned.jira.utils.CopyIssueWithAttachments.super$2$doScript(CopyIssueWithAttachments.groovy) at com.onresolve.scriptrunner.canned.jira.utils.CopyIssueWithAttachments.doScript(CopyIssueWithAttachments.groovy:13) at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue.super$3$doScript(CloneIssue.groovy) at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue.doScript(CloneIssue.groovy:89)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I had the same issue that it would not clear the watchers on creation of the issue. This is how I solved it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.