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 Type | Summary | Component | Estimated Time | Description | Priority | Assignee |
Can someone please help to automate this using Scrip runner groovy script.
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:-
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
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @sanjay_rakh
You are going to have to play around with the code to match your requirements.
Thank you and Kind regards,
Ram
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.