How should I approach managing the list of users who get assigned by a ScriptRunner listener?

Kelly November 5, 2019

Similar to how users can be added/removed as auto-assignees from Components, I want to achieve similar functionality based on the value of a custom field. I've been able to accomplish this by setting up a listener in ScriptRunner. However, all of my users are currently hard-coded into the script. Additionally, all of the expected values of the custom field are hard-coded into the script. While I realize this was a convoluted way to solve the problem, it was meant to be more of a rapid prototype than anything else.

Now that I've figured out how I want the listener to work, I need to find a better way to manage the users being notified in it. I'm comfortable with setting up REST endpoints and possibly adjusting the UI, if that's what it takes. I've been able to follow the tutorials on the ScriptRunner site so far. The only caveat here is that I have to vet this through our IT department first. So, I need it to be fairly straightforward to implement and maintain through them.

Example of the listener logic:

Project 1
     Area:    Production   -->   User1
     Area:    QA   -->   User2

Project 2
     Area:    Production   -->   User3

Project 3
     Area:    QA   -->   User4

Project 4
     Area:    Production   -->   User3
     Area:    QA   -->   User4

What's the best way to approach this? Should I start by using several cascading select fields?

Current versions of what we're using: Jira Server (8.4.2), ScriptRunner (5.6.6)

1 answer

1 accepted

0 votes
Answer accepted
PD Sheehan
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.
November 5, 2019

Here is an idea, just create a new project role. Then you can just populate that project role with 1 or more users that you want to include in your notifications.

Then your custom listener can just pull the members of that role from the current project.

import com.atlassian.jira.security.roles.ProjectRoleManager
def projectRoleManager = ComponentAccessor.getComponentOfType(ProjectRoleManager.class)
def roleName = "you new custom role"
def
role = projectRoleManager.getProjectRole(roleName)
def roleMembers = projectRoleManager.getProjectRoleActors(role, issue.projectObject)?.roleActors?.users?.flatten().sort().unique()

Note. roleActors will include groups and individual users. So we look in each actor item and get the list of users. 

Kelly November 6, 2019

@PD Sheehan, this is a great idea -- thank you! However, I just realized that I originally titled this question wrong (which I will edit so as not to confuse others -- sorry about that!). Rather than using this list of users to notify people, I want to actually assign the issues automatically, depending on the value of the "Area" custom field.

So, I think your solution gets me in the right direction. As a test, I created a simple "Default Assignees" project role and was able to retrieve a list of those users. How can I take that list of users and map it to the values of the "Area" custom field?

The first option that comes to mind is creating a distinct project role for each value of the "Area" custom field. However, the drawback is that it could easily require 30+ new project roles to be created. That seems like it would get messy quickly.

Another option I'm considering is to utilize Jira's user properties and add some sort of flag to any of those users who should be an auto-assignee.

Again, I'm completely open to other suggestions here. I'm still relatively new to ScriptRunner, so this is a great learning process for me.

PD Sheehan
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.
November 6, 2019

Yes, having to create so many new roles would be an issue.

So what you need it a way to store a different default assignee for each Options of the Area custom field. And that might be different for different projects?

One way to perhaps do that would be to use custom project properties.

import com.atlassian.jira.component.ComponentAccessor 
import com.atlassian.core.ofbiz.util.OFBizPropertyUtils
import groovy.json.JsonBuilder

def project = ComponentAccessor.projectManager.getProjectByCurrentKey('JSP')
def projectProps= OFBizPropertyUtils.getCachingPropertySet('Project', project.id)
def defaultAssigneeMap = [QAD: 'abcUser', Production: 'xyzUser']
projectProps.setText("defaultAssigneeForArea", JsonBuilder(defaultAssigneeMap).toString())

 Then you could read the info like this:

import com.atlassian.jira.component.ComponentAccessor 
import com.atlassian.core.ofbiz.util.OFBizPropertyUtils
import groovy.json.JsonSlurper

def project = ComponentAccessor.projectManager.getProjectByCurrentKey('JSP')
def projectProps= OFBizPropertyUtils.getCachingPropertySet('Project', project.id)

def defaultAssigneeMap = new JsonSlurper().parseText(projectProps.getText("defaultAssigneeForArea"))

The reason to perhaps avoid using the user properties is that there is no way (that I know of) to quickly search for a single user based on a property. You'd have to retrieve all your users and then filter for the one with the project and area. That's a bit wasteful.

Before I knew how to use OfBuzPropertyUtils, I actually used the project's description for something similar. That might be something you'd be interested in ... but it's a bit of a hack. Add to your settings to the description using something like <!-- defaultAssigneeForArea=somwayOfEncodingYourSettings --> The html comment brackets will make sure that this is never visible, and you can then have normal user trained on how to change the settings. You'll have to come up with some way of encoding and parsing your settings. Json might work for you. Some more simple key=value pairs may also work:

<!-- defaultAssigneeForArea
QA=abcUser
Production=xyzUser
etc
-->
Kelly November 7, 2019

Yes, you're correct -- I need a way to store a different default assignee for each option of the Area custom field, and it will likely be different for different projects.

I never knew about custom project properties! That's a really helpful tip.

Is the example code you provided something that I can run in the console? I tried to use it (with a few small changes for project name and users), but I keep getting this error:

groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.JsonBuilder() is applicable for argument types: (java.util.LinkedHashMap) values: [[QA:user1, Production:user2]]

at Script387.run(Script387.groovy:8)

no-signature-method.png

PD Sheehan
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.
November 7, 2019

Yes, that should work in the console.

The error was my bad... you need to add "new" in front of JsonBuilder

Kelly November 7, 2019

Awesome -- that fixed it! So, now I'm able to read the info. It returns this as the value for defaultAssigneeForArea:

[QA:user1, Production:user2]

How do I build that into my listener to determine which user gets assigned the issue?

PD Sheehan
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.
November 7, 2019

You can do something like this 

def area = issue.getCustomFieldValue(areaCustomFld)
issue.assignee = defaultAssigneeForArea[area.value]
Kelly November 7, 2019

That worked perfectly. Thank you so much for all of your help!

Suggest an answer

Log in or Sign up to answer