Using the Workflow Enhancer
Validators and Conditions
To enter a validator or a condition provided by Workflow Enhancer for Jira, edit your workflow and in any transition add a new "Universal Validator" or "Universal Condition". You will be prompted with entering a boolean expression as explained below. In case of the universal validator, you will be prompted to enter a message as well.
Post Functions
You have the possibility of executing any post function depending on whether a boolean expression (see the rest of this documentation) evaluates to true or false, respectively. When adding a "Universal Post Function", you will not only be prompted for a boolean expression, but also for another post function to be executed for any values the post function might take.
Note that some of the provided post functions in Jira have unintuitive functionality:
Create a comment: If comment was added in the transition screen, it will be added again.
Update Issue Status: Will update the issue status after transition, although it was already changed.
Create Issue: Recreates the issue, e.g., previously there is an issue "TEST-4 - A task", but after the post function transition executes it becomes "TEST-5 - A task"
In the future we might decide to hide these post functions.
If you add a post function to the create transition, it must happen before the “Creates the issue originally.”
Fields
Name | Type | Explanation | Example | Annotation |
---|---|---|---|---|
Reporter, Assignee | String | User field containing a username, e.g., {Reporter} represents the username of the issue's Reporter field. | {Reporter} = "admin" | Anonymous is represented by "" |
Environment, Description, Summary | String | Text field, e.g., {Summary} contains the text entered in the issue's Summary field. | {Summary} = "Summary" | |
Due Date, Created, Updated | Date | Date field, e.g., {Due Date} contains the date entered in the issue's Due Date field. | {Due Date} = 24.12.2012 | |
Original Estimate, Remaining Estimate, Time Spent | Timespan | Timespan field, e.g., {Original Estimate} contains the timespan entered in the issue's Original Estimate field. | {Original Estimate} = 4w 5d 6h | If nothing is entered in the field, Workflow Enhancer for Jira returns 0min (i.e., {...} = 0min) |
Σ Original Estimate, Σ Remaining Estimate, Σ Time Spent | Timespan | Time span field, e.g., {Σ Original Estimate} contains the sum of the Original Estimates of the issue's subtasks. | {Σ Original Estimate} = 1w 4d 3h | if nothing is entered in the field, Workflow Enhancer for Jira returns 0min (i.e., {...} = 0min) |
Project | String | {Project} contains the issue's Project name. | {Project} = "Rocket" | |
Priority | String | {Priority} contains the text of the issue’s Priority field. | {Priority} = "Major" | |
Status | String | {Status} = "In Progress" | ||
Resolution | String | {Resolution} = "Resolved" | ||
Issue Type | String | {Issue Type} = "Bug" | ||
Key | String | {Key} contains the issue’s key. | {Key} = "ROCKET-1" | |
Issue Links | String | {Linked Issues} <=> "Passive: LinkType % IssueKey $ ... $ LinkType % IssueKey Aktive: LinkType % IssueKey $ ...$ LinkType % IssueKey" |
| Jira’s default link types are Blocks, Cloners and Duplicate. Note the space before “Aktive“ and the spelling of “Aktive“. Set the log level to DEBUG and check in the logs as this syntax is not really easy to handle. |
Labels | String | Returns the array of labels as String in alphabetical order; e.g., [label1, label2, label3] |
| Use regular expressions to check for one label among several. |
Fix Version/s, Affects Version/s | String | Returns the array of versions as String in alphabetical order; e.g., [version1, version2, version3] |
| Use regular expressions to check for one version among several. |
Components | String | Returns the Array of components as String in alphabetical order; e.g., [component1, component2, component3] |
| Use regular expressions to check for one component among several. |
Transition Comment | String | Returns the comment added in the transition as a String. | Only useful for post functions and validators if a screen is shown during the transition. |
Jira fields (written as `{field_id}`) may themselves contain a special value. Therefore if a field contains a value such as `1h 30min`, it will automatically be parsed as a timespan. This also allows for a chain of field identifiers (by putting the identifier of another field in a field). An application might be that the first element of the chain is set as a post-function to dynamically change the behavior of the condition/validator depending on the steps in the workflow we have visited.
To make the field value non-evaluating (i.e not evaluating chained field identifiers within the field), use double brackets (e.g. {{description}}
)
Please compare Jira fields always with English field values, e.g., {Resolution} = "Resolved".
Fields of type String only allow String comparisons. So, especially the order operations <, <=, >=, and > often do not make sense, e.g., in the case of priority {Priority} > "A String which begins with the letter a" always evaluates to "True".
You can use both, field names in your local language as well as english lower-case names, e.g., in German {resolution} and {Lösung} both refer to the resolution while {Resolution} tries to evaluate a custom field.
Custom Fields
Use field id to include custom fields in an expression: {customfield_123}
While using custom field names directly works for expression evaluation, it does not work for cloud migration.
Type | Explanation | Annotation |
---|---|---|
Date Picker | {Date Picker} represents the picked date as a date value. | e.g., |
Version Picker | {Single Version Picker} represents all picked versions of the issue as a comma and space separated String. | |
Single Version Picker | {Version Picker} represents the picked version as a String. | |
Project Picker | {Project Picker} represents the picked project name as a String. | |
User Picker | {User Picker} represents the picked username as a String. | |
Multi User Picker | {Multi User Picker} represents all picked usernames in a comma and space separated String. | e.g., |
Group Picker | {Group Picker} represents the picked group name as a String. | |
Multi Group Picker | {Multi Group Picker} represents all picked group names in a comma and space separated String. | e.g., |
Number Field | {Number Field} represents the entered number as a Float value. | e.g., |
Free Text Field | {Free Text Field} represents the entered text as a String. | e.g., |
Text Field | cf. Free Text Field | |
Label | {Labels} represents all labels, which are set for this issue, as a String. | e.g., |
Date Time | {Date Time} represents the picked point in time as a Date value. | e.g., |
URL Field | {URL Field} represents the entered URL as a String. | e.g., |
Import Id | NOT SUPPORTED | |
Read only Text Field | NOT SUPPORTED | |
Cascading Select | {Cascading Select} represents the selected options as a String in the same format as Atlassian's
| e.g., |
Bug Import ID | NOT SUPPORTED | |
Multi Select | {Multi Select} represents the selected options as a comma and space separated String. | |
Radio Buttons | {Radio Button Field} represents the selected option as a String. | |
(Multi) Checkbox | {Checkbox} represents the selected options as a comma and space separated String. | |
Select List | {Select List} represents the selected option as a String. | |
Hidden Job Switch | NOT SUPPORTED |
Boolean evaluations (equations and comparisons) are logged. If you are not sure, to which value Workflow Enhancer for Jira evaluates your custom field, just do the following:
Administration → Logging & Profiling
Configure a new logger:
com.tng.jira.workflowenhancer.evaluator.types.AbstractGenericValue
Set the logging level to DEBUG (or below).
Now, you can see every evaluation and its result in the logs.
Note that Workflow Enhancer for Jira can change the left and right side of the equation/comparison.
Macros
Macro | Type | Description | Example |
---|---|---|---|
[user] | String | The username of the current user. | |
[groups] | String | A comma-separated list of the groups the user belongs to. | |
[roles] | String | A comma-separated list of the project roles the user belongs to. |
|
[now] | Date | The current date and time. | |
[subtasks#field] | String | A comma-separated list of the values in the subtasks. |
|
Values
String
Example | |
---|---|
any String has to be enclosed by " (quotation marks) |
|
Regular Expression
Example | |
---|---|
any regular expression has to be enclosed by / (forward slashes) |
|
* matches the preceding element zero or more times |
|
+ matches the preceding element one or more times |
|
? matches the preceding element zero or one time |
|
( ) defines subexpression |
|
{n} matches the precending element exactly n times |
|
{min, max} matches the preceding element at least min and at most max times |
|
In the examples above ε always stands for the empty word. For example, in the case of /a?/
there can be either one "a" or no "a".
Field interpolation in Regular Expression
For your field to be evaluated in regex, you must use the {field_id} notation, as expressions of the type {field_name} will not be evaluated. For custom fields, this will be of the form {customfield_123}, for system fields, it is generally the name in lowercase with spaces and special characters removed, as per the table below. Note that, when inserting a field using the UI, it will show the {field_name} by default, and this must be converted to {field_id}.
Example | |
---|---|
A field in a regular expression is replaced by its value (as string) |
|
The value of the field is evaluated |
|
Use double curry brackets ( |
|
Custom fields are supported |
|
Use |
|
Use |
|
Both left and right curry braces need to be escaped. Regex like /\{abc}/
will not work.
System Field Name in English | Field ID |
---|---|
Description | description |
Summary | summary |
Issue Type | issuetype |
Priority | priority |
Resolution | resolution |
Version/s | versions |
Fix Version/s | fixVersions |
Component/s | components |
Labels | labels |
Environment | environment |
Linked Issues | issuelinks |
Attachment | attachment |
Assignee | assignee |
Reporter | reporter |
Due Date | duedate |
Time Tracking | timetracking |
Security Level | security |
Date
Example | |
---|---|
Date pattern: dd.mm.yyyy hh:mm |
|
Time is optional |
|
The maximum date value is 31.12.2099 23:59
.
Timespan
Example | |
---|---|
Labor Timespan pattern: n1w n2d n3h n4min , where n1, n2, n3, n4 are non negative integers |
|
Real Timespan pattern: n1W n2D n3H n4MIN , where n1, n2, n3, n4 are non negative integers |
|
If a component is 0, it can be omitted |
|
It is not possible to change the order | Wrong: Right: 8 |
Workflow Enhancer for Jira works with the time tracker of your Jira such that a timespan of Jira is automatically a labor timespan. This also means that a date and timespan field cannot be added.
If the time tracker is disabled, we have 1 day = 8 hours and 1 week = 5 days.
So, if your Jira time tracker settings are 1 labour day = 24 hours and 1 labor week = 7 labor days, labor timespan and real timespans are the same.
Float
Example | |
---|---|
Pattern: d+(.d*)? or d*(.d+)? where d is an integer |
|
The Workflow Enhancer for Jira float data type works with negative values, but the parser does not support unary operations.
Operators
Boolean Operators
Description | Operator |
---|---|
AND | & (alternatively && or AND) |
OR | | (alternatively || or OR) |
NOT | ! |
Parentheses | ( ) |
Order Operators
Description | Operator |
---|---|
Equal | = (alternatively ==) |
Not equal | != |
Greater | > |
Greater or equal | >= |
Less | < |
Less or equal | <= |
Arithmetic Operators
Description | Operator |
---|---|
Plus | + |
Minus | - |
Order Operations
The following matrix shows which values allow order operations and how they are defined.
String | Float | Date | Real Timespan | Labor Timespan | Regular Expression | |
---|---|---|---|---|---|---|
String | s | default | default | default | default | r |
Float | default | f | default | default | default | default |
Date | default | default | d | default | default | default |
Real Timespan | default | default | default | t | t | default |
Labor Timespan | default | default | default | t | t | default |
Regular Expression | r | default | default | default | default | default |
Order operations are possible if the field at the crossing point is not empty. The type of the operation is explained in the legend.
Type | Explanation | Example |
s | Lexicographical comparison based on the Unicode value of each character in the Strings. |
|
f | Standard comparison of numbers. |
|
d | The time is considered if and only if both values match the pattern dd.mm.yyyy hh:mm. |
|
t | Number comparison of the timespan values converted to minutes. |
|
r | Equal if and only if the String matches the regular expression. |
|
default | Lexicographical comparison after both values have been converted to String. |
|
Arithmetic Operations
Addition
The following matrix shows between which values additions are possible and how they are defined.
String | Float | Date | Real Timespan | Labor Timespan | Regular Expression | |
---|---|---|---|---|---|---|
String | s | |||||
Float | f | |||||
Date | d | |||||
Real Timespan | d | t | t | |||
Labor Timespan | t | t | ||||
Regular Expression |
Additions are possible if the field at the crossing point is not empty.
Type | Explanation | Example |
s | String concatenation. |
|
f | Standard addition of numbers. |
|
t | Standard addition of timespan values based on minutes. If the timespan values do not have the same type (i.e., not both real or both labor), the result has the type of the first operand. |
|
d | The timespan value is added to the date. If the date has no entered time, hours and minutes do not matter. |
|
Subtraction
The following matrix shows between which values subtractions are possible and how they are defined.
String | Float | Date | Real Timespan | Labour Timespan | Regular Expression | |
---|---|---|---|---|---|---|
String | ||||||
Float | f | |||||
Date | d | |||||
Real Timespan | d | t | t | |||
Labor Timespan | t | t | ||||
Regular Expression |
Subtractions are possible if the field at the crossing point is not empty.
Type | Explanation | Example |
f | Standard subtraction of numbers. |
|
t | The subtraction of two timespans returns the absolute difference based on minutes. If the the timespan values do not have the same type (i.e., not both real or both labor), the result has the type of the first operand. |
|
d | The timespan value is subtracted from the date. If the date has no entered time, hours and minutes do not matter. |
|
The subtraction of Date values is not supported. Use, e.g., {Date A} < {Date B} + 1W
instead of comparing the difference of the dates to a week.