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

How to link a post-function 'cloned' task to an Epic that is indirectly linked to the 'cloned' task

Lara Arthur March 26, 2021

Hi Atlassian Community,

Please note that the last answer posted from me is the correct coding...however, I wanted to give @Max Lim _Adaptavist_ credit for actually answering sooo...if you are trying to do something similar, look at the last coding block.

Alrighty...let me see if I can describe this well enough to get some ideas/assistance.

We have put together a Support Request issue type that is created and auto linked from a projects Epic (using a combo of ScriptRunners fragments/behaviours). Thought process behind this was since these requests will happen mainly during Quarterly Planning and Epics are how we capture 'ideas of work', that it makes sense to send out these requests and link them to the Epic body of work. Our workflow allows the teams to kick it back to each other for more info as needed as well as accepting/rejecting the request. We then can run a nice filter to show interdependency, timliness of requesting support, etc, etc.  image.png

Once the Support Request is approved, it auto creates a task in the supporting teams project and another link is created to the originating Support Request.image.png

From there they can keep it as a placeholder task OR move it to whatever it will require work wise...ie Story if the support includes any development. image.png

Now, we are looking to somehow take the original Epic and do the following:

  1. add the Epic link in which the Support Request (SR)  was created from, to the resulting support task
  2. automatically add the resulting SR task as a child of the Epic in which the Support Request was created from (ultimately this is what we'd like to do since the Team requesting support will be listing the resulting Task or work in their Release scope)

Right now the way it is set up, you have to manually click back 2 links to find the originating Epic and manually connect the two via a link. I can't for the life of me wrap my head around how exactly to automate this so that Teams don't have to follow the breadcrumbs back to the originating Epic.

I have found code to copy or add from the original issue to the linked issue, but not through 2 links. I've tried copying the epic link when cloning...and this does work, but the link doesn't make sense on the resulting task. I've also tried creating a parent hierarchy scripted field using a built in SR function and tried to copy this field over during the clone post function - this doesn't work since the scripted field is looking at the first link and hence will not copy over.

Any ideas would be most helpful!

2 answers

2 accepted

Suggest an answer

Log in or Sign up to answer
0 votes
Answer accepted
Lara Arthur April 20, 2021

Thanks to Max's tenacity...he was able to solve my coding issue. Thanks again @Max Lim _Adaptavist_ !

Here is the working code:

import com.atlassian.jira.project.ProjectImpl
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLinkTypeManager

//Adding "IN SUPPORT OF:"" before the summary pulled from the Support Request
issue.summary = "IN SUPPORT OF: " + issue.summary

//Telling Jira where to assign the resulting Task from the SR to the corresponding project, using the Supporting Project custom field (project picker)
def cf = customFieldManager.getCustomFieldObjects(sourceIssue).find
{it.name == 'Supporting Project'}
def project = sourceIssue.getCustomFieldValue(cf) as ProjectImpl
issue.setProjectObject(project)

//What issue link to pull - adding the Epic Link to the resulting Task as well as adding the "blocks" link from the resulting Task to the Epic the SR was created from
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def epicIssueLinked = ComponentAccessor.getIssueLinkManager().getInwardLinks(sourceIssue.id).find(
{it.getIssueLinkType().name == "Support Request"}
).getSourceObject()

def epicLinkCustomField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Epic Link")
def blockLink = ComponentAccessor.getComponent(IssueLinkTypeManager).getIssueLinkTypesByName("Blocks").first()

issue.setCustomFieldValue(epicLinkCustomField, epicIssueLinked)
doAfterCreate = {
issueLinkManager.createIssueLink(issue.id, epicIssueLinked.id, blockLink.getId(), null, user)
}

This was used in the ScriptRunner Clones and issue and links - Additional issue actions.

0 votes
Answer accepted
Max Lim _Adaptavist_
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.
April 5, 2021

 

Once the Support Request is approved, it auto creates a task.

Assuming you create this Task issue with post-function when Support Request issue is approved, as an example, you can extend the post-function to link the created Task to the original Epic with following script:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLinkTypeManager
import com.atlassian.jira.event.type.EventDispatchOption


def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def issueLinkManager = ComponentAccessor.getIssueLinkManager()
//"issue" is a binding variable available to the approved Support Request issue
def epicLinked = issueLinkManager.getInwardLinks(issue.id).find({it.getIssueLinkType().name == "Epic-Story Link"}).getSourceObject()
def epicLink = ComponentAccessor.getComponent(IssueLinkTypeManager).getIssueLinkTypesByName("Epic-Story Link").first()

//"createdTask" is the created Task issue, you should replace with corresponding name in your script
issueLinkManager.createIssueLink(epicLinked.id, createdTask.id, epicLink.getId(), null, user)

 

Lara Arthur April 5, 2021

@Max Lim _Adaptavist_ Hi Max - thanks for the reply.

I had found a posting with that info in it, but did not think it would work dynamically. Since the Support Request will always be a new issue #, I cannot constantly update the post function code to add the 'getIssueByCurrentKey' issue #.  How would you code this dynamically? Can I just take out the issue #'s ie 

def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey() 

instead of 

def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("SS-3")

Also, this is what I have presently in my Additional issue actions (Clones an issue, and links postfunction):

issue.summary = "IN SUPPORT OF: " + issue.summary
import com.atlassian.jira.project.ProjectImpl
def cf = customFieldManager.getCustomFieldObjects(sourceIssue).find {it.name == 'Supporting Project'}
def project = sourceIssue.getCustomFieldValue(cf) as ProjectImpl
issue.setProjectObject(project)

The Task is being created based on the Supporting Project project picker field. If I add the code from you, I get 2 warnings...

So if all addtional issue actions are this:

issue.summary = "IN SUPPORT OF: " + issue.summary
import com.atlassian.jira.project.ProjectImpl
def cf = customFieldManager.getCustomFieldObjects(sourceIssue).find {it.name == 'Supporting Project'}
def project = sourceIssue.getCustomFieldValue(cf) as ProjectImpl
issue.setProjectObject(project)

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLinkTypeManager
import com.atlassian.jira.event.type.EventDispatchOption

def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("SS-3")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def createdTask = ComponentAccessor.getIssueManager().getIssueByCurrentKey("SS-4")

def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def epicLinked = issueLinkManager.getInwardLinks(issue.id).find({it.getIssueLinkType().name == "Epic-Story Link"}).getSourceObject()
def epicLink = ComponentAccessor.getComponent(IssueLinkTypeManager).getIssueLinkTypesByName("Epic-Story Link").first()
def blockLink = ComponentAccessor.getComponent(IssueLinkTypeManager).getIssueLinkTypesByName("Blocks").first()

issueLinkManager.createIssueLink(epicLinked.id, createdTask.id, epicLink.getId(), null, user)
issueLinkManager.createIssueLink(createdTask.id, epicLinked.id, blockLink.getId(), null, user)

The warnings are: 

image.png

and

image.png

I tried it just for grins and adding your code negates my creating the task in the corresponding "Supporting Project"

Max Lim _Adaptavist_
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.
April 5, 2021

First Warning

You can use the binding variables available (marked with arrow) for you to put in the appropriate variables:

Check binding variables.png

 

With proper variables, this revised version should work for you:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLinkTypeManager
import com.atlassian.jira.event.type.EventDispatchOption


def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def epicIssueLinked = issueLinkManager.getInwardLinks(sourceIssue.id).find({it.getIssueLinkType().name == "Epic-Story Link"}).getSourceObject()
def epicLink = ComponentAccessor.getComponent(IssueLinkTypeManager).getIssueLinkTypesByName("Epic-Story Link").first()

issueLinkManager.createIssueLink(epicIssueLinked.id, issue.id, epicLink.getId(), null, user)

 

Second warning
It might due to the version ScriptRunner you are using. The binded issueLinkManager is deprecated now. You can simply ignore this.

TAGS
AUG Leaders

Atlassian Community Events