Using Adaptavist ScriptRuner
I need to check all opens issues(add value(from parent epic) to the "Deadline" field if it is null) in all open epics in project "BUIS".
I think, this can to use cycle(find epics), but i dont know how. Please, write solution or examples.
Hey Andrey!
I am unsure of the "cicle" method that you are referring to, but I believe the easiest way to do this would actually be to just run a stand-alone script in the ScriptRunner Script Console.
As far as the script goes, you can pick one of two options for traversing the project's issues. Either you run through all of the issues in a project and check their Epic Link custom field to obtain the linked epic. Or you go through and find every epic in a project and then look at all of that epic's linked issues. I've gone ahead and coded up the two variants for you and will paste them below:
Traverse all issues and look at Epic Link field
import com.atlassian.jira.component.ComponentAccessor
//Get necessary managers
def projectManager = ComponentAccessor.projectManager
def issueManager = ComponentAccessor.issueManager
def cfm = ComponentAccessor.customFieldManager
//Get issues in specified project
def project = projectManager.getProjectByCurrentKey("BUIS")
def issueIdsInProject = issueManager.getIssueIdsForProject(project.id)
//Traverse all issues in aforementioned project
issueIdsInProject.each{
def currentIssue = issueManager.getIssueObject(it)
//Check that issue is in status "Open"
if(currentIssue.status.name == "Open")
{
//Get the Deadline and Epic Link as well as their values for the current issue
def deadlineCF = cfm.getCustomFieldObjectByName("Deadline")
def epicLink = cfm.getCustomFieldObjectByName("Epic Link")
def deadlineValue = currentIssue.getCustomFieldValue(deadlineCF)
def epicLinkValue = currentIssue.getCustomFieldValue(epicLink)
//If the issue is linked to an epic and does not have a Deadline value
if(!(deadlineValue) && epicLinkValue)
{
//Set the issues Deadline value to it's epic's
def epicDeadline = epicLinkValue.getCustomFieldValue(deadlineCF)
currentIssue.setCustomFieldValue(epicDeadline)
}
}
}
Traverse Epics and get linked issues
import com.atlassian.jira.component.ComponentAccessor
//Get necessary managers
def projectManager = ComponentAccessor.projectManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def cfm = ComponentAccessor.customFieldManager
//Get issues in specified project
def project = projectManager.getProjectByCurrentKey("BUIS")
def issueIdsInProject = issueManager.getIssueIdsForProject(project.id)
//Traverse all issues in aforementioned project
issueIdsInProject.each{
def currentIssue = issueManager.getIssueObject(it)
//Check that issue is an Open Epic
if(currentIssue.issueType.name == "Epic" && currentIssue.status.name == "Open")
{
//Get all of the Epic's Epic-Story Links
issueLinkManager.getOutwardLinks(it).each{
if(it.issueLinkType.name == "Epic-Story Link")
{
//Get the linked mutable issue object and check that it is Open as well
def linkedIssue = issueManager.getIssueObject(it.destinationObject.id)
if(linkedIssue.status.name == "Open")
{
def deadlineCF = cfm.getCustomFieldObjectByName("Deadline")
//Check if the linked issue has a set Deadline
if(!(linkedIssue.getCustomFieldValue(deadlineCF)))
{
//If no set Deadline is found, set the linked issue's Deadline to that of the Epic's
def epicDeadlineValue = currentIssue.getCustomFieldValue(deadlineCF)
linkedIssue.setCustomFieldValue(epicDeadlineValue)
}
}
}
}
}
}
Let me know if everything I've included in this answer makes sense and if you need me help figuring anything out! And when running the scripts in the console, ignore any errors by the static type checker. :D
Aidan
Hi, Aidan.
I have question(upload image in next message)
Whiсh class i need to add in import in first script?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey again Andrey!
I believe you can ignore the errors that you are getting in the below screenshot. Those are errors thrown by the static type checker, as it is unable to discern the returned type of the epicLinkValue variable.
Try running the script regardless of the errors and see if it still works for you.
Aidan :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you, Aidan, its working.. But only if issues in project(BUIS), what to do if in differents(epics in BUIS and issues in others )?
Please, give me new consult, how to do conditions correct - If issue not containt component "Поддержка" and not have other components.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
No problem!
If you want to execute the script on a different project, all you need to do is change this line of code to contain a different project's key:
def project = projectManager.getProjectByCurrentKey("BUIS")
As far as your other request, where are you wanting to put those conditions? What is the condition meant to do? Are you saying to only copy the Deadline field from the Epic if the issue contains on that component? (I'm just asking for context)
Aidan :D
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi, Aidan
I got new extra conditions for thise script, from busines. :(
All conditions:
1. Epics in one project(BUIS), issues in others projects.
2. Add component "Сопровождение", if in issue not writed component "Поддержка".
3. "Due Date" field from Epic will be copied to all issues in the Epic , if it have "null"
4."Заказчик" field from Epic will be copied to all issues in the Epic, if it have "null"
5. "Deadline" field from Epic will be copied to all issues in the Epic, if it have "null"
Can help?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey again Andrey!
With all of those conditions you may have better luck using the first script that I provided you. If you use the first script, the first condition that you've listed will be irrelevant because all of the issues will be accessed via the Epic's links (so you won't need to specify the issue's projects).
Conditions 2-4 are basically the same as 5, which I added in my first reply. So to add those conditions, you'll follow the same process.
I'll go head and make some changes to the script to reflect conditions 2-4. However, it's difficult for me to test these scripts on my own instance because of how specific they are, so I cannot be sure that they will work the first time around. So let me know if you get any errors. Read through the code to make sure everything looks how you expect or how you'd like it to:
import com.atlassian.jira.component.ComponentAccessor
//Get necessary managers
def projectManager = ComponentAccessor.projectManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def cfm = ComponentAccessor.customFieldManager
def pcm = ComponentAccessor.projectComponentManager
//Get issues in specified project
def project = projectManager.getProjectByCurrentKey("BUIS")
def issueIdsInProject = issueManager.getIssueIdsForProject(project.id)
//Traverse all issues in aforementioned project
issueIdsInProject.each{
def currentIssue = issueManager.getIssueObject(it)
//Check that issue is an Open Epic
if(currentIssue.issueType.name == "Epic" && currentIssue.status.name == "Open")
{
//Get all of the Epic's Epic-Story Links
issueLinkManager.getOutwardLinks(it).each{
if(it.issueLinkType.name == "Epic-Story Link")
{
//Get the linked mutable issue object and check that it is Open as well
def linkedIssue = issueManager.getIssueObject(it.destinationObject.id)
def projectComponents = pcm.findAllForProject(linkedIssue.projectId)
if(linkedIssue.status.name == "Open")
{
def componentsOfIssue = linkedIssue.components
def componentNames = componentsOfIssue.collect{it.name}
if(!("Поддержка" in componentNames))
{
def componentToAdd = componentsOfIssue.find{it.name == "Сопровождение"}
componentsOfIssue << componentToAdd
linkedIssue.setComponent(componentsOfIssue)
}
def deadlineCF = cfm.getCustomFieldObjectByName("Deadline")
//Check if the linked issue has a set Deadline
if(!(linkedIssue.getCustomFieldValue(deadlineCF)))
{
//If no set Deadline is found, set the linked issue's Deadline to that of the Epic's
def epicDeadlineValue = currentIssue.getCustomFieldValue(deadlineCF)
if(epicDeadlineValue)
{
linkedIssue.setCustomFieldValue(deadlineCF, epicDeadlineValue)
}
}
//If there is no due date on the linked issue, set it from the Epic's
if(!(linkedIssue.dueDate))
{
if(currentIssue.dueDate)
{
linkedIssue.setDueDate(currentIssue.dueDate)
}
}
//Check if Заказчик CF is present on the linked issue and set from the Epic's if it is not
def customField = cfm.getCustomFieldObjectByName("Заказчик")
if(!(linkedIssue.getCustomFieldValue(customField)))
{
def customFieldValue = currentIssue.getCustomFieldValue(customField)
if(customFieldValue)
{
linkedIssue.setCustomFieldValue(customField, customFieldValue)
}
}
}
}
}
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Adian, script working without errors.
But issues in other projects(not BUIS) not changing. (
DueDate, Заказчик(user) still empty.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey again,
Could you give me a bit more detail on how all of these issues are connect/linked? Are all of the issues that you are wanting to change in epics? And if so, what are the ways in which they are linked?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
For example - epic from AFT, issues from CC. I started script before
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.
AH yes! Ok sooooooo the script that I provided you with will ONLY access epics that are in the specified project and all of the issues attached to those epics. Were you wanting to execute this script on a set of projects or all of them?
If you'd like to operate on a set of projects, you only need to add a couple of lines of code. You need to wrap everything after the managers in an "each" loop that loops over a list of project keys:
import com.atlassian.jira.component.ComponentAccessor
//Get necessary managers
def projectManager = ComponentAccessor.projectManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def cfm = ComponentAccessor.customFieldManager
def pcm = ComponentAccessor.projectComponentManager
def projectKeys = ["BUIS","Other project key","Other project key","Other project key"] //SET THE PROJECT KEYS HERE
projectKeys.each{
//Get issues in specified project
def project = projectManager.getProjectByCurrentKey(it)
def issueIdsInProject = issueManager.getIssueIdsForProject(project.id)
//Traverse all issues in aforementioned project
issueIdsInProject.each{
def currentIssue = issueManager.getIssueObject(it)
//Check that issue is an Open Epic
if(currentIssue.issueType.name == "Epic" && currentIssue.status.name == "Open")
{
//Get all of the Epic's Epic-Story Links
issueLinkManager.getOutwardLinks(it).each{
if(it.issueLinkType.name == "Epic-Story Link")
{
//Get the linked mutable issue object and check that it is Open as well
def linkedIssue = issueManager.getIssueObject(it.destinationObject.id)
def projectComponents = pcm.findAllForProject(linkedIssue.projectId)
if(linkedIssue.status.name == "Open")
{
def componentsOfIssue = linkedIssue.components
def componentNames = componentsOfIssue.collect{it.name}
if(!("Поддержка" in componentNames))
{
def componentToAdd = componentsOfIssue.find{it.name == "Сопровождение"}
componentsOfIssue << componentToAdd
linkedIssue.setComponent(componentsOfIssue)
}
def deadlineCF = cfm.getCustomFieldObjectByName("Deadline")
//Check if the linked issue has a set Deadline
if(!(linkedIssue.getCustomFieldValue(deadlineCF)))
{
//If no set Deadline is found, set the linked issue's Deadline to that of the Epic's
def epicDeadlineValue = currentIssue.getCustomFieldValue(deadlineCF)
if(epicDeadlineValue)
{
linkedIssue.setCustomFieldValue(deadlineCF, epicDeadlineValue)
}
}
//If there is no due date on the linked issue, set it from the Epic's
if(!(linkedIssue.dueDate))
{
if(currentIssue.dueDate)
{
linkedIssue.setDueDate(currentIssue.dueDate)
}
}
//Check if Заказчик CF is present on the linked issue and set from the Epic's if it is not
def customField = cfm.getCustomFieldObjectByName("Заказчик")
if(!(linkedIssue.getCustomFieldValue(customField)))
{
def customFieldValue = currentIssue.getCustomFieldValue(customField)
if(customFieldValue)
{
linkedIssue.setCustomFieldValue(customField, customFieldValue)
}
}
}
}
}
}
}
}
If instead you'd like to run over ALL project, you would only need to change one line. Instead of initializing the projectKeys variable to be a list of keys, you would just get all of the project keys via the ProjectManager:
def projectKeys = projectManager.getProjects().collect{it.key}
Try whichever one of those out that you feel is appropriate and let me know if that does it for you! :)
Aidan (Thanks for being so patient with me)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi, Aidan.
When i choose all projects - get timeout error.
When i choose projects, it still not working ..
We have one project(BUIS) with analitics issues and epics, from thises epics we add issues in programmers project(CC). And i dont to change issues in CC, wich not have parent epics in BUIS
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.