Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Cascade issues to Done - Resolution is not set

Jeff Abbott September 30, 2020

I have Stores that link back to Requirement Issues. This is a many to many relationship. When I close a Story I iterate over the blocked requirements and then iterate over the blocking stories to each requirement. If the blocking stories are all Done, I want to transition those requirements to Done. 

I have written a workflow transition Post Function to do this. Everything works except the requirement resolution does not get set, even though the Status does.

Also, the TransitionValidationResult, issueService.transition, and issueService.update all return isValid()=true.  I assume I don't need the transition combed with the .update, so I'm likely doing something wrong that is obvious.

2 answers

1 accepted

0 votes
Answer accepted
caglad
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.
September 30, 2020

One other way to do this is to add a post function to your workflow transtion.

Jeff Abbott September 30, 2020

I believe that is what I have done.

caglad
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.
September 30, 2020

Go to workflow of the project and diagram view- click on the transition to the status. then under post functions make sure you add a rule for resolution set to donejira1.png

Like Jeff Abbott likes this
Jeff Abbott September 30, 2020

Well, that does work. Any idea why the script did not work?  

caglad
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.
September 30, 2020

That I dont know.. but one other bonus answer for you. If you already have done tickets without resolution set - simply create a new transition from done to done and you can transtion tickets to done from done which will update their resolution.

Like Jeff Abbott likes this
Jeff Abbott October 1, 2020

Yes, I already have that in place. Makes testing much easier.  

0 votes
Jeff Abbott September 30, 2020

Here is my code:

import com.atlassian.jira.component.ComponentAccessor

// Check link types:
final LINK_TYPE_NAME = "Blocks"
// Target issue type to transition:
final ISSUE_TYPE = "Story"
// Status of linked issue to enable transtion:
final LINKED_ISSUE_TYPE = "Requirement"
// Status of linked issue to enable transtion:
final LINKED_ISSUE_STATUS = "Done"
// Transition ID:
final TRANSITION_ID = 121

def issueManager = ComponentAccessor.getIssueManager();
def linkManager = ComponentAccessor.getIssueLinkManager();
def projectManager = ComponentAccessor.getProjectManager();
def issueService = ComponentAccessor.getIssueService();
def outwardLinks =linkManager.getOutwardLinks(issue.id);
def commentManager = ComponentAccessor.commentManager;
def constantsManager = ComponentAccessor.constantsManager;

//com.atlassian.jira.bc.issue.IssueService issueService = ComponentAccessor.getIssueService();

def worflowManager = ComponentAccessor.getWorkflowManager();

def user =issue.reporterUser;
def issueTypeName = issue.getIssueType().name;
def issueStatus = issue.getStatus().name;

commentManager.create(issue, user, "POST FUNCTION ON STORY: ${issue.key}",true)
commentManager.create(issue, user, "OUTWARD LINKS: ${outwardLinks.size()}",true)

// Iterate each requirement under the Story by checking ISSUE_LINK_TYPE and LINKED_ISSUE_TYPE

