Skip to content

SET VAR

Writes one stash key from a block of text, expanding any ${var} placeholders in that text first. Reach for it whenever the value is a constant or a template built out of values other ops already put in the stash.

Use SET EXPR when the value has to be worked out in code, and PUSH VAR when you want to add to a list rather than replace it.

Value raw text expand ${...} one placeholder only mixed with text original type survives a list stays a list the result is text a list stops the op

Fields

Variable

The stash key to write. Type the bare name, with no ${} wrapper: build_dir, not ${build_dir}.

Placeholders are not expanded here, so the key name cannot be built at run time. If you need a computed key name, use SET EXPR.

Dots are part of the name, not a path. Typing topic.title creates a flat key whose name happens to contain a dot, and it does not write into the loaded topic. Worse, it then shadows the real value: ${topic.title} prefers an exact key match, so it reads your flat key, while the condition rows in IF var condition THEN walk the nested path and still see the topic. The two disagree and the mismatch is silent. Keep key names flat.

Leave this blank and the op writes a key with an empty name. Nothing fails and nothing warns, but no other op can read it back. That is the most common way to make this op do nothing.

The write is unconditional. An existing key of the same name is replaced, whatever it held.

Value

A multi-line text area. Whatever you type is stored verbatim except for ${...} placeholders, which are resolved against the stash as the op runs.

Whether the result is text or structured data depends on the shape of what you type:

  • The whole value is exactly one placeholder, as in ${changesets}. The key gets the original value, so a list stays a list and a resource stays a resource.
  • The placeholder sits next to other characters, as in build-${version}. The result is text, and every placeholder in it has to resolve to a single value.

In that second case a placeholder that resolves to a list, a hash or a resource stops the op with Unexpected reference found in ${changesets}. It is not flattened into an unreadable text form, and it is not silently dropped: the step fails. Reach into the structure instead, since ${changesets[0]} and ${topic.title} each produce a single value and sit happily in mixed text.

A placeholder that cannot be resolved is left in the text exactly as you typed it. There is no error and no blanking, so a typo in a variable name turns up later as a literal ${typo} in a command line or a file. When a missing value should stop the rule instead, write ${+version}.

Leave the Value blank and the key is set to the empty string. That differs from never setting it only in that the key now exists; an IS EMPTY test is still true for it.

Resolution is recursive. If a placeholder resolves to text that itself contains ${...}, that is resolved too. Two variables that refer to each other fail the op with a recursion error naming the path it followed. Resolution also gives up after 30 seconds on a very large stash.

Placeholder forms

You write You get
${foo} the value of the key foo
${foo.bar} a value nested inside foo, when no flat key named foo.bar exists
${foo[0]} the first entry of the list in foo
${+foo} the same as ${foo}, but the op fails when foo is missing
${{foo}} the value of foo with no second pass over its contents
${uc(foo)}, ${lc(foo)} the value upper-cased or lower-cased
${to_id(${foo})} the value reduced to a plain identifier, spaces and punctuation folded to _
${nvl(foo,none)} the value of foo, or none when it is missing
${pad('0',5,foo)} the value padded on the left to 5 characters
${quote_list(foo)} the entries of the list in foo, each wrapped in double quotes
${json(foo)} the contents of foo as JSON
${ci(foo).name} an attribute of the resource whose id is in foo
${outer_${inner}} a key name built from another variable
$${foo} a literal ${foo}, left alone

to_id is the odd one out. uc, lc, pad and quote_list read the variable you name, but to_id works on the text between its brackets, so ${to_id(foo)} gives you the word foo rather than the value of foo. Nest the placeholder, as in the table, to get the value.

Variable parsing covers the same syntax in more depth.

Behaviour in a job

The op writes nothing to the job log of its own. The name you gave the node in the rule tree appears as the step heading, and ${...} in that name is expanded, so you can label the step with the value being set.

During a rollback the rule runs again in the reverse direction. This op runs in both directions unless you clear Run Rollback on the node, so variables the rollback ops depend on are still set for them. Clearing Run Forward instead gives you a value that exists only during rollback.

Combining with other ops

Set a flag before a branch and read it back with IF var condition THEN or IF var THEN.

Build a list one entry at a time with PUSH VAR, then walk it with FOREACH CI or FOREACH file/item.

Print what you stored with LOG Message, which takes the same ${...} syntax in its text.

When the value is a resource id and you want the resource itself, follow this op with SET VAR to CI, or skip both and read ${ci(myvar).name} directly.

In a YAML rulebook the same op is written as set, with var and value keys. There the value may also be a list, and each entry is expanded on its own. See Variables and templating.

Examples

A constant switch that later branches read.

Variable   dry_run
Value      1

A path assembled from values other ops left behind.

Variable   release_dir
Value      /deploy/${project.name}/${version}

Copying a list without flattening it. Because the value is nothing but the placeholder, the key ends up holding the list itself.

Variable   changeset_mids
Value      ${job.changesets}