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

Create default list of issues when creating JIRA epic associated with component type

sanjay_rakh February 27, 2024

We would like a specific list of issues to be created when an epic is created with component of type "Upgrade Project" or "New Client Project". 

These issue will be created from CSV file wherein we have 7 Issue Type of type Task and summary end text would be appended text (example:  ABXX Upgrade Project - UAT Build ) and would have different component for each task as it is CSV file. 

Issue TypeSummaryComponentEstimated TimeDescriptionPriorityAssignee

Can someone please help to automate this using Scrip runner groovy script.

1 answer

0 votes
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.
February 28, 2024

Hi @sanjay_rakh

For your requirement, you will need to do something like this:-

import com.adaptavist.hapi.jira.issues.Issues

def file = new File('/home/ram/Downloads/issue_data.csv') // Modify the Path where the csv is stored

def list = [] as ArrayList<Map>

def projectKey = 'MOCK'

def epic = Issues.getByKey('MOCK-1') // Enter Epic Key

/**
* Extract the value from the CSV file and add it to a List of Maps
*/
file.eachLine {
def column = it.split(',')
def mapInput = [:] as Map
mapInput.put('Issue Type', column[0])
mapInput.put('Summary', column[1])
mapInput.put('Component', column[2])
mapInput.put('Estimated Time', column[3])
mapInput.put('Description', column[4])
mapInput.put('Priority', column[5])
mapInput.put('Assignee', column[6])
list.add(mapInput)
}
list.remove(0)

list.each { Map map ->
Issues.create(projectKey, map['Issue Type'].toString().trim()) {
setAssignee(map['Assignee'].toString().trim())
setSummary(map['Summary'].toString().trim())
setDescription(map['Description'].toString().trim())
setPriority(map['Priority'].toString().trim())
setComponents(map['Component'].toString().trim())
setOriginalEstimate(map['Estimated Time'].toString().trim())
setPriority(map['Priority'].toString().trim())
setEpic(epic)
}
}

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

I have tested this in my environment, and it works as expected. I can create new issues according to the values set in the CSV file and automatically add them to the Epic issue.

Below is the sample CSV document that I have tested with:-

csv_data.png

First, ensure that you have the Epic created first. Once you have done that, set the Epic key to this line:-

def epic = Issues.getByKey('MOCK-1') // Enter Epic Key

Next, ensure you have saved the csv file in the correct directory path that is accessible to your Jira instance. You must update the path and file details in this line:-

 

def file = new File('/home/ram/Downloads/issue_data.csv') // Modify the Path where the csv is stored

 Finally, execute the code on the ScriptRunner console.

I hope this helps to solve your question. :-)

Thank you and Kind regards,
Ram

sanjay_rakh February 28, 2024

Thank you @Ram Kumar Aravindakshan _Adaptavist_  for your quick response on this.

On Scriptrunner console the above code on line import com.adaptavist.hapi.jira.issues.Issues. Getting "unable to resolve class".

 

I was trying to test the script from the console. Scriptrunner plugin that is installed 6.40.1 on Dev instance.

 

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.
February 28, 2024

Hi @sanjay_rakh

Scriptrunner 6.40.1 is very outdated.

Please update your ScriptRunner plugin to the latest release as there are a lot of fixes and new features since the current version you are using.

The code I have provided is built on the HAPI which is available after Scriptrunner 7.12.0 and above.

Thank you and Kind regards,

Ram

 

sanjay_rakh February 28, 2024

Hi @Ram Kumar Aravindakshan _Adaptavist_ 

I cannot update the plugin due the Jira server maintenance expiry. Can you provide alternative solution that would support the available version on scriptrunner.

Also after upgrading Jira and scriptrunner to higher version the script will continue to work? 

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.
February 29, 2024

Hi @sanjay_rakh

The old approach is very dirty, and I do not recommend it.

However, for your reference, below is a working example of the old approach:-

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

def issueManager = ComponentAccessor.issueManager
def issueFactory = ComponentAccessor.issueFactory
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.customFieldManager
def priorities = ComponentAccessor.getComponent(PriorityManager).priorities
def userManager = ComponentAccessor.userManager
def constantsManager = ComponentAccessor.constantsManager
def projectComponentManager = ComponentAccessor.projectComponentManager

def file = new File('/home/ram/Downloads/issue_data.csv') // Modify the Path where the csv is stored
def list = [] as ArrayList<Map>
def epic = issueManager.getIssueByCurrentKey('MOCK-1') // Enter Epic Key
def project = epic.projectObject

/**
* Extract the value from the CSV file and add it to a List of Maps
*/
file.eachLine {
def column = it.split(',')
def mapInput = [:] as Map
mapInput.put('Issue Type', column[0].trim())
mapInput.put('Summary', column[1].trim())
mapInput.put('Component', column[2].trim())
mapInput.put('Estimated Time', column[3].trim())
mapInput.put('Description', column[4].trim())
mapInput.put('Priority', column[5].trim())
mapInput.put('Assignee', column[6].trim())
list.add(mapInput)
}
list.remove(0)

list.each { map ->
def issueObject = issueFactory.issue
def issueType = constantsManager.allIssueTypeObjects.find {it.name == map['Issue Type'] }.id
def component = projectComponentManager.findByComponentName(project.id,map['Component'])
def estimate = map['Estimated Time'].toString().replace('d','').trim()
issueObject.setProjectObject(project)
issueObject.setSummary(map['Summary'])
issueObject.setDescription(map['Description'])
issueObject.setIssueTypeId(issueType)
issueObject.setPriority(priorities.find {it.name == map['Priority']})
issueObject.setOriginalEstimate(Long.parseLong(estimate) * 8 * 3600) // Estimate by day
issueObject.setReporter(loggedInUser)
issueObject.setComponent([component])
issueObject.setAssignee(userManager.getUserByName(map['Assignee']))
issueManager.createIssueObject(loggedInUser,issueObject)
def targetField = customFieldManager.getCustomFieldObjects(issueObject).findByName('Epic Link')
targetField.updateValue(null, issueObject, new ModifiedValue(issueObject.getCustomFieldValue(targetField), epic), new DefaultIssueChangeHolder())
issueManager.updateIssue(loggedInUser, issueObject, EventDispatchOption.DO_NOT_DISPATCH, false)
}

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

