Anyone can help to give me a scriptrunner script?

I want to set validation condition like

: if liked issue type id is 10609, and link type id is 11100 → true

: if liked issue type id is not 10609, and link type id is 11100 → false

: if liked issue type id is 10609, and link type id is not 11100 → true

: if liked issue type id is not 10609, and link type id is not 11100 → true

In sum, several types of issues may be connected with several connection types. if there is a issue type 10609, validation rule has to check whether the link type is 11100 or not.

If even one condition is false, the result value must be false.
For example, when issue type = 10609 & link type = 11100, issue type = 10610 & link type = 11100, issue type = 10609 & link type = 11111, and issue type = 10610 & link type = 11111, validation should be false.

when issue type = 10609 & link type = 11100 and issue type = 10609 & link type = 11111, validation should be true.

I posted this to the https://community.atlassian.com but nobody answered.

I tried like below, but it doesn’t work properly.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.context.IssueContext
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.issue.link.IssueLink
import utils.*

def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())

def linkId = “11100” //TEST link

if(links != null) {
for(link in links) {
if(link.getLinkTypeId() == Integer.parseInt(linkId)) { // TEST link
def linkedIssue = link.getDestinationObject()
if(linkedIssue.issueTypeId == “10609”){ // Release issuetype
return true
}
}
else {
if(link.getLinkTypeId() == Integer.parseInt(linkId)) { // TEST link
def linkedIssue = link.getDestinationObject()
if(linkedIssue.issueTypeId != “10609”){ // Release issuetype
return false
}
} else {
if(link.getLinkTypeId() != Integer.parseInt(linkId)) { // TEST link
def linkedIssue = link.getDestinationObject()
if(linkedIssue.issueTypeId == “10609”){ // Release issuetype
return true
}
} else {
if(link.getLinkTypeId() != Integer.parseInt(linkId)) { // TEST link
def linkedIssue = link.getDestinationObject()
if(linkedIssue.issueTypeId != “10609”){ // Release issuetype
return true
}
}
}
}
}
}
} else {
return true
}

Please help me.

something like that:

def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId());

if (links == null) {
    return true;
}

def linkId = 11100; // TEST link
def releaseIssueTypeId = "10609"; // Realease IssueType 
def isCondition = true;

for (link in links) {
    def isTestLink = link.getLinkTypeId() == linkId;
    def linkedIssue = link.getDestinationObject();
    def isReleaseIssue = linkedIssue.issueTypeId == releaseIssueTypeId; 

    isCondition &= !(!isTestLink && isReleaseIssue);

    if (!isCondition) {
        break;
    }
}

return isCondition;

Thankyo so much. It works.

@mikhail.gorev If I add one more linkid as or condition, how can I change? I tried …
def linkId in [11100, 11111]
def linkId = 11100 || 11111
However it dosen’t work.

Don’t have scriptrunner to check, but something like this:

def linkId = [11100, 11111];
...
def isTestLink = linkId.contains(link.getLinkTypeId());

?

Thank you for your help.

I used this script, and use this to another case.

I’m going to use it the other way. I want to… when linkid is 10309 or 10703 and issuetype is 10511, it should be break.

I add validation like below, but workflow is transitioned.

import com.atlassian.jira.component.ComponentAccessor

def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId());

if (links == null) {
return true;
}

def linkId = [10309, 10703]; // Contains link
def changeIssueTypeId = “10511”; // Change IssueType
def isCondition = true;

for (link in links) {
def isContainLink = linkId.contains(link.getLinkTypeId());
def linkedIssue = link.getDestinationObject();
def isChangeIssue = linkedIssue.issueTypeId == changeIssueTypeId;

isCondition &= !(isContainLink && isChangeIssue);  // <- changed **!isContainLink** to **isContainLink**

if (!isCondition) {
    break;
}

}

return isCondition;

How should I chage script?

To be honest, I don’t fully understand what you are trying to do.
But…
As soon as isCondition is getting false, the for loop breaks and you return isCondition - which is false. So whenever you break the loop you return false and if loop is not broken you return true. So just return the false inside the loop and get rid of the isCondition variable.

