Transition issue when all linked issues are resolved

What is the best method for automatically transitioning an issue when all linked issues are closed? Example: Our support team has their own JIRA instance. When a issue in the support project requires development, they open another issue in the appropriate development project and link it to the original support issue. They would like to then push their support issue into a "waiting for dev" state, and have it automatically pop into a "dev complete" state when the developers close the development issue.

I've seen similar requests for sub-tasks, but since a sub-task has to be in the same project as the parent task, this won't work for us. Any recommendations for scripts/plugins/methodologies that would address our needs would be greatly appreciated!

Thanks,

Jason

3 answers

1 accepted

Accepted Answer
0 votes

Hi Jason, the Script Runner plugin has this option called:

Allows the transition if this query matches a JQL query

But this works when it's in the same JIRA instance, than know if it would work between two instances.

And there's listener you can create: Fast-track transition an issue

OK - I've looked at the script runner. If I understand the way this works, then I'd want a post function script to fire on the CLOSE transition for a development issue. That script should:

1. Get a list (list1) of all linked issues where:

a) link type = "Blocks"

b) linked issue is in the Support project

c) linked issue is in state "Awaiting Development".

2. For each Blocked issue in list1:

a. Get a list (list2) of all issue links of type "Blocked By" (minus originating issue)

b. If all issues in list2 are closed, transition the Blocked issue to the "Dev Complete" state

Does the logic sound right? Or am I missing something obvious? I am trying to handle the case where a support issue may be blocked by multiple dev issues, as well as the case where a single dev issue might block multiple support issues...

Thanks,

Jason

I followed Ramiro's advice and installed the script runner plugin. I cobbled together a Groovy script from various examples that did what I wanted. This is my first ever Groovy script, so it may have significant problems I just haven't seen yet. If you see any places to clean it up, please let me know.

//Post-function script for transitioning a linked issue in another project when this issue is closed
//Jason Plumhoff
//May 2, 2013
import org.apache.log4j.Category
import com.atlassian.jira.ComponentManager 
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.project.Project
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.TransitionValidationResult
import com.atlassian.crowd.embedded.api.User

def Category log = Category.getInstance("com.onresolve.jira.groovy.TransitionToDevComplete")

User currentUserObj = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

issueManager = ComponentAccessor.getIssueManager()
linkMgr = ComponentAccessor.getIssueLinkManager()
projectMgr = ComponentAccessor.getProjectManager()
issueIndexMgr = ComponentAccessor.getIssueIndexManager()
log.debug ("Current issue ID: " + issue.id)
log.debug ("Looking for Links...")

//Iterate through the dev issue's links
for (IssueLink link in linkMgr.getOutwardLinks(issue.id)) {
    def issueLinkTypeName = link.issueLinkType.name
    def linkedIssue = link.getDestinationObject()
    def linkProjectName = linkedIssue.getProjectObject().getName()
    def linkedIssueKey = linkedIssue.getKey()
    def linkedIssueID = linkedIssue.getId()
    def linkedIssueStatus = linkedIssue.getStatusObject().getName()
 
    //look for a link that blocks an In Dev Tech Support issue
    if (issueLinkTypeName == "Blocks" && linkProjectName == "Technical Support" && linkedIssueStatus == "In Development") {
        log.debug ("issue "+ issue.getKey() + " blocks " + linkProjectName + " issue " + linkedIssueKey)
        def allClosed = true
 
        //go to tech support issue and see if it has other open blockers
        for (IssueLink parentIssueLink in linkMgr.getInwardLinks(linkedIssueID)) {
            def parentIssue = parentIssueLink.getSourceObject()
            def parentIssueKey = parentIssue.getKey()
            def parentIssueID = parentIssue.getId()
            def parentIssueLinkType = parentIssueLink.issueLinkType.name
            def parentIssueStatusName = parentIssue.getStatusObject().name
            log.debug ("parentIssueLinkType = " + parentIssueLinkType)
            if (issue.getKey() != parentIssueKey  && parentIssueLinkType == "Blocks") {
                if (parentIssueStatusName == "Closed") {
                    log.debug ("Issue " + parentIssueKey + " is closed")
                } else {
                    log.debug ("Issue " + parentIssueKey + " is still open")
                    allClosed = false
                }
            }
        }
        log.debug ("All issues closed? " + allClosed)
        
        //if no other blockers remain open, try to transition the issue
        if (allClosed) {
            def actionID = 201 //CHANGE THIS TO THE APPROPRIATE VALUE FOR YOUR TRANSITION
            log.debug ("Transition issue " + linkedIssueKey)
            issueService = ComponentAccessor.getIssueService()
            issueInputParameters = issueService.newIssueInputParameters()
            TransitionValidationResult validationResult = issueService.validateTransition(currentUserObj, linkedIssue.getId(), actionID, issueInputParameters)
            if (validationResult.isValid()) {
            // Transition linked issue to status = "Closed"
                issueService.transition(currentUserObj, validationResult)
                log.debug ("Transitioned")
                // Re-index issue
                issueIndexMgr.reIndex(validationResult.getIssue())
                log.debug ("Reindexed")
            } else {
                Collection<String> errors = validationResult.getErrorCollection().getErrorMessages()
                for (errmsg in errors) {
                    log.debug ("[ERROR] - Error message:" + errmsg)
                }
            }
        }
    }
}

This works like charm. Thanks !

Hy guys, is this solution valid for JIRA 6? I'm getting no errors, but the issue remains in the same state...

We have the same problem on our Jira 6 instance.

I was missing this line:

issueInputParameters.setSkipScreenCheck(true);

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted Sep 18, 2018 in Jira

What modern development practices are at the heart of how your team delivers software?

Hey Community mates! Claire here from the Software Product Marketing team. We all know software development changes rapidly, and it's often tough to keep up. But from our research, we've found the h...

22,091 views 2 7
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you