Skip to end of metadata
Go to start of metadata

Overview

JIRA 3 provides the ability to create fully customized workflows - giving the user full control over the life cycle of a JIRA issue. This powerful feature allows the workflow designer to specify:

  • the available actions at each step
  • the users/groups who can execute a workflow transition
  • functions that are executed on completion of a workflow transition

This tutorial focuses on the Condition and Post Function elements of a workflow - with an example of creating a custom condition and post function, and how they are integrated with JIRA through the plugin system.

The JIRA documentation contains further detailed information on workflows.

Also, the following documents expand on working with the JIRA plugin system:

Plugin Structure

In order to make a custom workflow element (e.g condition, post-function) available within JIRA, it is necessary to create a workflow plugin module. As with all plugin modules, the workflow plugin will consist of the following components:

  • Java classes encapsulating workflow element logic
  • Resource templates for display of the workflow element
  • Plugin descriptor to enable the workflow module in JIRA

all contained within a single JAR file.

Each element is further discussed in the examples below.

Jira Plugin Development Kit

The full source for each example is available in the JIRA Plugin Development Kit.

Using the JIRA Plugin Development Kit, it is possible to navigate to the workflow example directory and build the workflow example JAR file with the command:

maven jar

The resulting JAR file contains all the workflow examples discussed here. The workflow example plugin becomes available once the JAR file is copied to the JIRA lib directory.

Workflow Conditions

A Condition restricts the execution of a workflow transition until certain criteria are met. If the Condition fails, the transition link will not be available on the 'View Issue' page.

This section of the tutorial focuses on the Condition element and provides an example custom Condition which can be plugged into JIRA.

JIRA 3 System Conditions

JIRA 3 provides a number of system conditions available on setup - DisallowIfInStepCondition, AllowOnlyAssignee, IssueAssignedCondition, etc - each allowing the user to define when a worklfow transition becomes available.

The SubTaskBlockingCondition (another system condition) determines if a transition is available for an issue based on the status of its associated sub-tasks. The user specifies a list of statuses that will permit the transition to be available.

For example, the 'Close Issue' workflow transition link for an issue can be conditioned to be only available if all related sub-tasks are associated with the 'Closed' status. In effect, this transition link is not available for the parent issue until all sub-tasks are closed.

Custom Workflow Conditions

For developers designing a custom workflow condition, we recommend that the custom condition class extend the JIRA AbstractJiraCondition class. In order to avoid multiple database calls to retrieve the original issue object for the condition check, there are two possibilities available to the condition designer. Firstly, the custom condition class can overwrite the following method:

The logic within this method should retrieve the original issue object as required.

Alternatively, if the getIssue method is not overwriten, it is possible to pass the original issue object to the transientVars map, for example:

In this instance, the fields object will be passed to the getIssue method as the transientVars map.

This ensures that the original issue is examined during the condition check and minimal database calls are made.

Example - Parent Issue Blocking Condition

This example provides the reverse condition of the SubTaskBlockingFunction - in that it determines if a transition is available for a sub-task based on the status of its associated parent issue.

