Flow Conditionals

Flow conditionals allow you to set specific blocks of code to run or not run depending on your flow file functionality needs.

Read more: Advanced Flow File

Note: The flow feature requires Liquibase 4.17.0+.

Flow conditionals code format

Flow conditionals exist within their own block of code within a Stage or Action in a Flow file. A few formatting rules to note are:

  • The entire conditional must be encompassed by "quotes".
  • Variables must begin with $ and be encompassed by {curly braces}.

For example:

if: "${LIQUIBASE_ACTIVE_TARGET} == dev"

Any defined variable within the scope of the flow file can be used as a conditional.
This includes:

  • Environment variables
  • Global variables
  • Stage variables
  • "included" variables
  • Properties from the defaults file

Read more: Flow Variables

Implement flow conditionals

Values within flow conditionals are called on in the format below. If the conditional value is evaluated to true, it will run the command. If the conditional value is evaluated to false, it will not run the command.

- type: liquibase
    if: "${LIQUIBASE_ACTIVE_TARGET} == dev"
    command: checks run
    cmdArgs: {checks-scope: changelog}
	
- type: liquibase
    if: "${LIQUIBASE_ACTIVE_TARGET} != dev"
    command: updatesql

When you run the flow command, messages will appear in the CLI after the flow file executes each section:

  • Executing 'liquibase' checks run: this is because the environment variable above is set to true.
  • Skipping action: 'liquibase' updatesql because condition 'dev != dev' evaluated to false.': this is the best location to find why flow conditionals did or did not run successfully. If you expected a conditional to run successfully and it did not, you are better equipped to adjust the flow file accordingly.
***********************************************************************
*
* Executing 'liquibase' checks run
*
***********************************************************************

Executing Quiality Checks against example-changelog.sql

Executing all changelog checks because a valid license key was found!

Warning: No database checks were run. Make sure the checks-scope property includes "database" to run database checks. In the CLI set --checks-scope+'changelog.database" or set an environment variable.
LIQUIBASE_COMMAND_CHECKS_SCOPE=database. Learn more at https://docs.liquibase.com/policy-checks

INFO: Checks executed against SQL generated by H2 at jdbc:h2:tcp://localhost:9090/mem:dev.
Changesets Validated: in example-changelog.sql
	ID: 1; Author: your.name
	ID: 2; Author: your.name
	ID: 3; Author: other.dev
	
Checks run against each changeset:
	Changesets Must Have a Context Assigned (Short names: ChangesetCommentCheck)
	Changesets Must Have a Context Assigned (Short names: ChangesetContextCheck)
	Changesets Must Have a Label Assigned (Short names: ChangesetLabelCheck)
	Check Table Column Count (Short names: TableColumnLimit)
	Rollback Required for Changeset (Short names: RollbackRequired)
	Warn on Detection of 'GRANT' statements (short names: SQLGrantWarn)
	Warn on Detection of 'REVOKE' statements (short names: SQLRevokeWarn)
	Warn on Detection of grant that contains 'WITH ADMIN OPTION' (Short names: SqlGrantAdminWarn)
	Warn on Detection of grant that contains 'WITH GRANT OPTION' (Short names: SqlGrantOptionWarn)
	Warn when 'DROP COLUMN' detected (Short names: ChangeDropColumnWarn)
	Warn when 'DROP TABLE' detected (Short names: ChangeDropTableWarn)
	Warn when 'MODIFY <column>' detected (Short names: ModifyDataTypeWarn)
	Warn when 'TRUNCATE TABLE' detected (Short names: ChangeTruncateTableWarn)
	
Changelogs Checks Skipped Due to unsupported changeset type for this check:
	Require primary key when creating table (Short names: PrimaryKeyOnCreateTable) skipped for:
		1:your.name,
		2:your.name,
		3:other.dev,
		
Liquibase command 'checks run' was executed successfully.

***********************************************************************
*
* Skipping action: 'liquibase updatesql because condition 'dev != dev' evaluated to false.
*
***********************************************************************

Expansion on Conditionals

Additional conditionals are available in Liquibase 4.26.0. These conditional features provide more flexibility that allows users to determine if a stage or action is executed within their Flow File. This permits users to author simplified flows that are easier to reuse and maintain when applied to multiple products across an organization. This makes flows scalable and applicable to your database as your company grows. This section covers how to enable AND, OR, NULL, STARTSWITH, ENDSWITH, and CONTAINS logic conditionals. Find descriptions and examples of these below.

Rules for additional conditionals

  • It is best practice to encompass entire conditionals by "quotes"
  • Example:
    if: "${key} == 'production'"

    if: "thisIsAVar == 'This is a string'"

    if: "'thisString' == ${myVar}"

  • Strings, also referred to as non-variables, require quotations around them, otherwise Liquibase will assume they are variables or property names instead of strings.
  • Example:
    Correct: $user == 'example'
    Incorrect: $user == example

  • Any conditional previously written is guaranteed to work, as long as it is not modified. If changes are needed you should rewrite the conditional and follow the quoting rule above.

Implementing additional conditionals

Conditional AND statements

This section includes additional conditionals which allow logic operations such as AND and OR.

if: "${KEY} == ${VALUE} && ${KEY2} != ${VALUE2}"

Conditional OR statements

if: "${KEY} == ${VALUE} || ${KEY2} == ${VALUE2}"

Grouping in Flows

You may group conditionals and nest groups of conditionals within flows.

if: "(a==true && b==true) or c==false"
if: "((a==true && b==true) or c==false) && d=true"

Conditionals that check if variables exist

flow files can check the state of a variable to see if it exists or not.

if: "(key != 'null')"
if: "(${KEY2} == nil)"
if: "(myVar == empty)"

You can express a null value in the following three ways:

'null'
nil
empty

Conditionals that check if files exist

The if exists conditional allows a user to check if a file exits at a certain location.

Rules for if exists conditionals:

  • A file can exist in a local or remote location
  • The path can be quoted or not
  • The path can be passed wholly or in part as a property substitution
  • The path can be marked as true or false relative to the current working directory.

exists example:

  • if: exists("path/to/file")
  • if: exists("./path/to/file")
  • if: exists("s3://mybucket/path/to/file")
    • Requires S3 credentials and S3 extension
  • if: exists("path/to/file", [true|false])
    • This is relative to the current working directory. It is true by default.

Conditional Substring Matching

You can set flow conditionals to determine actions based on if variables or strings start with, end with, or contain a specified string. These conditional's names are case insensitive, so you may specify startswith, STARTSWITH, endswith, ENDSWITH, and so on in whichever case you prefer. The string that you want to match must be quoted and is case sensitive.

  • STARTSWITH example: 
    if: "STARTSWITH(${MYVAR}, "STRINGTITLE")"

    This conditional matches STRINGTITLEONE but does not match TITLEONESTRING.

  • ENDSWITH example:

    if: "endswith(${MYVAR}, "STRINGTITLE")"

    This conditional matches FIRSTSTRINGTITLE, but does not match STRINGTITLEFIRST.

  • CONTAINS example:

    if: "contains(${VAR}, "TITLE")"

    This condition matches TITLE, STRINGTITLE, and STRINGTITLEONE.