How to map workflow Conditions based on linked issue resolution, issue type, and project?

Diana
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.
November 22, 2022

Using Scriptrunner, I want to use the workflow condition "Linked issues condition" to transition an issue based on the resolution of linked issues. The problem is that that built-in capability doesn't specific by issue type or by project.

For context, we have Feature issue types in project ABC, that uses link type "derivation". So a Feature can have an inward direction called "derivation is", and that's where all the child issues are under. But our Feature can have that same link type for different issue types and some to different projects.

We want so that if a Feature has derived issue types Story or Spike, within the same project as the Feature, and if those child issues are Done, then the Feature can be done. 

I'm trying to use Custom script condition. And this goes under the Feature workflow in project ABC.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink

def issueTypes = ["Story","Spike"]
def projectABC = ComponentAccessor.getProjectManager().getProjectObjByKey("ABC")
def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def parentLink = "derivation is"
def done = ["Done","OBE"]

for(IssueLink derivedLink in issueLinkManager.getOutwardLinks(issue.id)) {
   if (derivedLink.getIssueLinkType().getName() == parentLink) {
      def linkedIssue = derivedLink.getSourceObject()
      def linkType = linkedIssue.getIssueType().getName()

         if(linkedIssue.issueType.name == issueTypes && linkedIssue == projectABC && linkedIssue.getStatus().name != done) {

            passesCondition = false

      }

}

I tried switch Inward and Outward direction, and tried grouping conditions and still doesn't work. I test it by viewing this:

BEOFRE
Feature-123
   >parent link "derivation is"
      -Story << not done, so Feature cannot transition to done
      -Spike  << is done
      -Bug << different issue type, so ignore
      -Story << under different project, so ignore

AFTER
Feature-123
   >parent link "derivation is"
      -Story << now is done, so Feature can transition to done
      -Spike  << is done
      -Bug << different issue type, so ignore
      -Story << under different project, so ignore

2 answers

1 accepted

0 votes
Answer accepted
Tom Lister
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 24, 2022

Hi @Diana Gorv 

The clause

linkedIssue.issueType.name == issueTypes

is trying to compare a single string to an array of strings and this will always fail to match.

Try using

issueTypes.contains(linkedIssue.issueType.name) 

Similarly

linkedIssue == projectABC

seems to be comparing an issue to a project object. You will need to compare to the issues project. I don't have the exact syntax to hand. It will something linkedIssue.getProjectObject()

Diana
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.
November 28, 2022

Hi @Tom Lister so far I've been unlucky.

I've tried

if(issueTypes.contains(linkedIssue.issueType.name) && 
issueTypes.contains(linkedIssue.getProjectObject().key == projectABC) &&
linkedIssue.getStatus().name != done)

 and I've tried

if(linkedIssue.getComponents().contains(issueTypes) &&
linkedIssue.getComponents().contains(projectABC) &&
linkedIssue.status.name !=done)

But I still can't get it to work. Is it possible this kind of mapping requirements might be better in listeners? 

p.s. i meant to type this under "reply". the first comment i had typed accidentally under "suggest an answer"

Tom Lister
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 29, 2022

Hi @Diana Gorv 

in the first example

if(issueTypes.contains(linkedIssue.issueType.name) && 
issueTypes.contains(linkedIssue.getProjectObject().key == projectABC) &&
linkedIssue.getStatus().name != done)

will fail because you are asking if the issue types list contain the boolean result of linkedIssue.getProjectObject().key == projectABC

and

linkedIssue.getStatus().name != done

Would compare the name to an array of status names which will fail

In the second sample

if(linkedIssue.getComponents().contains(issueTypes) &&
linkedIssue.getComponents().contains(projectABC) &&
linkedIssue.status.name !=done)

you comparing the list of components to a project object. This fail.

This is difficult to debug by question and answer. I would definitely recommend adding log statements until you are sure of the output. This will confirm the values you are passing and whether the compares are correct e.g.

log.info("***IssueType: " + linked.issueType.name + " " + issueTypes.contains(linkedIssue.issueType.name)

I think the form you are trying to get to is

if (
issueTypes.contains(linkedIssue.issueType.name) &&
linkedIssue.getProjectObject().key == projectABC.key &&
done.contains(linkedIssue.getStatus().name)
)
Diana
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.
December 1, 2022

Hi @Tom Lister 

I think what I was aiming for was something similar to this https://community.atlassian.com/t5/Jira-questions/Validator-script-to-check-status-of-all-linked-issues-before/qaq-p/427966

For some reason the logging wouldn't show in Conditions so I tried on Validators to test the logging at the debug level. I've tried as suggested, using all my conditions under 1 IF statement, and I even tried multi IF statements. The debug logs would tell me the issue types are correct, and its under the right link name, so it possible I'm trying to put too many condition criteria.

I'll mark this as answered, or really obe, but I'll discuss with my team. I appreciate your help!

Tom Lister
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 1, 2022

Hi @Diana Gorv 

Thanks for the answer brownie point :-)

debugging scriptrunner is quite difficult. If you have access to the server log files you should be able to find the log output. I always put some tag at the front so I can find them 

log.info("***...

I have often changed to log4j.properties to redirect logs to a separate files. I can post some info on doing that.

A simpler way to test small pieces of script is in the console although you will not see the same inbuilt variables.

Try this as an example to play around with this case and get logging output. I've used logit.warn as I could see that was the logging level set on my server.

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import org.apache.log4j.Logger
import org.apache.log4j.Level

Logger logit = Logger.getRootLogger()

logit.warn logit.getLevel()

def issueManager = ComponentAccessor.issueManager
def issueKey = 'SCR-1'
def issue = issueManager.getIssueObject(issueKey)
assert issue: "Could not find issue with key $issueKey"

def issueTypes = ["Story","Spike"]
def projectABC = ComponentAccessor.getProjectManager().getProjectObjByKey("ABC")
def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def parentLink = "derivation is"
def done = ["Done","OBE"]

logit.warn("*** link: " + issueLinkManager.getOutwardLinks(issue.id))

for(IssueLink derivedLink in issueLinkManager.getOutwardLinks(issue.id)) {

if (derivedLink.getIssueLinkType().getName() == parentLink) {
def linkedIssue = derivedLink.getSourceObject()
def linkType = linkedIssue.getIssueType().getName()
if(linkedIssue.issueType.name == issueTypes && linkedIssue == projectABC && linkedIssue.getStatus().name != done) {
logit.warn false
}
}
}

Screenshot 2022-12-01 at 16.20.34.png 

0 votes
Diana
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.
November 28, 2022

 

I've tried

if(issueTypes.contains(linkedIssue.issueType.name) && 
issueTypes.contains(linkedIssue.getProjectObject().key == projectABC) &&
linkedIssue.getStatus().name != done)

 and I've tried

if(linkedIssue.getComponents().contains(issueTypes) &&
linkedIssue.getComponents().contains(projectABC) &&
linkedIssue.status.name !=done)

But I still can't get it to work. Is it possible this kind of mapping requirements might be better in listeners? 

Suggest an answer

Log in or Sign up to answer