Info | ||
---|---|---|
| ||
Questions about usageIf you have a question on the best way to use this plugin, please ask it on Atlassian Answers. Too see the questions (and hopefully answers) other people ask on this plugin, click here. Bugs reportsTo report an issue, please create a Bug Report in our issue tracker. To browse the list of known bugs, go to our issue tracker. Feature requestsTo suggest a new feature, please create a Feature Request in our issue tracker. To suggest an improvement to an existing feature, please create an Improvement Request in our issue tracker. To browse the list of feature and improvement requests, go to our issue tracker. |
You can also restore the previous Assignee by saving it in a custom field during the Request clarification transition and then restoring it during the Provide info transition (see Copy Value From Other Field workflow function in JIRA Suite Utilities). Alternatively, you can use the Assign to last role member function described below to assign the issue to the last user in the Users role.
2- Separation of Duties Condition (new in 1.1)
A workflow condition that enforces separation of duties (for SAS-70 compliance), i.e. that makes sure the same user cannot trigger two incompatible transitions on the same issue.
For example, you can prevent a user who has triggered the "Resolve Issue" transition on an issue to trigger the "Close" issue.
Info | ||
---|---|---|
| ||
Because JIRA does not keep track of actual transitions (or workflow actions) but only of changes in the Status of an issue, it is impossible to distinguish between two transitions that share the same source and destination Statuses. |
3 - Hide Transition "Condition" (new in 2.2)
The purpose of the Hide Transition workflow condition is to hide a transition from the user, thus preventing the user from triggering it, while making it available to the Transition Parent Issue function or to scripts or remote API calls.
...
1 - Field has been modified Validator (new in 1.3)
A validator that forces users to modify a field during a transition.
2 - Comment Required Validator
A validator than forces users to enter a comment during a transition. If they don't, a customized error message will be displayed.
Note that this validator is disabled if the transition is being made through SOAP because the progressWorkflowAction method does not let you specify a comment.
3 - Field has single value Validator
A workflow validator that checks that a multi-valued field does not contain more than one value during a transition. This can be useful, for example, to make sure users don't select more than one "Fix version" during the Resolve transition.
Option "Excluding values copied from sub-tasks" is a bit more complex. During the single-valuation test, it will make the validator ignore values that are associated with the issue's sub-tasks, if any. For example, if the issue has one sub-task, and this sub-task's Fix version(s) is "1.0", then a Fix version(s)'s value of "1.0, 2.0" will be acceptable during the issue's transition (because "1.0" will be ignored).
4 - Previous Status Validator
A validator that does basically the same thing as the Previous Status Condition above.
5 - Parent Status Validator
A workflow validator that ensures that the current issue's parent issue is in one of the specified Statuses. This is useful only for sub-tasks.
...
Post-functions
Note | ||
---|---|---|
| ||
If you insert a Post-function (except "Set Issue Security From User's Project Role Function" and "Copy Value From Field to Field Function") in the Create transition, you must make sure that you move it down to after the Creates the issue originally built-in function. |
1 - Assign to role member (new in 1.2)
A worfklow function that assigns the current issue to the default member of the specified project role.
Since JIRA does not support the notion of a default member for project roles, the Assign to role member function identifies the default member of a project role by going through all the members of the project role looking for a User Property with the following two characteristics:
- Property key: defaultAssignee
- Property value: contains a comma-separated list of entries in the form ProjectKey -> *RoleName. *For example:
Code Block |
---|
TST -> Developers, JMWE -> Testers |
For backward compatibility, the following two forms are also supported:
- Property Key: {ProjectName}x{RoleName} (for example: CoolProjectxQAMembers)
- Property value: "default" (without the quotes)
Or: (since 1.5.3)
- Property Key: defaultAssignee{n} (where n is a number from 1 up, for example: defaultAssignee1)
- Property value: {ProjectName}x{RoleName} (for example: CoolProjectxQAMembers)
If no such member is found, the first member of the project role is used instead.
This can be used for scenarios like: "when a developer resolves the issue, assign the issue to the QA lead".
The Skip if Assignee option allows you to prevent the automatic assignation to the role member if the user specifies an explicit Assignee in the workflow screen.
2 - Assign to last role member (new in 1.2) (updated in 1.5.1 & 2.4.1)
A worfklow function that assigns the current issue to the latest Assignee (excluding the current one) who is a member of the specified project role.
When the function is executed it goes backwards through the change history of the issue. When it finds a user that belongs to the specified role, it assigns the issue to that user. Optionally, it can consider the Reporter and/or the Current Assignee in addition to previous assignees.
This can be used for scenarios like: "when QA fails assign the issue to the last developer who worked on it".
The Skip if Assignee option allows you to prevent the automatic assignation to the last role member if the user specifies an explicit Assignee in the workflow screen.
3 - Increase value of field Function
A workflow function that increases the value of a numerical field by one.
4 - Set field value from User Property value Function
A workflow function that sets a field to the value of a User Property.
A typical use is to store the country, or department, or other such information, of the Reporter of an issue into the issue itself (so that it can be displayed, searched, or used by the workflow).
When setting the Issue Security field, the user property must contain the numerical id of the Issue Security Level, which you can find by looking at the links associated with the Add/Default/Delete operations on the desired Security Level (on the Edit Issue Security Levels screen).
5 - Copy Field Value to Parent Function (new in 1.3.2)
A worfklow function that copies the value(s) of a field into the same field of the issue's parent issue.
6 - Set Field Value From Parent Function (new in 2.4)
A worfklow function that sets a field value to the value(s) of the same field of the issue's parent issue.
7 - Copy Value From Field to Field Function (new in 2.3)
A workflow function that copies the value(s) of a field to another field of the same issue. It can optionally take the source value as it was before the transition (useful in case the user modified the source field during the transition screen). Since 2.4, it can also optionally merge multi-valued field values instead of replacing them.
8 - Add Field Value to Parent Function
A worfklow function that adds the value(s) of a multi-valued field (such as Fix version(s)) into the same field of the issue's parent issue.
9 - Set Issue Security From User's Project Role Function (new in 1.5)
A worfklow function that sets the issue security level based on the Project Role to which the current user belongs. This function can be used on the Create transition to set a different issue security level depending on whether the issue is being created by an internal user or by an external user (e.g. a customer).
Note |
---|
To use this workflow function in the "Create Issue" transition, you must place it before the "Creates the issue originally" step. |
10 - Transition Parent Issue (new in 2.1)
A workflow function that triggers a named transition on the parent issue of the current sub-task.
Note that the transition can specified by name, so that the transition can be found regardless of the parent issue's actual workflow, or by ID if disambiguation is required (since 2.4).
Also note that the parent transition should not be associated with a transition screen (which would not be displayed), especially if it includes required fields.
Maintenance and new features
If you encounter a problem with this plugin, or if you would like to suggest enhancements or even new workflow extensions, please submit an issue into this plugin's JIRA project. I will look into it as soon as possible.
Table of Contentschildren | ||||
---|---|---|---|---|
|
Installation
Versions < 2.0
Install the plugin by copying the JAR to WEB-INF/lib inside your JIRA web application and restart JIRA.
Version 2.0 and above
Starting with version 2.0, the plugin is a "type TWO" plugin, which means that the plugin can be installed by copying it to jira-home/plugins/installed-plugins or, better yet, from the excellent Atlassian Universal Plugin Manager.
Note | ||
---|---|---|
| ||
If you are upgrading from version 1.x to version 2.0 or above, you must make sure that you delete jira-misc-workflow-extension-1.x.jar from atlassian-jira/WEB-INF/lib before installing the new version in jira-data/plugins/installed-plugins. Also note that the Universal Plugin Manager will not offer to upgrade from version 1.x automatically. |
Description/Features
Excerpt |
---|
This plugin provides a set of workflow extensions (conditions, validators and post-functions) that you can use to customize your JIRA workflows. |
...
1 - Previous Status Condition
A workflow condition that allows you to disable a particular transition (hiding it from the list of Available Workflow Actions) if the current Issue either:
- has never been in the specified Status
- or was not in the specified Status just before it entered the current Status (if "Most recent status only" is checked)
...
title | Why on Earth would I need something like this? |
---|
A typical use for this workflow condition is when you can reach a certain Status from several other Statuses (through the same Transition) and want to be able to return to the originating Status.
Consider the following partial workflow :
JIRA will allow you to create a single Transition from both Open and In Progress statuses to the Waiting for clarification status. But how do you create the transition (Provide info) back to Open and In Progress? And, more importantly, how do you make sure the issue is transitioned back to the originating status?
Here's the trick:
- create two Provide info transitions, one from Waiting for clarification to Open, and another from Waiting for clarification to In Progress (just add a space at the end of the name of one of the two transitions so that JIRA doesn't complain about duplicate transition names).
- on the first transition, add a Previous Status Condition to make the transition available only if the previous status was Open (don't forget to check the "Most recent status only" checkbox).
- on the second transition, add a Previous Status Condition to make the transition available only if the previous status was In Progress (don't forget to check the "Most recent status only" checkbox).
And voilà! Your users will see only one transition from the Waiting for clarification status, and it will transition the ticket back to the originating status.
Note that you could also use an advanced feature of JIRA that allows you to define conditional "<result>" elements in the XML definition of a transition, but you need to edit the workflow XML and this is definitely not for the faint of heart. Below is an example XML snippet extracted from a workflow XML (only the transition XML is shown):
...
<action id="801" name="Provide Information" view="fieldscreen">
<meta name="jira.description">Provide the requested information</meta>
<meta name="jira.fieldscreen.id">10010</meta>
<validators>
<!-- Force the user to provide a comment -->
<validator name="" type="class">
<arg name="errorMessage">You must provide your answer in the Comment field.</arg>
<arg name="class.name">com.innovalog.jmwe.plugins.validators.CommentRequiredValidator</arg>
<arg name="hidGroupsList"></arg>
</validator>
</validators>
<results>
<!-- Conditional results (transitions) first -->
<!-- First possible destination step: 1 ("Backlog") -->
<result old-status="Not Done" status="Done" step="1">
<conditions>
<!-- Transition will only be available when coming from the "Backlog" status -->
<condition type="class">
<arg name="jira.previousstatus">Backlog</arg>
<arg name="class.name">com.innovalog.jmwe.plugins.conditions.PreviousStatusCondition</arg>
<arg name="jira.mostRecentStatusOnly">yes</arg>
</condition>
</conditions>
<post-functions>
<!-- restore former assignee field from custom field "Previous Assignee" -->
<function type="class">
<arg name="sourceField">customfield_10090</arg>
<arg name="destinationField">assignee</arg>
<arg name="class.name">com.googlecode.jsu.workflow.function.CopyValueFromOtherFieldPostFunction</arg>
</function>
<!-- standard Jira functions follow -->
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.UpdateIssueStatusFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.misc.CreateCommentFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.GenerateChangeHistoryFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.IssueReindexFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.event.FireIssueEventFunction</arg>
<arg name="eventTypeId">10008</arg>
</function>
</post-functions>
</result>
<!-- Second possible destination step: 1 ("In Progress") -->
<result old-status="Not Done" status="Done" step="3">
<conditions>
<condition type="class">
<arg name="jira.previousstatus">In Progress</arg>
<arg name="class.name">com.innovalog.jmwe.plugins.conditions.PreviousStatusCondition</arg>
<arg name="jira.mostRecentStatusOnly">yes</arg>
</condition>
</conditions>
<post-functions>
<function type="class">
<arg name="sourceField">customfield_10090</arg>
<arg name="destinationField">assignee</arg>
<arg name="class.name">com.googlecode.jsu.workflow.function.CopyValueFromOtherFieldPostFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.UpdateIssueStatusFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.misc.CreateCommentFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.GenerateChangeHistoryFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.IssueReindexFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.event.FireIssueEventFunction</arg>
<arg name="eventTypeId">10008</arg>
</function>
</post-functions>
</result>
<!-- Last possible destination step: 7 ("Resolved") -->
<unconditional-result old-status="Not Done" status="Done" step="7">
<!-- no condition - will be executed if no conditional result above matched -->
<post-functions>
<function type="class">
<arg name="sourceField">customfield_10090</arg>
<arg name="destinationField">assignee</arg>
<arg name="class.name">com.googlecode.jsu.workflow.function.CopyValueFromOtherFieldPostFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.UpdateIssueStatusFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.misc.CreateCommentFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.GenerateChangeHistoryFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.issue.IssueReindexFunction</arg>
</function>
<function type="class">
<arg name="class.name">com.atlassian.jira.workflow.function.event.FireIssueEventFunction</arg>
<arg name="eventTypeId">10008</arg>
</function>
</post-functions>
</unconditional-result>
</results>
</action>
|