scriptrunner clone epic with all child tasks and sub-tasks

Antonio Caeiro March 7, 2022

Hi,

Need to clone an Epic with all dependent issues and sub-tasks. 

 

tks

Antonio

4 answers

1 accepted

0 votes
Answer accepted
Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 8, 2022

Hi @Antonio Caeiro

For your requirement, you could try something like this:-

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.customFieldManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def issueFactory = ComponentAccessor.issueFactory
def subtaskManager = ComponentAccessor.subTaskManager

def originalIssuesInEpic = [] as ArrayList<Issue>
def changeHolder = new DefaultIssueChangeHolder()


/**
* Create a clone of an issue
*/
static def clonedIssue(Issue issue) {
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def issueManager = ComponentAccessor.issueManager
def issueFactory = ComponentAccessor.issueFactory

def cloneIssueFactory = issueFactory.cloneIssue(issue)
def newIssueParams = ["issue": cloneIssueFactory] as Map<String, Object>
issueManager.createIssueObject(loggedInUser, newIssueParams)
}


if (issue.issueType.name=="Epic") {

/**
* Cloning of the Epic
*/
def epicClone = clonedIssue(issue)
def epic = issueManager.getIssueByCurrentKey(epicClone.key)
def epicName = customFieldManager.getCustomFieldObjectsByName("Epic Name")[0]
def originalEpicName = issue.getCustomFieldValue(epicName)
epicName.updateValue(null, epic, new ModifiedValue(epic.getCustomFieldValue(epicName), "${originalEpicName} Clone".toString()),changeHolder)
issueManager.updateIssue(loggedInUser, epic, EventDispatchOption.ISSUE_UPDATED, false)

/**
* Extraction of Original Issues from Original Epic
*/
def links = issueLinkManager.getOutwardLinks(issue.id)
links.findAll {
def name = it.issueLinkType.name
def destinationObject = it.destinationObject
if (name == "Epic-Story Link") {
originalIssuesInEpic.add(destinationObject)
}
}

/**
* Cloning of Original Issue from the Epic and Adding it
* to the Cloned Epic
*/
originalIssuesInEpic.findAll {
def clonedIssue = clonedIssue(it)
def subtasks = it.subTaskObjects

if (subtasks) {
subtasks.each {subtask ->
def toClone = issueFactory.cloneIssueWithAllFields(subtask)
def cloned = issueManager.createIssueObject(clonedIssue.reporter, toClone)
subtaskManager.createSubTaskIssueLink(clonedIssue, cloned, clonedIssue.reporter)
}
}

def targetField = customFieldManager.getCustomFieldObjects(clonedIssue).findByName("Epic Link")
targetField.updateValue(null, clonedIssue, new ModifiedValue(clonedIssue.getCustomFieldValue(targetField), epic), changeHolder)
}
}

Please note the working sample code above is not 100% exact to your environment. Hence, you will need to make the required modifications.

This sample code above is for the Post-Function, i.e. when you transition the issue to a specific status, the cloning of the Epic, its issues and sub-tasks will take place.

I hope this helps to solve your question. :)

Thank you and Kind Regards,
Ram

Antonio Caeiro March 9, 2022

Hi Ram, tks for the script. it works fine.

 

however, the script have some errors when writing into the script window. any idea?

 

tks

Antonio

error.PNG

 

error.1PNG.png

error.2PNG.png

error.3PNG.pngerror.4PNG.pngerror.5PNG.pngerror.6PNG.pngerror.7PNG.png

 

 

 

 

Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 9, 2022

Hi @Antonio Caeiro

Glad to hear the script worked.

To fix the error messages, you need to make a minor modification in the code, i.e. modify this section

static def clonedIssue(Issue issue) {
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def issueManager = ComponentAccessor.issueManager
def issueFactory = ComponentAccessor.issueFactory

def cloneIssueFactory = issueFactory.cloneIssue(issue)
def newIssueParams = ["issue": cloneIssueFactory] as Map<String, Object>
issueManager.createIssueObject(loggedInUser, newIssueParams)
}

to

static Issue clonedIssue(Issue issue) {
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def issueManager = ComponentAccessor.issueManager
def issueFactory = ComponentAccessor.issueFactory

def cloneIssueFactory = issueFactory.cloneIssue(issue)
def newIssueParams = ["issue": cloneIssueFactory] as Map<String, Object>
issueManager.createIssueObject(loggedInUser, newIssueParams)
}

 so the updated code will be like:-

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.customFieldManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def issueFactory = ComponentAccessor.issueFactory
def subtaskManager = ComponentAccessor.subTaskManager

