IF var condition THEN
Runs the ops nested underneath it when one or more comparisons against the stash hold true. This is the general-purpose branch in the palette: it reads values straight from the stash, compares them without you writing any code, and combines several comparisons with a single any/all/none choice.
Reach for it first. IF var THEN and IF var ne value THEN only do a plain string equality test on one variable, and IF condition THEN makes you write Perl or JavaScript. This op covers the ground between them.
Fields¶
When¶
Decides how the individual condition rows combine.
| When | The block runs if |
|---|---|
All |
every row is true |
Any |
at least one row is true |
None |
no row is true |
None is the opposite of Any, not the opposite of All. One true row is enough to shut the block
down.
Every setting short-circuits. All stops at the first row that comes out false, Any and None
stop at the first row that comes out true, and the remaining rows are never evaluated. Order your
rows cheapest-first and put guards ahead of the rows that depend on them.
Leave When unset and the block never runs, whatever the rows say. Nothing warns you. Pick one of
the three values even when you only have a single row.
Stash Variable¶
The left side of the comparison. Write the variable name on its own, with no ${} wrapper:
status, not ${status}. A row whose variable is blank fails validation, so every row has to name
something.
Dots walk into nested data, so topic.title reads the title out of a topic. Positions in a list
take square brackets: job.changesets[0].name reaches the first entry, while
job.changesets.0.name resolves to nothing at all. A path that does not resolve gives back an empty
value instead of an error, which is why IS EMPTY is the safe way to test whether something reached
the stash at all.
Operator¶
Picks the comparison, listed in full below. A new row starts on IS TRUE. Your choice
reshapes the rest of the row: IS TRUE, IS FALSE, IS EMPTY and NOT EMPTY hide the value field
because they only inspect the left side, and the case and numeric checkboxes appear only for the
operators that honour them.
Value¶
The right side of the comparison. Unlike the variable field, this one expands ${var} placeholders
against the stash, so ${project.name}-build and release/${version} both work. That asymmetry
catches people out: the left field is a path, the right field is a template.
For LIKE and NOT LIKE, type a regular expression.
IN and NOT IN never split what you type. approved,scheduled is compared as one long string and
matches nothing, which is the most common way to get a row that is silently always false. The
several values have to arrive as several values: point the field at a stash key that already holds a
list, ${allowed_statuses}, built by PUSH VAR or by
SET EXPR returning a list. For a fixed set typed into the form, use
LIKE with ^(approved|scheduled)$, or give each value its own row and set When to Any.
Options¶
Two checkboxes, shown only for the operators that support them.
Ignore case lowercases both sides before comparing. On LIKE and NOT LIKE it makes the pattern
itself case-insensitive instead.
Numeric switches from text ordering to number ordering. This matters more than it looks: as text,
9 sorts after 10, and 007 is not 7. Tick it for build numbers, counts, sizes, anything that
came out of arithmetic.
Add condition and Remove¶
Add condition appends another row; Remove deletes the row it sits in. Rows have no individual
weight and no nesting of their own, so every row answers to the same When setting. For mixed
and/or logic, nest a second IF var condition THEN inside the first, or move the whole test into
IF condition THEN.
Operators¶
| Operator | True when | Value field | Options |
|---|---|---|---|
IS TRUE |
the variable holds a non-empty, non-zero value; for a list, any element does | hidden | none |
IS FALSE |
nothing in the variable is truthy | hidden | none |
IS EMPTY |
the variable is unset, an empty string, an empty list or an empty hash | hidden | none |
NOT EMPTY |
the variable holds something | hidden | none |
EQUALS |
the two sides match exactly | text | case, numeric |
NOT EQUALS |
the sides differ | text | case, numeric |
GREATER THAN, >=, LESS THAN, <= |
the ordering holds | text | case, numeric |
LIKE |
the regular expression matches somewhere in the value | regex | case |
NOT LIKE |
the regular expression does not match | regex | case |
IN |
the value resolves to a list and the variable equals one of its entries | list | case |
NOT IN |
the variable matches none of them | list | case |
HAS |
the variable is a list or hash and the value is one of its entries | text | case |
NOT HAS |
that list does not contain the value | text | case |
IN and HAS look alike and get swapped constantly. IN asks whether one stash value appears in
the list on the right. HAS asks whether the text on the right appears in a list sitting in the
stash on the left. When the variable holds many things, you want HAS. Neither one builds a list out
of a comma-separated string, so the side that is meant to hold several values has to hold a real
list. On a hash, both operators look at the keys and the values.
An unset variable is true for IS EMPTY and true for IS FALSE. A variable holding 0 is true for
IS FALSE and false for IS EMPTY, because a zero is a character like any other. Use IS EMPTY
when the difference between "never set" and "set to zero" is the thing you are testing.
An operator the server does not recognise stops the rule with an error rather than quietly evaluating false. That only happens to hand-edited rules, since the form can only produce the operators above.
Combining with other ops¶
Drop ELSE or ELSIF condition THEN directly after
this op for the other branch. They bind to the closest preceding IF, so keep them adjacent in the
tree.
The same condition builder drives WHILE condition and
DO-WHILE condition, so everything on this page applies there too. A
WHILE whose body never changes the variable it tests will spin forever.
To branch on something the stash does not carry yet, load it first. The loader services write into the stash and this op reads whatever they left behind.
Examples¶
Skip a deployment block unless the topic reached a status that permits it, on the environments you care about. Both sets are written as patterns because they are typed into the form.
When: All
status LIKE ^(approved|scheduled)$
env LIKE ^(PROD|PRE)$ (Ignore case)
The same test against a list another op left in the stash, where IN does apply.
When: All
status IN ${allowed_statuses}
Stop early when an earlier step recorded trouble. Nest FAIL inside to end the job.
When: Any
build_errors NOT EMPTY
test_failures GREATER THAN 0 (Numeric)
Act only on unassigned incidents, reading paths out of a loaded topic.
When: All
topic.owners IS EMPTY
topic.category EQUALS incident (Ignore case)