Set a Precondition on a Task
You can control when tasks run in your release flow by setting preconditions. This helps you create more flexible releases that adapt to different conditions and skip unnecessary tasks, saving time and preventing errors.
A precondition is an if
statement for tasks that determines whether a task should be executed. If the precondition evaluates to true, the task is started. If the precondition evaluates to false, the task is skipped. If an exception is raised or a compilation error occurs when Release is evaluating the precondition, the task fails. You can fix the precondition and retry the task.
Common use cases for preconditions include:
- Skip deployment tasks when the environment is already up to date
- Run different tasks based on the target environment (development, staging, production)
- Execute tasks only when specific conditions are met (like successful previous steps)
- Avoid running tasks when certain variables indicate they aren't needed
You can define task preconditions in two ways:
- Expression Language (recommended for most use cases)
- Jython Scripts (for advanced or legacy scenarios)
Select the precondition type from the Precondition type drop-down in the task configuration.
Expression Language Preconditions
Expression language preconditions provide a fast, secure, and simple way to write preconditions using single-line expressions. This is the recommended approach for most scenarios.
Expression language supports commonly available methods and properties for most precondition scenarios. If you're already familiar with Jython preconditions, you'll find that expression language works similarly—you can access all the same release, task, and phase properties, but with simpler, more direct syntax (no getter methods like getTitle()
or getDescription()
).
Expression language does not support multi-line expressions; your condition must be a single line.
Set Up Preconditions Using Expression Language
- Open the task conditions panel.
- Select Enable precondition.
- From the Precondition type drop-down, select Expression language.
- In the EL Precondition Expression field, enter your expression.
Expression Language Syntax and Property Access
Expression language provides a standardized way to access properties and evaluate expressions. The syntax is designed to be simple and intuitive, supporting common programming constructs and data access patterns.
The key advantage is direct property access without needing getter methods. Instead of release.getTitle()
or task.getDescription()
, you can directly access properties like task.release.title
or task.description
. All release and phase properties are accessed through the task object (for example, task.release.id
or task.phase.title
).
What You Can Access
You can access all the standard release, task, and phase properties through expression language:
- Release variables:
releaseVariables['variableName']
- Global variables:
globalVariables['global.variableName']
- Folder variables:
folderVariables['folder.variableName']
- Task properties: Access through
task.propertyName
(liketask.id
,task.title
,task.description
) - Release properties: Access through
task.release.propertyName
(liketask.release.title
,task.release.id
,task.release.description
) - Phase properties: Access through
task.phase.propertyName
(liketask.phase.title
,task.phase.id
) - Variable operations: Check existence with
hasVariable('variableName')
or get values withgetVariable('variableName')
- String operations: Use functions like
contains()
,equalsIgnoreCase()
,startsWith()
,endsWith()
, and many other standard string methods - JSON data: Parse and access with
parseJson(releaseVariables['jsonVariable'])['property']
All release, task, and phase properties that you're familiar with from Jython scripts are available through expression language. You access release and phase properties through the task object (task.release.title
, task.phase.title
), similar to Jython but without needing getter methods like getTitle()
—you can directly use the property name.
Common Expression Patterns
Here are typical patterns you'll use in your preconditions. These examples demonstrate common use cases, but expression language supports many more properties and methods than shown here:
Variable comparisons:
releaseVariables['variableKey1'] == 'value1'
globalVariables['global.user'] == 'admin'
releaseVariables['environment'] == 'production'
Variable existence and safety checks:
hasVariable('jsonVariable')
getVariable('global.password') != null
hasVariable('deploymentFlag')
String comparison functions:
equalsIgnoreCase('Test', 'TEST')
containsIgnoreCase('Production Environment', 'PROD')
startsWith('Production Environment', 'Prod')
startsWithIgnoreCase('Production Environment', 'PROD')
endsWith('Production Environment', 'ment')
endsWithIgnoreCase('Production Environment', 'MENT')
String content checks with contains:
contains('Hello world', 'llo')
contains('Production Environment', 'PROD')
contains('Test String', 'test')
Working with numbers and mixed types:
contains(123456, '234')
contains('123', 123)
JSON data access and collection checks:
contains(parseJson(releaseVariables['jsonVariable'])['roles'], 'admin')
contains(parseJson(releaseVariables['jsonVariable'])['roles'], 'ADMIN')
contains(parseJson(releaseVariables['jsonVariable'])['id'], '123')
parseJson(releaseVariables['config'])['environment'] == 'prod'
Edge case handling:
contains('', '') == true
contains('Hello', '') == true
!contains(null, 'abc')
!contains('abc', null)
startsWith('Hello World', '')
endsWith('Hello World', '')
!startsWith(null, 'test')
!endsWith('test', null)
startsWith('Production', 'Production')
endsWith('Environment', 'Environment')
Task and Release property access:
task.id != null
task.title.length() > 0
task.release.title.length() > 0
task.release.id != null
task.phase.title != null
task.phase.id != null
containsIgnoreCase(task.release.description, 'demo')
containsIgnoreCase(task.phase.title, 'deployment')
These examples show just a few of the many properties available. All task, release, and phase properties that you use in Jython scripts are accessible through expression language using the same property names, but without needing getter methods.
Combining Conditions with Logical Operators:
releaseVariables['environment'] == 'prod' and hasVariable('approvalToken')
containsIgnoreCase(task.release.title, 'emergency') or releaseVariables['priority'] == 'high'
getVariable('global.password') != null and hasVariable('deploymentFlag')
task.phase.title == 'Production Phase' and task.release.id != null
Additional capabilities: Expression language supports many more string methods, mathematical operations, and property access patterns beyond these examples. The expression language provides standard functionality for evaluating expressions, accessing properties, and performing operations on various data types.
Security and Restrictions
Expression language includes built-in security measures to protect your release environment. Some operations that could be potentially dangerous are automatically restricted, ensuring that preconditions remain safe and secure.
If you encounter a security-related error message (like "method is not permitted on type"), it means you're trying to use a function that's been restricted for safety reasons. In most cases, there are alternative approaches you can use to achieve the same result.
Working with Security Restrictions
The default security configuration allows you to perform most common precondition operations safely. If you need access to additional functionality for advanced use cases, your administrator can adjust the security settings in the system configuration.
For most users, the default restrictions provide the right balance of functionality and security. Focus on using the standard expression patterns shown in this guide, which work within the security boundaries and cover the majority of precondition scenarios.
Security settings should only be modified by administrators when absolutely necessary, as changes may introduce security risks to your release environment.
Performance Benefits
Expression language preconditions execute much faster than Jython scripts. While Jython scripts need to be processed and compiled, expression language evaluates your conditions instantly - similar to how a calculator immediately processes mathematical expressions.
For More Information
For more information about expression language capabilities and syntax, see:
- Expression Language Documentation - Comprehensive guide to expression language features
- Language Reference - Detailed syntax and operator reference
Jython Script Preconditions
Jython script preconditions are available for backward compatibility and for scenarios that require more complex or multi-line logic. Use Jython scripts if you need advanced programming constructs or if you are maintaining legacy configurations.
From the Precondition type drop-down, select Jython.
You can write Jython preconditions in two ways:
Boolean Expression (Single Line)
A Boolean expression is limited to a single statement script. For example:
releaseVariables['jobStatus'] == 'Success'
The task starts only when the variable jobStatus
equals 'Success'.
Multi-Line Script
For more complex scripts, set the result variable. For example:
if releaseVariables['OS'] == 'Linux' and releaseVariables['pingResult'] == '0':
result = True
else:
result = False
Best Practices
- Use expression language for simple conditions to get better performance
- Use Jython scripts for complex logic that needs multiple statements or advanced programming constructs
- Test preconditions thoroughly before you deploy to production releases
- Keep expressions readable by using clear variable names and logical operators
Troubleshooting
When a precondition fails with a security error (for example, "method repeat is not permitted on type string"), check the expression to make sure it doesn't use restricted methods. Consider using alternative approaches or consult with your administrator about security configuration when you need advanced functionality.
Disable Preconditions
You can disable preconditions on certain task types. For example, to disable a precondition on parallel groups, modify the synthetic.xml
file as follows:
<type-modification type="xlrelease.ParallelGroup">
<property name="preconditionEnabled" kind="boolean" required="true" default="false" hidden="true"
description="Whether preconditions should be enabled"/>
</type-modification>