def originalIssuesInEpic = [] as ArrayList<Issue>
def changeHolder = new DefaultIssueChangeHolder()


/**
* Create a clone of an issue
*/
static Issue clonedIssue(Issue issue) {
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def issueManager = ComponentAccessor.issueManager
def issueFactory = ComponentAccessor.issueFactory

def cloneIssueFactory = issueFactory.cloneIssue(issue)
def newIssueParams = ["issue": cloneIssueFactory] as Map<String, Object>
issueManager.createIssueObject(loggedInUser, newIssueParams)
}


if (issue.issueType.name=="Epic") {

/**
* Cloning of the Epic
*/
def epicClone = clonedIssue(issue)
def epic = issueManager.getIssueByCurrentKey(epicClone.key)
def epicName = customFieldManager.getCustomFieldObjectsByName("Epic Name")[0]
def originalEpicName = issue.getCustomFieldValue(epicName)
epicName.updateValue(null, epic, new ModifiedValue(epic.getCustomFieldValue(epicName), "${originalEpicName} Clone".toString()),changeHolder)
issueManager.updateIssue(loggedInUser, epic, EventDispatchOption.ISSUE_UPDATED, false)

/**
* Extraction of Original Issues from Original Epic
*/
def links = issueLinkManager.getOutwardLinks(issue.id)
links.findAll {
def name = it.issueLinkType.name
def destinationObject = it.destinationObject
if (name == "Epic-Story Link") {
originalIssuesInEpic.add(destinationObject)
}
}

/**
* Cloning of Original Issue from the Epic and Adding it
* to the Cloned Epic
*/
originalIssuesInEpic.findAll {
def clonedIssue = clonedIssue(it)
def subtasks = it.subTaskObjects

if (subtasks) {
subtasks.each {subtask ->
def toClone = issueFactory.cloneIssueWithAllFields(subtask)
def cloned = issueManager.createIssueObject(clonedIssue.reporter, toClone)
subtaskManager.createSubTaskIssueLink(clonedIssue, cloned, clonedIssue.reporter)
}
}

def targetField = customFieldManager.getCustomFieldObjects(clonedIssue).findByName("Epic Link")
targetField.updateValue(null, clonedIssue, new ModifiedValue(clonedIssue.getCustomFieldValue(targetField), epic), changeHolder)
}
}

I hope this helps to solve your question. :)

Thank you and Kind regards,

Ram

Antonio Caeiro March 9, 2022

Tks Ram, it is perfect now.

 

many thanks

Antonio

Antonio Caeiro March 16, 2022

Hi @Ram Kumar Aravindakshan _Adaptavist_ can you kindly help on another thing.

 

i notice, the create date is being cloned from the original Epic.

I need the create date to reflect the current date (and not the date that is in the epic source).

 

can you advise?

 

tks

Antonio

Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 22, 2022

Hi @Antonio Caeiro

Apologies for the Delay.

So, if you want to include the updated timestamp when the Epic and its issues are cloned, you will need to modify the code to something like this:-

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.*
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.user.ApplicationUser

def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.customFieldManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def issueFactory = ComponentAccessor.issueFactory
def subtaskManager = ComponentAccessor.subTaskManager

def changeHolder = new DefaultIssueChangeHolder()

//Create a clone of an issue
static Issue clonedIssue(Issue issue, ApplicationUser loggedInUser, IssueFactory issueFactory, IssueManager issueManager) {
def cloneIssueFactory = issueFactory.cloneIssue(issue)
cloneIssueFactory.setCreated( new Date(System.currentTimeMillis()).toTimestamp() )
def newIssueParams = ['issue': cloneIssueFactory] as Map<String, Object>
issueManager.createIssueObject(loggedInUser, newIssueParams)
}

