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

transfer watchers to custom field

Rene Rath January 28, 2014

Hi there,

Introduction/Setting:

We have a Jira Project, which not all jira users shall be allowed to browse. Only those people who are on the watchlist of an issue, shall be able to see it. We achieved this with the help of a custom field ("Contributor"), more to the point a User Picker (multiple users): this field is now used in the permission scheme for the browsing permission (Thanks again to Henning Tietgens: https://answers.atlassian.com/questions/255408/browse-permission-based-on-watchlist).

Thing is: typically, tickets in this project are automatically created from incoming eMails. Whoever is on cc of the mail, shall

a) be added to the watchlist of the ticket and shall

b) be able to access the ticket.

Jira only lets me do a), while b) can be done with the above mentioned custom field "Contributor". What's missing now is the sync of the list of watchers and the contributor field.

Problem:

I have created a groovy script with the intention to add it as a post function when creating an issue. However, being a total noob in groovy, the script in fact does nothing but throw exceptions.

The script should simply add every watching user to that custom field "Contributor".

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager

def componentManager = ComponentManager.getInstance()
def watcherManager = componentManager.getWatcherManager()
def customFieldManager = componentManager.getCustomFieldManager()

CustomField contributorField = customFieldManager.getCustomFieldObjects().find {name == "Contributor"}

List<String> watchers = watcherManager.getWatchers()
issue.setCustomFieldValue(contributorField, watchers);

Any help greatly appreciated. Thanks, folks!

5 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Answer accepted
Henning Tietgens
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.
January 28, 2014

getWatchers() need some parameters, see here. You could create a new Locale object (Locale locale = new Locale('en')), because this is only used for sorting the result, which you don't need here.

Henning Tietgens
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.
January 28, 2014

And it returns List<ApplicationUser>, which should be good for cf Contributors.

Rene Rath January 28, 2014

Hi Henning, thanks again for your help. I tried to implement all your suggestions (and Nic's). this is what the script looks like now:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.user.ApplicationUser

def componentManager = ComponentManager.getInstance()
def watcherManager = componentManager.getWatcherManager()
def customFieldManager = componentManager.getCustomFieldManager()

Locale locale = new Locale('de')

CustomField contributorField = customFieldManager.getCustomFieldObjects().find {it.name == 'Contributor'}
List&lt;ApplicationUser&gt; watchers = watcherManager.getWatchers(issue,locale)
issue.setCustomFieldValue(contributorField, watchers);

However, I am still getting exceptions. Here's what I get:

Stack Trace:

javax.script.ScriptException: javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: issue for class: Script19
	at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:117)
	at javax.script.AbstractScriptEngine.eval(Unknown Source)
	at com.onresolve.jira.groovy.GroovyRunner.runFile(GroovyRunner.java:115)
...

Henning Tietgens
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.
January 29, 2014

Where do you run this script? In a postfunction "issue" should exist. Do you run it from the console?

Rene Rath January 29, 2014

Yup, in the script console, a.k.a. /secure/admin/groovy/GroovyRunner.jspa.

I was hoping that I could test & tune the script there, before I carve it into a file and store it. I suppose the file would have to be stored on the jira server, a local path (C:\somefolder\somefile.txt) will not work, I suppose.

Uploading a file on that server can only be done by our IT dept. Takes a while till it's done, so I hoped I could do this just once as a final step.

Anyway, I'll try and keep you posted.

Henning Tietgens
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.
January 29, 2014

You could get an example issue through the issueManager for testing purposes in the console.

But especially for the create issue transition the result in the postfunction could differ from the result in the console...

Rene Rath January 29, 2014

Okay, script has been transferred to the server and added to the post functions (as the final step of the create operation). However, the people who were on cc of the mail, are only in the list of watchers, the script has not copied them into the list of contributors. Looking at the access.log and catalina.out, I see no trace of the script. To me, it looks as if hasn't been called. Any clue where the script runner would collect error output unless in these two files (which were just guessed)?

Henning Tietgens
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.
January 29, 2014

catalina.out is the right place to look for errors. Maybe you could add some "log.error()" calls to your script to look if the script runs, and what the values are.

In general I would say you should try to move the script in the list of postfunctions to a point after the part which creates the issue (or to the end of the list) and add a call to issueManager.updateIssue() to write the changes to the issue. This is not needed if the issue was not created at the time the postfunction runs, but maybe at that time the getWatchers() call doesn't get the watchers because the issue doesn't exists on the database.

Rene Rath January 29, 2014

This post function is the very last, which is executed for the transaction "Create Issue".

log.error(watchers) gave me an empty list of watchers. This points into the same direction which you suggested: at the time when this post function is called, the issue doesn't yet exist in the DB.

In parallel, I have been investigating the Plugin "JIRA Suite Utilities", which claims to allow writing to custom fields in post functions. However, it seems to only give me access to '%%CURRENT_USER%%', '%%CURRENT_DATETIME%%' and '%%ADD_CURRENT_USER%%' - no way to obtain the current watchers of the issue. And even if there was a way to do so: if you are right and at this point of time the issues doesn't exist yet in the DB, this plugin will run into the same problem like the script above.

So, thinking aloud: if the script itself is OK, but not properly applicable in this transition, because the issue is not yet present in the DB, then I should apply the script AFTER the issue got created in the DB. IMHO, this means to create a new status "pre-open", which shall just make sure that the issue gets created in the DB. So all issues in this status shall automatically perform a transition "open issue properly", which shall do 2 things: call this script and then set the status to "open".