Thank you and Kind regards,

Ram

sanjay_rakh February 29, 2024

Thank you @Ram Kumar Aravindakshan _Adaptavist_ for working on this and writing the script. I am see below error 

Cannot find matching method MutableIssue#setDescription(V)

Cannot find matching method MutableIssue#setSummary(V)

etc

 Error.PNG

sanjay_rakh February 29, 2024

Hi @Ram Kumar Aravindakshan _Adaptavist_ 

I am able to resolve it by adding .toString to the error line. I am able to create the issues from the csv now.

But my ask is that whenever the Epic is created using the component type example 'ABC' this script should run and create issues underneath the Epic.

We do not want to set epic manually in the script. 

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.
February 29, 2024

Hi @sanjay_rakh

As I mentioned in my previous comment:-

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

The code I have provided is tested on the ScriptRunner console. You will need to make the required modifications for it to work on the Post-Function.

Please do not just copy and paste the code expecting it to work. This will not happen as the code has been tested in my environment, which is different from yours.

In your case, you must add a Post-Function, i.e. in the Create Transition.

You will need to use ScriptRunner's Custom Script Post-Function.

In the Custom Script Post-Function page, you do not need to set the Issue Key for the Epic issue.

You can remove this line:-

def epic = issueManager.getIssueByCurrentKey('MOCK-1') // Enter Epic Key

and add this condition:-

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

...

}

So the code should be something like this:-

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

def issueManager = ComponentAccessor.issueManager
def issueFactory = ComponentAccessor.issueFactory
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.customFieldManager
def priorities = ComponentAccessor.getComponent(PriorityManager).priorities
def userManager = ComponentAccessor.userManager
def constantsManager = ComponentAccessor.constantsManager
def projectComponentManager = ComponentAccessor.projectComponentManager

def file = new File('/home/ram/Downloads/issue_data.csv') // Modify the Path where the csv is stored
def list = [] as ArrayList<Map>

/**
* Extract the value from the CSV file and add it to a List of Maps
*/
file.eachLine {
def column = it.split(',')
def mapInput = [:] as Map
mapInput.put('Issue Type', column[0].trim())
mapInput.put('Summary', column[1].trim())
mapInput.put('Component', column[2].trim())
mapInput.put('Estimated Time', column[3].trim())
mapInput.put('Description', column[4].trim())
mapInput.put('Priority', column[5].trim())
mapInput.put('Assignee', column[6].trim())
list.add(mapInput)
}
list.remove(0)

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

def project = issue.projectObject

list.each { map ->
def issueObject = issueFactory.issue
def issueType = constantsManager.allIssueTypeObjects.find {it.name == map['Issue Type'] }.id
def component = projectComponentManager.findByComponentName(project.id,map['Component'])
def estimate = map['Estimated Time'].toString().replace('d','').trim()
issueObject.setProjectObject(project)
issueObject.setSummary(map['Summary'])
issueObject.setDescription(map['Description'])
issueObject.setIssueTypeId(issueType)
issueObject.setPriority(priorities.find {it.name == map['Priority']})
issueObject.setOriginalEstimate(Long.parseLong(estimate) * 8 * 3600) // Estimate by day
issueObject.setReporter(loggedInUser)
issueObject.setComponent([component])
issueObject.setAssignee(userManager.getUserByName(map['Assignee']))
issueManager.createIssueObject(loggedInUser,issueObject)
def targetField = customFieldManager.getCustomFieldObjects(issueObject).findByName('Epic Link')
targetField.updateValue(null, issueObject, new ModifiedValue(issueObject.getCustomFieldValue(targetField), epic), new DefaultIssueChangeHolder())
issueManager.updateIssue(loggedInUser, issueObject, EventDispatchOption.DO_NOT_DISPATCH, false)
}
}

You will need to modify the code according to your requirements.

You also mentioned:-

 am see below error 

Cannot find matching method MutableIssue#setDescription(V)

Cannot find matching method MutableIssue#setSummary(V)

You are using a very old ScriptRunner editor which has its limitations. This editor has already been changed in the later versions, and the Strict Type validation problem you facing has been resolved.

Although you see that error, the code will still work. You don't have to convert it to String.

Thank you and Kind regards,

Ram

 

 

sanjay_rakh February 29, 2024

Hi @Ram Kumar Aravindakshan _Adaptavist_ 

Thank you so much for your quick response and support for writing the script.

Sorry I missed to mention that there are 2 CSV file (Upgrade Project.csv and New Project.csv) and the issues to be created using CSV would be based on issuetype= Epic and component = "Upgrade Project" or component = "New Project".

So extracting the value from the CSV file 1 or file 2 and add it to a List of Map will be based on condition whether component 1 or component 2 is selected.

 

Thank and Regards

Sanjay

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.
February 29, 2024

Hi @sanjay_rakh

You are going to have to play around with the code to match your requirements.

Thank you and Kind regards,

Ram

sanjay_rakh March 19, 2024

@Ram Kumar Aravindakshan _Adaptavist_ I tried play around with the code but failed to get it working and encountering different errors. As new to Scriptrunner groovy finding hard time to resolve this issue.

 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events