if (issue.issueType.name == 'Epic') {
//Cloning of the Epic
def epicClone = clonedIssue(issue, loggedInUser, issueFactory, issueManager)
def epic = issueManager.getIssueByCurrentKey(epicClone.key)
def epicName = customFieldManager.getCustomFieldObjectsByName('Epic Name').first()
def originalEpicName = issue.getCustomFieldValue(epicName)
epicName.updateValue(null, epic, new ModifiedValue(epic.getCustomFieldValue(epicName), "${originalEpicName} Clone".toString()), changeHolder)
issueManager.updateIssue(loggedInUser, epic, EventDispatchOption.ISSUE_UPDATED, false)

//Extraction of Original Issue(s) from Original Epic
def links = issueLinkManager.getOutwardLinks(issue.id)

def originalIssuesInEpic= links.findAll { it.issueLinkType.name == 'Epic-Story Link' }*.destinationObject

//Cloning of Original Issue(s) from the Original Epic and Adding it to the Cloned Epic
originalIssuesInEpic.each {
def clonedIssue = clonedIssue(it, loggedInUser, issueFactory, issueManager)
def subtasks = it.subTaskObjects
if (subtasks) {
subtasks.each {subtask ->
def mutableSubtask = subtasks as MutableIssue
mutableSubtask.setCreated(new Date(System.currentTimeMillis()).toTimestamp())
def toClone = issueFactory.cloneIssueWithAllFields(mutableSubtask)
def cloned = issueManager.createIssueObject(clonedIssue.reporter, toClone)
subtaskManager.createSubTaskIssueLink(clonedIssue, cloned, clonedIssue.reporter)
}
}
def targetField = customFieldManager.getCustomFieldObjects(clonedIssue).findByName('Epic Link')
targetField.updateValue(null, clonedIssue, new ModifiedValue(clonedIssue.getCustomFieldValue(targetField), epic), changeHolder)
}
}

The main modification I have made is in this section:-

//Create a clone of an issue
static Issue clonedIssue(Issue issue, ApplicationUser loggedInUser, IssueFactory issueFactory, IssueManager issueManager) {
def cloneIssueFactory = issueFactory.cloneIssue(issue)
cloneIssueFactory.setCreated( new Date(System.currentTimeMillis()).toTimestamp() )
def newIssueParams = ['issue': cloneIssueFactory] as Map<String, Object>
issueManager.createIssueObject(loggedInUser, newIssueParams)
}

 And also in this section:-

subtasks.each {subtask ->
def mutableSubtask = subtasks as MutableIssue
mutableSubtask.setCreated(new Date(System.currentTimeMillis()).toTimestamp())
def toClone = issueFactory.cloneIssueWithAllFields(mutableSubtask)
def cloned = issueManager.createIssueObject(clonedIssue.reporter, toClone)
subtaskManager.createSubTaskIssueLink(clonedIssue, cloned, clonedIssue.reporter)
}

I have mainly updated the issue using the setCreated method to update the Creation timestamp of the Clone Epic, its Issues and Sub-Tasks.

I hope this helps to solve your question. :)

Thank you and Kind regards,
Ram

Antonio Caeiro March 22, 2022

Hi @Ram Kumar Aravindakshan _Adaptavist_ 

 

tks for the code, however, i have the following error:

tks

 


 

