Skip to main content

3 min read

Jira Genius: Ensuring Epics are only closed when Stories are complete

Phill Fox
Phill Fox
18 August 16 Adaptavist
Jira Genius: Ensuring Epics are only closed when Stories are complete
alert2 Icon
The content of this blog is no longer updated

Jira Genius: Ensuring epics are only closed when Stories are complete

If you’'re following an agile methodology for your Jira project, it is likely that you will have many Stories linked to a single Epic. Sometimes an Epic is closed by accident before all of the associated Stories are complete.

You can prevent this problem from occurring by training your team and sending them continual reminders not to close Epics until all Stories are complete. Although there has to be a better way of ensuring your team follows this best practice.

Use transitions to manage Epic closure

 As the 'Epic' follows a workflow (as do all Issue Types), you can identify the transition or transitions that are used to 'Close an Epic.' If you apply a condition on those 'Close' transitions, you can stop the transition being available while there are open Stories.

By restricting the availability of the 'Close Epic' transition, you can ensure visibility of progress on all your Epics with linked Stories.

Control transitions with ScriptRunner for Jira

Restricting the availability of your 'Close Epic' transition requires Adaptavist ScriptRunner for Jira and works with any version of Jira, although typically it is used with Jira Software. By using a scripted condition in ScriptRunner for Jira you can check if all your linked Stories are complete before allowing the transition to 'Done' to be shown to the end user.

Place the following script as a condition on transition(s) to 'Done' for your workflows that are being used by Epics and you will no longer experience Epics closing before all your Stories are complete.

import com.atlassian.jira.component.ComponentAccessor
// Allow logging for debug and tracking purposes
import org.apache.log4j.Level
import org.apache.log4j.Logger
// Script code for easy log identification
String scriptCode = "Check all stories closed -"
// Setup the log and leave a message to show what we're doing
Logger logger = log
logger.setLevel( Level.ERROR )
logger.debug( "$scriptCode Triggered by $issue.key" )
passesCondition = true
if ( == 'Epic')
     IssueLinkManager issueLinkManager = ComponentAccessor.issueLinkManager
     def found = issueLinkManager.getOutwardLinks(
       it?.destinationObject?.getStatus().getName() != 'Done' &&
           it?.destinationObject?.getIssueType().getName() == 'Story'
       logger.debug( "$scriptCode Found =  $found " )
       if (found) {
           logger.debug( "$scriptCode return false" )
           passesCondition = false
       } else {
           logger.debug( "$scriptCode return true" )
	   passesCondition = true
// Always allow all other issue types to execute this transition
       logger.debug( "$scriptCode Not Epic return true" )
       passesCondition = true

The script provided has debug statements present but this line restricts the logging to only report at ERROR level.

    logger.setLevel( Level.ERROR )

If you wish to review the logs consider changing the line to:

    logger.setLevel( Level.ALL )

Want to take things further?

Adaptavist ScriptRunner for Jira gives you the ability to extend, automate and integrate Jira. Use it to further enhance your transition management for Epics and their associated Stories:

  • The automatic transition of an Epic to 'In Progress' when the first Story enters 'In Progress.'
  • Automatic closure of the Epic when the last Story is complete
  • Automatic reopening of the Epic if a Story is reopened

For more information about ScriptRunner for Jira and to start a free trial, visit the Atlassian Marketplace.

copy_text Icon