import com.atlassian.jira.component.ComponentAccessor
def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId());
if (links == null) {
  return true;
}

def linkId = [10309, 10703]; // Contains link
def changeIssueTypeId = “10511”; // Change IssueType

for (link in links) {
  def isContainLink = linkId.contains(link.getLinkTypeId());
  def linkedIssue = link.getDestinationObject();
  def isChangeIssue = linkedIssue.issueTypeId == changeIssueTypeId;

  if (isContainLink && isChangeIssue) {
    return false;
  }
}
return true;

Hope it helps, if not - modify as needed.

1 Like

Thanks, but failed. Script looks fine, but I don’t know why workflow is transitted although linkid is 10309 or 10703 and issuetype is 10511.

linkid 10309, and 10703 are hierarchy link type. We have a rule that we should make issue types Epic > Story > Change > Task. However some people makes Change > Change, so I want to stop making like that. To do this, I add a validation Change workflow.

When I applied your first script, it is suceessed.
def linkId = 10309; // Contains 링크유형
def changeIssueTypeId = “10511”; // Change IssueType
def isCondition = true;

for (link in links) {
def isContainLink = link.getLinkTypeId() != linkId;
def linkedIssue = link.getDestinationObject();
def isChangeIssue = linkedIssue.issueTypeId == changeIssueTypeId;

isCondition &= !(!isContainLink && isChangeIssue);

However, Contains linkid are two as 10309, 10703. So I tried …
def linkId = [10309, 10703]; // Contains link

def isTestLink = linkId.contains(link.getLinkTypeId());

However workflow was transitted linkid is 10309 or 10703 and issuetype is 10511.
I want to make condition to false when linkid 10309 or 10703 & issuetype is 10511.

Can you help me one more time?

Again I’m not sure I get it, but since you wrote:

I want to make condition to false when linkid 10309 or 10703 & issuetype is 10511.

then maybe just negate the result of contains function as below:

def isTestLink = !linkId.contains(link.getLinkTypeId());

when I use below script, it works proferly.
linkid 10309 & issuetype 10511 → break

def linkId = 10309; // Contains 링크유형
def changeIssueTypeId = “10511”; // Change IssueType
def isCondition = true;

for (link in links) {
def isContainLink = link.getLinkTypeId() != linkId;
def linkedIssue = link.getDestinationObject();
def isChangeIssue = linkedIssue.issueTypeId == changeIssueTypeId;

isCondition &= !(!isContainLink && isChangeIssue);

if (!isCondition) {
    break;
}

However when i tried like below, it dosen’t work properly.
linkid 10309 & issuetype 10511 → passed, not break
linkid 10703 & issuetype 10511 → passed, not break

def linkId = [10309, 10703]; // Contains link
def changeIssueTypeId = “10511”; // Change IssueType
def isCondition = true;

for (link in links) {
def isContainLink = !linkId.contains(link.getLinkTypeId());
def linkedIssue = link.getDestinationObject();
def isChangeIssue = linkedIssue.issueTypeId == changeIssueTypeId;

isCondition &= !(!isContainLink && isChangeIssue);

if (!isCondition) {
    break;
}

Hmmm, should be doing the same.
Perhaps .contains function behaves differently than I expect.
I don’t have script runner to test it.
Can’t you add some logging to see what’s going on? Debug it other way?
Looks like linkId are numbers and changeIssueTypeId is a string. Chould they have the same type? Problem in this area?

Btw. please pay attention to formatting posts properly/better. It’s not making easier to understand the problem with current formatting.

1 Like

I resolved problem like below. Thanks you for your help.

def isContainLink1 = link.getLinkTypeId() != linkId1;
def isContainLink2 = link.getLinkTypeId() != linkId2;
def linkedIssue = link.getDestinationObject();
def isChangeIssue = linkedIssue.issueTypeId == changeIssueTypeId; 

isCondition1 &= !(!isContainLink1 && isChangeIssue);
isCondition2 &= !(!isContainLink2 && isChangeIssue);

   if (!isCondition1) {
    break;
    } else {
       if (!isCondition2) {
       break;
   }