2022-03-22 17:41:22,920 ERROR [workflow.AbstractScriptWorkflowFunction]: Workflow script has failed on issue DSM-1 for user 'ptzurace'. View here: https://deaww02349.emea.zurich.dev:8443/secure/admin/workflows/ViewWorkflowTransition.jspa?workflowMode=live&workflowName=DSM%3A+Project+Management+Workflow&descriptorTab=postfunctions&workflowTransition=71&highlight=2
java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
at Script14$_run_closure2$_closure3.doCall(Script14.groovy:44)
at Script14$_run_closure2.doCall(Script14.groovy:43)
at Script14.run(Script14.groovy:39)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner.runScriptAndGetContext(AbstractScriptRunner.groovy:180)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner$runScriptAndGetContext$2.callCurrent(Unknown Source)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner.runScriptAndGetContext(AbstractScriptRunner.groovy:299)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner$runScriptAndGetContext$1.callCurrent(Unknown Source)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner.runScript(AbstractScriptRunner.groovy:311)
at com.onresolve.scriptrunner.runner.ScriptRunner$runScript$10.call(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.utils.TypedCustomScriptDelegate.execute(TypedCustomScriptDelegate.groovy:19)
at com.onresolve.scriptrunner.canned.jira.utils.TypedCustomScriptDelegate$execute$0.call(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CustomScriptFunction.execute(CustomScriptFunction.groovy:53)
at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CustomScriptFunction$execute.callCurrent(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.workflow.AbstractWorkflowCannedScript.execute(AbstractWorkflowCannedScript.groovy:23)
at com.onresolve.scriptrunner.canned.jira.workflow.AbstractWorkflowCannedScript$execute$1.call(Unknown Source)
at com.onresolve.scriptrunner.jira.workflow.AbstractScriptWorkflowFunction$_run_closure2.doCall(AbstractScriptWorkflowFunction.groovy:89)
at com.onresolve.scriptrunner.jira.workflow.AbstractScriptWorkflowFunction$_run_closure2.doCall(AbstractScriptWorkflowFunction.groovy)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy:370)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy)
at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder.withRecording(ScriptExecutionRecorder.groovy:13)
at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder$withRecording.call(Unknown Source)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl.execute(DiagnosticsManagerImpl.groovy:368)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsExecutionHandler$execute$3.call(Unknown Source)
at com.onresolve.scriptrunner.jira.workflow.AbstractScriptWorkflowFunction.run(AbstractScriptWorkflowFunction.groovy:82)
Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyObject
... 24 more

Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 22, 2022

Hi @Antonio Caeiro

I didn't have any error messages when I tested it in my environments.

Could you please share the updated code you were using so I can review it?

Thank you and Kind regards,

Ram

Antonio Caeiro March 23, 2022

Hi @Ram Kumar Aravindakshan _Adaptavist_ 

 

i used this one tks

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.*
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.user.ApplicationUser

def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.customFieldManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def issueFactory = ComponentAccessor.issueFactory
def subtaskManager = ComponentAccessor.subTaskManager

def changeHolder = new DefaultIssueChangeHolder()

//Create a clone of an issue
static Issue clonedIssue(Issue issue, ApplicationUser loggedInUser, IssueFactory issueFactory, IssueManager issueManager) {
def cloneIssueFactory = issueFactory.cloneIssue(issue)
cloneIssueFactory.setCreated( new Date(System.currentTimeMillis()).toTimestamp() )
def newIssueParams = ['issue': cloneIssueFactory] as Map<String, Object>
issueManager.createIssueObject(loggedInUser, newIssueParams)
}

if (issue.issueType.name == 'Epic') {
//Cloning of the Epic
def epicClone = clonedIssue(issue, loggedInUser, issueFactory, issueManager)
def epic = issueManager.getIssueByCurrentKey(epicClone.key)
def epicName = customFieldManager.getCustomFieldObjectsByName('Epic Name').first()
def originalEpicName = issue.getCustomFieldValue(epicName)
epicName.updateValue(null, epic, new ModifiedValue(epic.getCustomFieldValue(epicName), "${originalEpicName} Clone".toString()), changeHolder)
issueManager.updateIssue(loggedInUser, epic, EventDispatchOption.ISSUE_UPDATED, false)

//Extraction of Original Issue(s) from Original Epic
def links = issueLinkManager.getOutwardLinks(issue.id)

def originalIssuesInEpic= links.findAll { it.issueLinkType.name == 'Epic-Story Link' }*.destinationObject

//Cloning of Original Issue(s) from the Original Epic and Adding it to the Cloned Epic
originalIssuesInEpic.each {
def clonedIssue = clonedIssue(it, loggedInUser, issueFactory, issueManager)
def subtasks = it.subTaskObjects
if (subtasks) {
subtasks.each {subtask ->
def mutableSubtask = subtasks as MutableIssue
mutableSubtask.setCreated(new Date(System.currentTimeMillis()).toTimestamp())
def toClone = issueFactory.cloneIssueWithAllFields(mutableSubtask)
def cloned = issueManager.createIssueObject(clonedIssue.reporter, toClone)
subtaskManager.createSubTaskIssueLink(clonedIssue, cloned, clonedIssue.reporter)
}
}
def targetField = customFieldManager.getCustomFieldObjects(clonedIssue).findByName('Epic Link')
targetField.updateValue(null, clonedIssue, new ModifiedValue(clonedIssue.getCustomFieldValue(targetField), epic), changeHolder)
}
}
Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 23, 2022

Hi @Antonio Caeiro

The error message doesn't seem to match the code you are using.

Aside from this post-function, do you have any other post-function configured for this project? If so, could you temporarily disable them and try to retest it once again and see if the error message is still returned?

Thank you and Kind Regards,

Ram

0 votes
Anna Hummel May 4, 2023

Hi @Ricardo Araya , I have tried your script and edited two things:

1. Line 27 - changed the key to an epic that should be cloned: 

def issue = issueManager.getIssueByCurrentKey("TAFS-3")
2. since my epic does have tasks as children, not stories, I guess I need to change the line 67 as well 
def originalIssuesInEpic= links.findAll { it.issueLinkType.name == 'Epic-Task Link' }*.destinationObject
Strangely, the script is working but not as it supposed to: 
1. it creates the epic without its children
2. it creates many epics + subtasks > more then 20. 
I dont get why. I would expect 1 epic with all its children. 
Could you help me, please? Thanks Anna
Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 4, 2023

Hi @Anna Hummel

You can take a look at the updated code in the Adaptavist Library.

Hope this helps to answer your question.

Thank you and Kind regards,

Ram

Like Anna Hummel likes this
0 votes
Alexandra-Mihaela Apostol September 13, 2022

Hello! Is it also possible to create for each subtask that was cloned in that project a new Task in another project? 

I tried something like the method below:

Capture1.PNG

but it seems I am getting a bunch of errors when trying to create a new issue in the same code block when the sub-tasks are cloned.

picture3.PNG

Any insight would be very helpful!

Thank you!

0 votes
Ricardo Araya May 25, 2022

Hello, I copied the last script and I had the same error, 
If anyone is intersted:
What the error was was in the subtasks.each module.
The line:

mutableSubtask.setCreated(new Date(System.currentTimeMillis()).toTimestamp())

 must be after

def toClone = issueFactory.cloneIssueWithAllFields(mutableSubtask)

So the final code is:


import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption

import com.atlassian.jira.issue.*

import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

import com.atlassian.jira.user.ApplicationUser

def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

def customFieldManager = ComponentAccessor.customFieldManager

def issueManager = ComponentAccessor.issueManager

def issueLinkManager = ComponentAccessor.issueLinkManager

def issueFactory = ComponentAccessor.issueFactory

def subtaskManager = ComponentAccessor.subTaskManager

def issue = issueManager.getIssueByCurrentKey("SAFEDEMO-35")

def changeHolder = new DefaultIssueChangeHolder()

//Create a clone of an issue

static Issue clonedIssue(Issue issue, ApplicationUser loggedInUser, IssueFactory issueFactory, IssueManager issueManager) {

    def cloneIssueFactory = issueFactory.cloneIssue(issue)

    cloneIssueFactory.setCreated( new Date(System.currentTimeMillis()).toTimestamp() )

    def newIssueParams = ['issue': cloneIssueFactory] as Map<String, Object>

    issueManager.createIssueObject(loggedInUser, newIssueParams)

}

def epic

if (issue.issueType.name == 'Epic') {

    //Cloning of the Epic

    def epicClone = clonedIssue(issue, loggedInUser, issueFactory, issueManager)

    epic = issueManager.getIssueByCurrentKey(epicClone.key)

    def epicName = customFieldManager.getCustomFieldObjectsByName('Epic Name').first()

    def originalEpicName = issue.getCustomFieldValue(epicName)

    epicName.updateValue(null, epic, new ModifiedValue(epic.getCustomFieldValue(epicName), "${originalEpicName} Clone".toString()), changeHolder)

    issueManager.updateIssue(loggedInUser, epic, EventDispatchOption.ISSUE_UPDATED, false)

    //Extraction of Original Issue(s) from Original Epic

    def links = issueLinkManager.getOutwardLinks(issue.id)

    def originalIssuesInEpic= links.findAll { it.issueLinkType.name == 'Epic-Story Link' }*.destinationObject

    //Cloning of Original Issue(s) from the Original Epic and Adding it to the Cloned Epic

    originalIssuesInEpic.each {

        def clonedIssue = clonedIssue(it, loggedInUser, issueFactory, issueManager)

        def subtasks = it.subTaskObjects

        if (subtasks) {

            subtasks.each {subtask ->

               

                def mutableSubtask = subtask as MutableIssue

               

               

                def toClone = issueFactory.cloneIssue(mutableSubtask)

                mutableSubtask.setCreated(new Date(System.currentTimeMillis()).toTimestamp())

                def cloned = issueManager.createIssueObject(clonedIssue.reporter, toClone)

                subtaskManager.createSubTaskIssueLink(clonedIssue, cloned, clonedIssue.reporter)

               

            log.warn(subtask.key)

            }

        }

        def targetField = customFieldManager.getCustomFieldObjects(clonedIssue).findByName('Epic Link')

        targetField.updateValue(null, clonedIssue, new ModifiedValue(clonedIssue.getCustomFieldValue(targetField), epic), changeHolder)

    }

}

return epic
Patrick Rach October 26, 2022

how would I include all the customfields of the Epic and the story points of the Story that gets cloned with the incoming Epic?

 

Disregard, I figured it out. The line of code that states def cloneIssueFactory = issueFactory.cloneIssue(issue)

Change that to 

def cloneIssueFactory = issueFactory.cloneIssueWithAllFields(issue)

Suggest an answer

Log in or Sign up to answer