Sounds a bit exaggerated to me, but hey, i'll give it a shot.

Henning Tietgens
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.
January 29, 2014

Mmh. If it's the last post function the issue exists on the database. How do you add the watchers while creating the issue?

Rene Rath January 29, 2014

With the incoming mail handler. Activated the checkbox "CC Watchers" (If selected, each CC'ed user will become a watcher of the created issue.)

That script is the last post function before the status "open" is reached. Maybe a status is indeed necessary for an issue to be ready to be written into the DB.

Henning Tietgens
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.
January 30, 2014

Ok, I suspect, the email handler adds the watchers after the issue is created (and therefor after your postfunction runs). Maybe because it's not possible to do this while creating the issue. Is there an option to add the CCs to a custom field? We're using JEMH as our email handler and here it's possible to add CCs to a customfield...

If not, I think you have to follow your idea with an additional status after Open (because Open is the first status and you cannot change that). But I'm not sure if this may help, because if you want to trigger an automatic transition you have to do this in the create post function as a fast track transition (built in script). And than it becomes a timing issue. So it could work but maybe sometimes not. IMO the only proper way is that the email handler adds the users to the contributors field.

Another easier way could be to install the watcher field plugin and use this field in the permission scheme for browse project.

Rene Rath January 30, 2014

JEMH seems like the right plugin for the use case, in combination with the custom field "Contributors" (invaluable tip of yours, thanks again!).

The watcher field plugin seems to do nothing more than what I've done already: create that multi user fied "Contributors" (they just call it "My Watchers"). Still not helping, if the watchers are only added once the issue has been created.

Introducing that new "pre open" status proved to be quite a pain in the bum: "Open" needs to stay the first status. But it can be renamed to something like "Pre OPEN", but this is a global change: in ALL workflows, which use the status "open" (that is: all workflows), this status is renamed. And I would have had to create all transitions in the workflow anew, because jira doesn't let me change the starting status of a transition.

One final attempt before I give up and opt for JEMH: does jira provide a way to do something automatically ON UPDATE? General idea: on every change of the ticket, copy all watchers into the contributors field (which then can even be hidden so nobody realizes that this custom field even exists - an added plus). Most of the time, this operation would not do anything new, just slow things down, but I'd be willing to let the people wait for that extra split second in this case.

I am aware of fast track transitions, but they necessarily change the status of the ticket. Is there a way which does not change the status (but leave the status at whatever the user has set it to)?

Nic Brough -Adaptavist-
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 30, 2014

>does jira provide a way to do something automatically ON UPDATE

Yes, "listeners" can catch any event (anything that changes issue data fires an event one way or another) and update an issue. It sounds like you'd want to write a listener that simply catches all issue events, compares watchers with contributors and amends if necessary.

I'm a little confused about the comments above about changing the starting step of a workflow and transition. You can have "create issue" land anywhere you want in your workflow (but only one "create issue") and you don't really need to change the start point of transitions, you just add new ones to the step. (I may be misunderstanding this though, I just wanted to say you can change stuff, albeit it might not be easy if you've got a lot of workflows to amend)

Henning Tietgens
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.
January 30, 2014

The watcher field provides a multi user field which is automatically filled with the watchers.

1 vote
Nic Brough -Adaptavist-
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 28, 2014

What exceptions do you get?

Aslo, what *type* of field is "Contibutor"?

Rene Rath January 28, 2014

Contributor is a User Picker (multiple users).

When I execute this script in the script console of my local Jira 6.1.6, here are the first few lines of the stack trace:

Stack Trace:

javax.script.ScriptException: javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: name for class: Script11
	at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:117)
	at javax.script.AbstractScriptEngine.eval(Unknown Source)
	at com.onresolve.jira.groovy.GroovyRunner.runFile(GroovyRunner.java:115)

If helpful, I can provide the full stack trace, but for the sake of readability, I don't do it right away.

Nic Brough -Adaptavist-
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 28, 2014

Hmm. I *think* there might be something wrong with the last line - I don't think setCustomFieldValue s expecting a list of users as strings, I think it's expecting a list of users as User objects.

0 votes
Rene Rath February 9, 2014

Atlassian keeps asking me to accept one of the answers. Probably the best solution to my problem would have been JEMH, which I didn't pursue because the license cost IMHO aren't justified for my use case. I've accepted Henning's response, which contains the hint to JEMH somewhere in the comments (although the first passage of this response doesn't look like it's a solution to my problem, but I can't accept a comment, just a whole response thread). Henning, well deserved 30 karma!

0 votes
Rene Rath February 3, 2014

For the sake of keeping this thread updated: we will manually transfer people from the watchlist to that custom field "contributors", if they need access to the ticket. The automatic transfer would of course be convenient, but this little plus in convenience doesn't justify the license cost for JEMH.

Anyhow, thanks Henning and Nic for the insights, I hope future readers of this thread find it as helpful as I did!

0 votes
Henning Tietgens
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.
January 28, 2014

The line

customFieldManager.getCustomFieldObjects().find {name == "Contributor"}

should be

customFieldManager.getCustomFieldObjects().find {it.name == "Contributor"}

So that Groovy knows from which object you want to access the property "name".

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS
AUG Leaders

Atlassian Community Events