Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Remove watchers when creating clone via workflow post function (scriptrunner)

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())
}

 

 

1 answer

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?   

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:

Screen Shot 2018-03-13 at 12.53.46 PM.png

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.  

Hi Becky,

Which version of ScriptRunner are you running? You can find it on the manage add-ons page in JIRA.

Thanks,

Josh

Hi Josh,  We're running version 4.3.15

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.  

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?

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 ? 

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.  

Capture.PNG

Capture2.PNG

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)
Davin Studer Community Leader Mar 21, 2019

I had the same issue that it would not clear the watchers on creation of the issue. This is how I solved it.

https://community.atlassian.com/t5/Jira-questions/Use-ScriptRunner-to-un-watch-an-issue-when-created/qaq-p/1038959#U1039042

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Asked in Jira Service Desk

Calling all Insight users, we need your help!

Hello Insight users,  As part of our (Mindville's) acquisition by Atlassian, our training team is looking to build some new Insight training materials. It would really helpful if you can ...

97 views 1 0
View question

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you