Transition based on linked issues status

My requirement:

I have an story in Project P1 and two linked task L1 and L2 (blocks story) in different project P2

I want my story to change its state automatically based on tis linked issue state For e.g. Change state of epic to Done only when all the linked issues are set to In Done

 

I tried using the post function for Project P2 for transition state: In progress  (21) and Done (31)

Post function created was  "Transition 21 will be triggered on all issues linked to the current issue through the blocks link type." without any conditon

Post function created was  "Transition 31 will be triggered on all issues linked to the current issue through the blocks link type." without any conditon

 

But the outcome is not what I expect . Status of epic changes if I alter one of the linked issues and keeps on changing each time I update any of the linked issue

 

For e.g. i change the status of L1 to Done. In that case epic also gets set to Done (even though L1 is in Inprogress state)

 

Unfortunately I am not able to find solution to it after going through online articles and exploring the options within JIRA Agile

 

Can someone help me with it?

 

If adding condition to post function will solve this, can someone share groovy script to change the status for the example above then it would be great

3 answers

Any inputs on this?

 

@Nic Brough [Adaptavist] , @Jobin Kuruvilla, Jamie Echlin : Was going through the leaderboard and came across your name. Can you guys help me with this?

Tried out 

Using the script post function option in project P2 and selecting the Custom script post-function option, I included the below script to it (I have no hands on groovy script and came with this script after referring to multiple online article and modifying it) and moved this function after the fire event

Script:

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.TransitionToDone")

 

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

    if (issueLinkTypeName == "Blocks") {

        log.debug ("issue "+ issue.getKey() + " blocks ")

        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 = 31 //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 = "Done"

                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)

                }

            }

        }

    }

}

But this script don't seem to work out. Could you please correct me on it?


What log output do you have?

I have no clue where to check the log output. I am checking it on UI after changing the transition for all the linked issues to done

You need to find out before you have such an involved question.

I was under the impression that groovy script for the requirement would already be handy as this seems to be a common case If you think I need to get into the details of it, then surely will do. Thanks

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'MGoodar2(mgoodar2)' with class 'com.atlassian.jira.user.DelegatingApplicationUser' to class 'com.atlassian.crowd.embedded.api.User'
at Script2.run(Script2.groovy:13)

hello @qatest Did you figure out any answer? More or less I am looking for same functionality as this and I was wondering if you made any progress and help me..Thank you

Suggest an answer

Log in or Sign up to answer
How to earn badges on the Atlassian Community

How to earn badges on the Atlassian Community

Badges are a great way to show off community activity, whether you’re a newbie or a Champion.

Learn more
Community showcase
Published May 21, 2018 in Jira Software

How large do you think Jira Software can grow?

Hi Atlassian Community! My name is Shana, and I’m on the Jira Software team. One of the many reasons this Community exists is to connect you to others on similar product journeys or with comparabl...

1,243 views 10 18
Read article

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