JIRA ScriptRunner listener to copy custom fields

Lev Ryvkin February 13, 2019

Hello!

I've ran into the problem with our JIRA installation. Our JIRA projects each have many Epic in it. Each Epic has several custom fields which are used across the system for administrative purposes. For example each Epic has it's own custom field "Project Team" (multi-user picker) which is used in issue security scheme. Each related task and sub-task has this field copied by JIRA Suit Utilities on creation (post-function in workflow).

Now I need to update these fields on Epic update. When, for example, Epic's "Project Team" has changed I want to copy this value to every task in this epic and every sub-task related to these tasks.

We have JIRA Script runner installed and I think custom listener on issue updated event is the best way to solve our issue across all project.

In conclusion the task is:

- Run a script only on issue updated event

- Perform actions only if updated issue is Epic

- Copy custom_field105, custom_field106, custom_field107 and system field "Labels" into every task in this Epic and every sub-task of these tasks (tasks and sub-tasks also have these custom fields enabled) 

Thank you very much in advance!

1 answer

1 vote
Hector
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.
February 13, 2019

Hi @Lev Ryvkin, based on your explanation I understand that your system is quite centralized on Epic entity, so what about not replicate the "project team" (or any other) on the linked issues, but define a Scripted field that reads and shows Epic's custom field information on child one. 

Example: 

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.IssueManager;
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.package.epic")
log.setLevel(Level.DEBUG)

def result = ""

IssueManager issueManager = ComponentAccessor.getIssueManager();
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def epicLinkCf = customFieldManager.getCustomFieldObjectByName("Epic Link")

def epicIssue = issue.getCustomFieldValue(epicLinkCf) as Issue
def customField = customFieldManager.getCustomFieldObject("customfield_105")

if (epicIssue) {
log.debug epicIssue.key
result = epicIssue.getCustomFieldValue(customField) //use .getValue() for Options
}

result
Lev Ryvkin February 13, 2019

Hello! Thank you for the reply!

It's an interesting solution, but unfortunately, as I described above we are heavily tied on these custom fields administrative-wise. Custom field "Project Team" is used in issue security scheme to show epic and its tasks only to a specific team. Another custom field "Project Manager" (which also should be copied) is used in permission scheme, so that only described Project Manager can for example resolve the Epic.

As I understood your suggestion is to create Scripted field. As far as i know it cannot be used in system settings like issue security or issue permissions. Even if it can somehow we'll need to re-make every administrative setting tied to old custom fields.

Hector
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.
February 13, 2019

If so, then I'd suggest to follow your original solution, implementing a Listener to cascade the change into every issue in Epic.

Note, that in some cases the change may not be notified properly as Issue updated (EventType.ISSUE_UPDATED_ID) depending on how the update is done, maybe a post-function does the change but does not force to send the proper event and index the issue, etc or maybe the event triggered comes with more than one change, so I would recommend to implement and test the behaviour of the different type of ways any of those fields can be updated.

Lev Ryvkin February 13, 2019

Well, the epic update is always manual. Could you help with the code, please?

Hector
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.
February 14, 2019

Sure, here it goes:

 //executin in case event fires id UPDATED
if(eventTypeID.equals(EventType.ISSUE_UPDATED_ID)){
...
//iterating over all changes
event?.getChangeLog()?.getRelated("ChildChangeItem")?.each{ change ->
def statusOLD = (String)change.oldstring
def statusNEW = (String)change.newstring

log.debug "${event.issue.getIssueType().name} ${event.issue.summary}"

//checking field name changed
if (change.field == "description"){
//blah
}
...
}
}

Also please check here for further details: https://scriptrunner.adaptavist.com/latest/jira/listeners.html 

Like Lev Ryvkin likes this
Lev Ryvkin February 14, 2019

Thank you very much!

Eric Sebian June 17, 2020

Is there a way to do this in reverse? Meaning that the Epic is updated with the values from all linked issues.

Hector
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.
June 17, 2020

Hi @Eric Sebian , Listener code works for any issue just a matter to filter and execute the code based on your needs. Once filtered, the only point is you need to look for the parent issue, via Epic link or parent linked issue (inward), in order to update the fields you need accordingly. Hope it helps.

Sai Praveen Aminigadda July 8, 2021

@Hector can we use this code for schedule jobs also?

Suggest an answer

Log in or Sign up to answer