You can now vote for scripts to help people know if they're useful or not. Login or create an account to vote!


Close an Epic when all the Issues Under that Epic are Closed


Transition an epic to Closed using a post function on the Closed workflow step which fires when all child issues are closed.


I work in a software project using epics to organise the tasks. I want to close an epic when all tasks are complete, so I do not have to do this manually. I can use this script as a post function to close an epic when the last child issue has been completed.

Good to Know

  • By changing the issueLinkName, the script can be used to transition the source issue in linked relationships different from epics.
  • The Close action must have the transition screen associated with it in order to set the resolution.
  • By default, this script will have the resolution Done but it can be configured.


  • Jira Software Jira Software (7.7 - 8.6)
  • ScriptRunner for Jira ScriptRunner for Jira (5.6.14)
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.workflow.TransitionOptions // the name of the action you want to move the issue to final actionName = 'Close' //Name of the resolution children issues should have final resolutionName = 'Done' // the name of the issue link final issueLinkName = 'Epic-Story Link' def workflow = ComponentAccessor.workflowManager.getWorkflow(issue) def actionId = workflow.allActions.findByName(actionName)?.id def linkManager = ComponentAccessor.issueLinkManager def epicIssue = linkManager.getInwardLinks( { == issueLinkName }?.sourceObject if (!epicIssue) { return } // Find all the linked - with the "Epic-Story Link" link - issues that their status is not the same as resolutionName def linkedIssues = linkManager .getOutwardLinks( .findAll { == issueLinkName } *.destinationObject?.findAll { it.resolution?.name != resolutionName } // If there are still open linked issues (except the one in transition) - then do nothing if (linkedIssues - issue) { return } def issueService = ComponentAccessor.issueService def inputParameters = issueService.newIssueInputParameters() inputParameters.setComment('This Epic closed automatically because all the issues in this Epic are closed.') inputParameters.setSkipScreenCheck(true) def transitionOptions = new TransitionOptions.Builder() .skipConditions() .skipPermissions() .skipValidators() .build() def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser def transitionValidationResult = issueService.validateTransition(loggedInUser,, actionId, inputParameters, transitionOptions) assert transitionValidationResult.valid: transitionValidationResult.errorCollection def result = issueService.transition(loggedInUser, transitionValidationResult) assert result.valid: result.errorCollection
Discovered an issue? Report it here

Suggested for you