Hi,
Need to clone an Epic with all dependent issues and sub-tasks.
tks
Antonio
Hi @Antonio Caeiro
For your requirement, you could try something like this:-
import com.atlassian.jira.component.ComponentAccessorimport com.atlassian.jira.event.type.EventDispatchOptionimport com.atlassian.jira.issue.Issueimport com.atlassian.jira.issue.ModifiedValueimport com.atlassian.jira.issue.util.DefaultIssueChangeHolderdef loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUserdef customFieldManager = ComponentAccessor.customFieldManagerdef issueManager = ComponentAccessor.issueManagerdef issueLinkManager = ComponentAccessor.issueLinkManagerdef issueFactory = ComponentAccessor.issueFactorydef subtaskManager = ComponentAccessor.subTaskManagerdef originalIssuesInEpic = [] as ArrayList<Issue>def changeHolder = new DefaultIssueChangeHolder()/** * Create a clone of an issue */static def clonedIssue(Issue issue) { def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUserdef 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.namedef destinationObject = it.destinationObjectif (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.subTaskObjectsif (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
Hi Ram, tks for the script. it works fine.
however, the script have some errors when writing into the script window. any idea?
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.loggedInUserdef 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.loggedInUserdef 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.ComponentAccessorimport com.atlassian.jira.event.type.EventDispatchOptionimport com.atlassian.jira.issue.Issueimport com.atlassian.jira.issue.ModifiedValueimport com.atlassian.jira.issue.util.DefaultIssueChangeHolderdef loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUserdef customFieldManager = ComponentAccessor.customFieldManagerdef issueManager = ComponentAccessor.issueManagerdef issueLinkManager = ComponentAccessor.issueLinkManagerdef issueFactory = ComponentAccessor.issueFactorydef subtaskManager = ComponentAccessor.subTaskManagerdef originalIssuesInEpic = [] as ArrayList<Issue>def changeHolder = new DefaultIssueChangeHolder()/** * Create a clone of an issue */static Issue clonedIssue(Issue issue) { def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUserdef 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.namedef destinationObject = it.destinationObjectif (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.subTaskObjectsif (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) }}
Thank you and Kind regards,
Ram
Tks Ram, it is perfect now.
many thanks
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.ComponentAccessorimport com.atlassian.jira.event.type.EventDispatchOptionimport com.atlassian.jira.issue.*import com.atlassian.jira.issue.util.DefaultIssueChangeHolderimport com.atlassian.jira.user.ApplicationUserdef loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUserdef customFieldManager = ComponentAccessor.customFieldManagerdef issueManager = ComponentAccessor.issueManagerdef issueLinkManager = ComponentAccessor.issueLinkManagerdef issueFactory = ComponentAccessor.issueFactorydef subtaskManager = ComponentAccessor.subTaskManagerdef issue = issueManager.getIssueByCurrentKey("SAFEDEMO-35")def changeHolder = new DefaultIssueChangeHolder()//Create a clone of an issuestatic 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 epicif (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
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:
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.
Any insight would be very helpful!
Thank you!
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
Hi @[deleted], I have tried your script and edited two things:
1. Line 27 - changed the key to an epic that should be cloned:
Hi @Anna Hummel
You can take a look at the updated code in the Adaptavist Library.
Hope this helps to answer your question.
It looks like you're new here. Sign in or register to get started.