Structure

Here is a minimal example for listing structures from the Structure plugin. The comments in the script give more information about the important elements.

package examples.docs.structure import com.almworks.jira.structure.api.permissions.PermissionLevel import com.almworks.jira.structure.api.StructureComponents import com.onresolve.scriptrunner.runner.customisers.PluginModule import com.onresolve.scriptrunner.runner.customisers.WithPlugin // Grab only useful for IDE help, not for runtime. Alternatively you can just add this jar to the // "provided" scope for the module @Grab(group = 'com.almworks.jira.structure', module = 'structure-api', version = '16.0.0') // Specify that classes from this plugin should be available to this script @WithPlugin("com.almworks.jira.structure") // Inject plugin module @PluginModule StructureComponents structureComponents def structureManager = structureComponents.getStructureManager() def structures = structureManager.getAllStructures(PermissionLevel.VIEW) structures.each { structure -> log.debug "Structure: ID: ${structure.id}, name: ${structure.name}" }

Add Issue to Structure on Transition

Here is another example with Structure, a post-function which adds the current current issue to a named structure. You might want this done automatically when the issue has been triaged or CCB’d…​ you may not wish to consider it in your structure before this point.

package examples.docs.structure import com.almworks.jira.structure.api.StructureComponents import com.almworks.jira.structure.api.forest.ForestSpec import com.almworks.jira.structure.api.forest.action.ForestAction import com.almworks.jira.structure.api.item.CoreIdentities import com.almworks.jira.structure.api.permissions.PermissionLevel import com.atlassian.jira.issue.Issue import com.onresolve.scriptrunner.runner.customisers.PluginModule import com.onresolve.scriptrunner.runner.customisers.WithPlugin // Grab only necessary for IDE help, not for runtime @Grab(group = 'com.almworks.jira.structure', module = 'structure-api', version = '16.0.0') // Specify that classes from this plugin should be available to this script @WithPlugin("com.almworks.jira.structure") // Inject plugin module @PluginModule StructureComponents structureComponents //noinspection GroovyVariableNotAssigned def structureManager = structureComponents.getStructureManager() def forestService = structureComponents.getForestService() Issue issue = issue // provided in binding // should only have one structure for this name - otherwise use a structure ID def structures = structureManager.getStructuresByName("GRV", PermissionLevel.VIEW) if (structures) { def structureId = structures.first().id // this adds the issue at the root, to the top of the structure forestService.getForestSource(ForestSpec.structure(structureId)) .apply(new ForestAction.Add(CoreIdentities.issue(issue.id), 0, 0, 0)) }

All Descendants Must be Resolved Condition

Another example, a condition whereby all descendant issues in all structures containing this issue must be resolved. This is just for illustrative purposes and not necessarily a good idea, or production code.

package examples.docs.structure import com.almworks.jira.structure.api.forest.ForestSpec import com.almworks.jira.structure.api.StructureComponents import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.Issue import com.onresolve.scriptrunner.runner.customisers.PluginModule import com.onresolve.scriptrunner.runner.customisers.WithPlugin @WithPlugin("com.almworks.jira.structure") // Inject plugin module @PluginModule StructureComponents structureComponents def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() def issueManager = ComponentAccessor.getIssueManager() //noinspection GroovyVariableNotAssigned def structureManager = structureComponents.getStructureManager() def forestService = structureComponents.getForestService() Issue myIssue if (!binding.hasVariable("issue")) { log.warn "No issue in context, presume running in console" myIssue = issueManager.getIssueObject("GRV-90") } else { myIssue = issue } def query = structureComponents.getStructureQueryParser().parse("descendants of ${myIssue.key} and [resolution is empty]") def structures = structureManager.getViewableStructuresWithIssue(myIssue.id) passesCondition = structures.every { structure -> def forest = forestService.getForestSource(ForestSpec.skeleton(structure.id)) def childrenClosedForStructure = query.execute(forest.getLatest().getForest()).isEmpty() log.debug("All children closed for structure: ${structure.name}: $childrenClosedForStructure") childrenClosedForStructure } log.debug "passesCondition: $passesCondition" passesCondition

On this page