In this example, the condition has been configured to display the workflow transition 'Reopen' for a sub-task, only if the parent issue is associated with an unresolved status (e.g. 'Open', 'In Progress' , Unresolved').

The condition is applied to the 'Reopen' transition in a copy of the default JIRA workflow associated with the 'Sub-Task' issue type.

In effect, the condition will prevent the transition for any sub-task from the 'Closed' to the 'Reopened' status, if the parent issue is not associated with an unresolved status.

Condition Logic

The condition logic is contained in the class ParentIssueBlockingCondition class that implements the interface Condition.

The only method requiring implementation is the passesCondition(...) method. Within this example, this method retrieves the parent issue and then determines if its associated status is contained in the user specified list of statuses. The condition passes if the specified list of statuses contains the status associated with the parent issue.

The list of statuses is specified when adding the workflow condition to a transition.

The class WorkflowParentIssueBlockingConditionFactoryImpl is also included - this class manages passing the required parameters to the resource templates.

Condition Resources

The workflow condition requires a number of resources in order to display the input, edit and view screens.

In this example, a velocity template is provided for each screen:

  • templates/issueblockingcondition/issueblockingcondition-input-params.vm
  • templates/issueblockingcondition/issueblockingcondition-edit-params.vm
  • templates/issueblockingcondition/issueblockingcondition-view.vm

allowing the user to initially specify the statuses which will result in a 'pass', to edit these statuses and also a screen displaying the selected statuses.

Plugin Descriptor

As with all plugins, the workflow condition must be defined in a file named atlassian-plugin.xml and be located in the root of the JAR file.

The definition of the ParentIssueBlockingCondition condition is as follows:

The workflow condition entry specifies the key, name and the Workflow Condition Factory for this condition. The factory class provides methods for passing input, edit and view parameters to the view templates. The condition description is also specified.

The class containing the condition logic, ParentIssueBlockingCondition, is specified next in the <condition-class> tag.

Finally, the location of the resource templates are specified - with an individual template for input, edit and view screens.

Parent Issue Blocking Condition - In Action

Once the workflow example JAR file has been placed in the JIRA lib directory, the Parent Issue Blocking Condition is now available as a condition within the workflow editor.

Workflow Post Functions

A Post Function executes specifed actions immediately after a transition is executed (hence the name post-function). Example possible actions include updating issue fields, generating change history, adding a comment, generating an event that signals that an issue has been progressed through workflow, etc.

This section of the tutorial focuses on the Post Function element and provides an example Post Function which can be plugged into JIRA.

JIRA 3 System Post Functions

JIRA 3 provides a number of system post functions available on setup - UpdateIssueStatusFunction, CreateCommentFunction, etc - each allowing the user to specify that certain actions should be executed following a specific workflow transition.

Note: Certain JIRA system post functions cannot be edited, deleted or ordered, as they must be executed during every transition. These post functions are essential for JIRA's issue life cycle, and would compromise other functionality if not executed.

Example - Close Parent Issue Post Function

This example post function will close the parent issue once the final sub-task is closed (all other associated sub-tasks are already closed).

The post function will ensure that the parent issue is still open and that all other associated sub-tasks are also closed before attempting to close the parent issue.

The post function can be applied to the 'Close Issue' transition in a copy of the default JIRA workflow associcated with the 'Sub-Task' issue type.

Post Function Logic

The post function logic is contained in the class CloseParentIssueFunction class that implements the interface FunctionProvider.

The execute method retrieves the sub-task from the parameters. From this, the parent issue is determined and a check is made as to whether the parent issue is closed or not.

If the parent issue is not closed, the statuses of the rest of the associated sub-tasks are also checked. If all sub-tasks are closed, the parent issue can be closed.

This function does not require any input or configuration - the action to be executed is defined within the post function logic.

The only user input required is to associate the post function with a particular transition within a workflow.

Post Function Resources

This post function only requires a view template as there is no configuration or editing required.

The velocity template is provided for the view screen:

  • templates/closeparentfunction/closeparentissue-function-view.vm

Plugin Descriptor

As with all plugins, the post function condition must be defined in a file named atlassian-plugin.xml and be located in the root of the JAR file.

The definition of the CloseParentIssueFunction condition is as follows:

Here, the WorkflowNoInputPluginFactory class must implement WorkflowPluginFunctionFactory.

The post function entry specifies the key, name and the Post Function Factory for this condition. The factory class provides methods for passing parameters to the view templates - in this case, no parameter passing is required. The post function description is also specified.

The class containing the post function logic, CloseParentIssueFunction, is specified next in the <function-class> tag.

It is also possible to configure the post function as it appears in the workflow editor. The following options can be specified:

  • orderable - specifies if this post function can be re-ordered within the list of post functions associated with a transition. The postion within the list determines when the post function actually executes.
  • unique - specifies if this post function is unique or not - i.e. if it is possible to add multiple instances of this post function on a single transition.
  • deleteable - specifies if the post funtion can be removed from a transition.
  • default - specifies if this post function is automatically associated with any new transitions created.

It is also possible to specify a weight configuration parameter - however this is mainly intended for JIRA system post function elements. This parameter is used in conjunction with the default parameter - if the post function is to be added to all new transitions, the weight parameter is used to determine the post function position within the post function list.

Finally, the location of the resource view template is specified.

Close Parent Issue Post Function - In Action

Once the workflow example JAR file has been placed in the JIRA lib directory, the Close Parent Issue Post Function is now available as a post function within the workflow editor.

  • No labels

13 Comments

  1. I noticed that the offsite linked workflow tutorial lists the Maven style artifact repository at http://repository.atlassian.com but this no longer seems to have any files. Any update on where this has moved to?

  2. This does contain jars:

    http://repository.atlassian.com/p6spy/jars/

    Its just that we do not show directory listings for the top level directories.

  3. There is a small problem in the ParentIssueBlockingCondition.java. It can't reopen the parent any more.

    So you need to change

            issue = ComponentManager.getInstance().getIssueManager().getIssue(subTask.getParentId());
            if (issue == null)
            {             return true;//In JIRA3.5.1, it is "return false;"         }

    1. Hi Bernie,
      I am not sure I get what you are saying here. If the issue is null then this means that we can not find the parent issue and we should always return false. This condition should never happen as the subtasks parent should always exist. I am not understanding what you are saying?
      Thanks,
      Dylan

    2. Anonymous

      Hi, Bernie,

      where can I get a look at the source code (java) of this plugin?

  4. There are updated instructions on How to Build an Atlassian Plugin here:
    http://confluence.atlassian.com/display/DEVNET/How+to+Build+an+Atlassian+Plugin

    The API JavaDocs for OpenSymphony Workflow are needed:
    http://www.opensymphony.com/osworkflow/api/index.html

    And the JIRA API JavaDocs: http://docs.atlassian.com/software/jira/docs/api/

    For Conditions, you have

    extends com.atlassian.jira.workflow.condition.AbstractJiraCondition
    implements com.opensymphony.workflow.Condition
    public boolean passesCondition(Map transientVars, Map args, PropertySet ps)

    For Validators, you have

    implements com.opensymphony.workflow.Validator
    public boolean validate(Map transientVars, Map args, PropertySet ps)

  5. I tried the example and set the same condition. When both the subtask and parent issue are closed, the parent issue does not get the "Reopen Issue" operation.

    Edit: Saw Bernie Gu's suggestion. Will try that.

    Update: Did not work.

    Any suggestions?

  6. Hi together

    i work on a post function to run jelly script. The jelly script can be entred in the parameters-view. The Problem is now, when the jelly script contains references with "$" an (com.opensymphony.module.propertyset.PropertyImplementationException: Property not found) occurrs when i invoke this post function. The tricky thing is that, when i remove this reference in the jelly script (realy only the reference), it works well.

    suggestions?

  7. Hello again

    Okay i resolve the problem. It seems so, that the descriptor not only overgive the condition-parameters. He is also an interpreter. My solution is to replace the all "$" for the transaction between the factory and function classes. Now the jellyscript works well...i saw my "Hello World" (smile)

    Maybe helps this anyone.

    Best regards

  8. Michel, I'd be very interested in the ability to run a jelly script during a workflow transition.  Can you provide more info on how this is done?  Thanks so much!

  9. All

    The examples are a bit outdated

    i used the Parent status blocking condition

    and found out there is a nice little workflowMode in the code , which also counted as a status (only messed up the view)

    simply change the getSelectedStatusIds function , adding :

  10. Are these instructions still valid for 4.0?  If not, are there updated versions or where can this information be found?

    1. At the top:

      This documentation relates to JIRA 4.1.x