if (issue.getIssueType().name == ISSUE_TYPE){
outwardLinks.each{
def storyLink = it;
def linkedIssue = storyLink.destinationObject;
def linkedIssueKey = linkedIssue.key;
def linkedIssueType = linkedIssue.getIssueType().name;

//log.info("ITERATE ISSUE TYPE (Story): ${linkedIssueType}");
commentManager.create(issue, issue.reporterUser, "ITERATE STORY ISSUE LINK (Requirement): ${linkedIssueKey}",true)

// If this is a REQUIREMENT
if (linkedIssueType == LINKED_ISSUE_TYPE){
def issueLinkTypeName = storyLink.getIssueLinkType().name;
def linkedIssueID = linkedIssue.id;
def linkedIssueStatus = linkedIssue.getStatus();
def linkedIssueStatusName = linkedIssueStatus.name;

//log.info("ITERATE LINK TYPE NAME (blocks): ${issueLinkTypeName}");
commentManager.create(issue, user, "ITERATE LINK TYPE NAME (Blocks): ${issueLinkTypeName}",true)

// If REQUIREMNT is not Done, link type is Blocks
if (issueLinkTypeName == LINK_TYPE_NAME ) {
def allClosed = true;
def inwardLinks = linkManager.getInwardLinks(linkedIssueID);

commentManager.create(issue, user, "ITERATE INWARD LINKS OF REQ: ${inwardLinks.size()}",true)

inwardLinks.each{
def requirementLink = it;
def requirementLinkType = requirementLink.issueLinkType.name;

def storytIssue = requirementLink.getSourceObject();
def storyIssueKey = storytIssue.key;
def storyIssueID = storytIssue.id;
def storyIssueStatus = storytIssue.getStatus();
def storyIssueStatusName = storyIssueStatus.name;
commentManager.create(issue, user, "REQ to STORY LINK TYPE: ${requirementLinkType}",true)

if (issue.key != storyIssueKey) {
if (requirementLinkType==LINK_TYPE_NAME) {
if (storyIssueStatusName != LINKED_ISSUE_STATUS) {
allClosed=false;
commentManager.create(issue, user, "STORY Key: ${storyIssueKey}",true)
commentManager.create(issue, user, "STORY NOT Done: ${storyIssueKey}",true)
} else {
commentManager.create(issue, user, "Passed: LNKED STORY STATUS: ${storyIssueKey}",true)
}
} else {
commentManager.create(issue, user, "Passed: REQ TO STORY LINK TYPE: ${requirementLinkType} is not Blocking",true)
}
} else {
commentManager.create(issue, user, "Passed: LNKED STORY IS ISSUE IN PROGESS OF CLOSURE: ${storyIssueKey}",true)
}

if (allClosed) {
def actionId=TRANSITION_ID;
def workFlow = worflowManager.getWorkflow(linkedIssue);
def currentStep = workFlow.getLinkedStep(linkedIssueStatus);

List<com.opensymphony.workflow.loader.ActionDescriptor> actions = currentStep.getActions();

actions.each() {
if (it.getName().equalsIgnoreCase("Done")) {
actionId = it.getId();
}
}

def issueInputParameters = issueService.newIssueInputParameters()
commentManager.create(issue, user,"Settiing Resolution to 1000 ${issue.key}",true)
issueInputParameters.setResolutionId("10000")

com.atlassian.jira.bc.issue.IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(user, linkedIssueID, actionId, issueService.newIssueInputParameters());

if (transitionValidationResult.isValid()) {
commentManager.create(issue, user,"Transaction Validation Passed, Executing Transaction...${issue.key}",true);
def transcationResult = issueService.transition(user, transitionValidationResult);

if (transcationResult.isValid()){
commentManager.create(issue, user,"Passed: Transaction Completed Successfully ${issue.key}!",true);
issueInputParameters.setResolutionId("10000")
def updateValidationResult = issueService.validateUpdate(user, issue.id, issueInputParameters);
def updateResult = issueService.update(user, updateValidationResult);
} else {
commentManager.create(issue, user,"Failed: Transaction Did Not Complete ${issue.key}!",true);
}
} else {
log.warn("Count not transtion requirement ${linkedIssueKey}")
}
} else {
commentManager.create(issue, issue.reporterUser, "Failed: Not All Blocking Stories Done ${storyIssueKey}",true)
}
}
} else {
commentManager.create(issue, user, "Failed: REQ to STORY LINK TYPE: ${linkedIssueType}",true)
commentManager.create(issue, user, "Failed: REQ ISSUE STATUS: ${linkedIssueStatus}",true)
}
}
}
} else {
if (issueTypeName == LINKED_ISSUE_TYPE && issueStatus == LINKED_ISSUE_STATUS) {
if(issue.getResolutionId() == null){
commentManager.create(issue,user,"Resolution ID: ${issue.getResolutionId()}",true)

def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.setResolutionId("10000")
def updateValidationResult = issueService.validateUpdate(user, issue.id, issueInputParameters);

if (updateValidationResult.isValid()) {
commentManager.create(issue, user, "Passed - REQ RESOLUTION VALID: ${issue.key}",true)
def updateResult = issueService.update(user, updateValidationResult);

if (updateResult.isValid()){
commentManager.create(issue, user, "Passed - REQ RESOLUTION SUCCESSFUL: ${issue.key}",true)
} else {
commentManager.create(issue, user, "Failed - REQ RESOLUTION FAILED: ${issue.key}",true)
}
} else {
commentManager.create(issue, user, "Failed - REQ RESOLUTION INVALID: ${issue.key}",true)
}
}else{
commentManager.create(issue, user, "REQ RESOLUTION NOT NULL: ${issue.key}",true)
}
}
}

Suggest an answer

Log in or Sign up to answer