Scriptrunner: Custom Listener: Works always on Creating Issues, Only sometimes on Updating Issues

david-guild August 5, 2019

Hello All,

Note: Server Edition

I wrote a custom listener to sync custom fields from the issue you are linking to.

ie: Create a Story, Link to Epic, copy custom fields down to Story.

This works, for a Story that is linking to an Epic, both when creating an issue (adding the Epic link in the form), as well as when editing the issue and adding a new link.

Shift to Epics, where the linking field is "parent" and not "epic" ...

This works, for an Epic, but only when you create AND set the "parent" field at the same time. 

If I create the Epic without a "parent" link, then edit in the parent link, it doesn't work.

In ALL cases, the listener fires, and my "info" logs show everything working correctly ... it's just the "update" action doesn't appear to work the same as the "create issue" action.

I am new to Groovy and Scriptrunner so any help would be appreciated.  Here is the code:

/*
* Fires when a Issue Link is created.
* Exits if Linked to Issue is not Initiative / Feature / Epic
* Copies Custom Fields down from Linked Issue
*/
import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.event.issue.link.IssueLinkCreatedEvent

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue

// Change Logger
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.acme.CreateSubtask")
log.setLevel(Level.INFO)

// Setup Custom Field Manager
def CustomFieldManager = ComponentAccessor.getCustomFieldManager()

// Setup Issue Manager
def IssueManager = ComponentAccessor.getIssueManager()

/**
* Grab both target and source issue objects from the event
*/

// Grab Event
def event = event as IssueLinkCreatedEvent

// sourceIssue is really the Issue that is being Linked to.
def sourceIssue = event.getIssueLink().getSourceObject()
log.info("sourceIssue: " + sourceIssue.key)


// Exit if not Initiative / Feature / Epic
if (sourceIssue.issueType.name != "Epic" &&
sourceIssue.issueType.name != "Feature" &&
sourceIssue.issueType.name != "Initiative") {
log.info("Exiting ... sourceIssue type of: " + sourceIssue.issueType.name + " is not Epic / Feature / Initiative")
return 0
}

// Which makes the Destination object really the issue

def issue = event.getIssueLink().getDestinationObject()

log.info("issue: " + issue.key)

// define ChangeHolder Object
def changeHolder = new DefaultIssueChangeHolder();

/**
* Account Section
*/

// setup CfAccount field object
def CfAccount = CustomFieldManager.getCustomFieldObject('customfield_10500')
log.info("CfAccount: " + CfAccount)


// Copy if target Field IS Empty and source field is NOT Emtpy
if(!issue.getCustomFieldValue(CfAccount) &&
sourceIssue.getCustomFieldValue(CfAccount)
) {
def oldData = issue.getCustomFieldValue(CfAccount)
def newData = sourceIssue.getCustomFieldValue(CfAccount)

CfAccount.updateValue(null, issue, new ModifiedValue(oldData, newData), changeHolder);
log.info("Account Updated to: " + newData)
} else {
log.info ("Not CfAccount && not value in CfAccount")
}

Note: There are about 5 more block of custom fields, but left those off as they are exactly the same, just with different fields.

In all cases, the "logging" info looks correct, and I can't find any obvious errors in the jira log.

Why this works *always* on a create issue, but only for certain situations when editing is really strange.

Any help would be greatly appreciated.

Also of note: I would love this to be more OO.  Having to repeat the Copy Field logic block over and over again just goes against the grain.  Would like to have a method where I pass in the CustomField object, and the two issues, and let it do the rest.

ie: this->updateCustom(issue, sourceIssue, "customfield_10500") ... or something like that.

Thanks again, this is driving me nuts. 

1 answer

0 votes
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 5, 2019

My experience in the past was that changing the epic link field didin't fire any event whatsoever.

I just tested and it appears to now, (7.13.2) it fires com.atlassian.jira.event.issue.link.IssueLinkCreatedEvent

So if you just watch for the Issue Updated event, you won't find it.

But watching for that event... and extracting the epic and issue from the event.issueLink, you should be able to re-jig your code above to work.

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 5, 2019

Nevemind ... looks like you already considered that. I didn't read carefully.

I'll re-read again more closely now.

david-guild August 6, 2019

It's really a strange situation.  

The only difference here is that the "Feature" that the Epic is linking to is in another project called Portfolio.  Again, if I create the Epic and add the Feature link directly it, it works fine.  

It's only when I link to the Feature "after" the Epic is created that things go pear shaped. 

Based upon my logging, the Edit is firing the listener, and the listener appears to be updating the field.

It's almost like something else is changing it back.  I disabled all my other listeners to avoid conflict.  I even wrote a new listener to watch for changing, and it does appear something is changing it back:

 

2019-08-05 16:22:50,728 INFO [acme.CreateSubtask]: isueType: Epic
2019-08-05 16:22:50,728 INFO [acme.CreateSubtask]: isueType: Epic
2019-08-05 16:22:50,728 INFO [acme.CreateSubtask]: issue: BETA-541
2019-08-05 16:22:50,728 INFO [acme.CreateSubtask]: issue: BETA-541
2019-08-05 16:22:50,730 INFO [acme.CreateSubtask]: Value changed from RTLPRD - Retail Marketing (0012) to None
2019-08-05 16:22:50,730 INFO [acme.CreateSubtask]: Value changed from RTLPRD - Retail Marketing (0012) to None

Note: I don't know why I started getting double log entries. 

The correct value does appear, and then it's gets changed back to "None". 

Code for the listener to match that log.  

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.model.ChangeGroup
import com.atlassian.jira.model.ChangeItem
import com.atlassian.jira.issue.history.ChangeItemBean

// Change Logger
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.acme.CreateSubtask")
log.setLevel(Level.INFO)

def issue = event.issue

log.info("isueType: " + issue.issueType.name)
log.info("issue: " + issue)

def change = event?.getChangeLog()?.getRelated("ChildChangeItem")?.find {
it.field == "Account"
}

if (change) {
  log.info "Value changed from ${change.oldstring} to ${change.newstring}"
}

Any help would be appreciated ...

Suggest an answer

Log in or Sign up to answer