How to use cyle?

Andrey Ozerov October 3, 2017

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.

2 answers

1 vote
Aidan Derossett _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 3, 2017

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

Andrey Ozerov October 4, 2017

 Hi, Aidan.

I have question(upload image in next message)

Whiсh class i need to add in import in first script?

Aidan Derossett _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 4, 2017

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 :)

Andrey Ozerov October 5, 2017

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.

Aidan Derossett _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 6, 2017

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

Andrey Ozerov October 8, 2017

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?

Aidan Derossett _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 10, 2017

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)
}
}
}
}
}
}
}
Andrey Ozerov October 11, 2017

Adian, script working without errors.

But issues in other projects(not BUIS) not changing. (

DueDate, Заказчик(user) still empty.

Aidan Derossett _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 11, 2017

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?

Andrey Ozerov October 11, 2017

For example - epic from AFT, issues from CC. I started script before

Снимок2.PNGСнимок1.PNGСнимок.PNG

Andrey Ozerov October 11, 2017

ResultСнимок4.PNG

Aidan Derossett _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 12, 2017

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) 

Andrey Ozerov October 16, 2017

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

 

0 votes
Andrey Ozerov October 4, 2017

Снимок.PNG

Andrey Ozerov October 5, 2017

Thank you for help. It working correct.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events