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.
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.
Nevemind ... looks like you already considered that. I didn't read carefully.
I'll re-read again more closely now.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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 ...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.