Skip to content

MERGE value INTO stash

Copies a block of keys you write in YAML into the stash in one go. It is the bulk version of SET VAR: handy for seeding a dozen defaults at the top of a rule without a dozen ops in the tree.

The trade is that the block is fixed when you save the rule. Nothing in it is computed and nothing in it is expanded at run time, so any value that depends on the job belongs in SET VAR or SET EXPR instead.

stash before env: PRE opts: retries: 3 debug: 1 value env: PROD opts: retries: 5 stash after env: PROD opts: retries: 5 debug is gone top-level keys are replaced whole, never merged into

Fields

This op has no form of its own. Its Config tab holds two things: the standard Name box, which relabels the op in the rule tree and changes nothing about what it does, and a YAML editor that starts as value: {}.

value

A YAML mapping. Each key directly under value becomes a stash key of the same name, holding whatever you wrote beneath it: a string, a number, a list, or a nested mapping.

The copy is one level deep. A key that already exists in the stash is replaced outright, not combined. If the stash holds opts with four entries and your block sets opts with one, the other three are gone. Rewrite the whole structure, or set the individual values with SET VAR.

Nothing is expanded. ${version} written in here reaches the stash as those ten characters, not as the version, at the top level and at any depth. Anything that has to be resolved against the stash has to go through an op that expands placeholders.

The block has to be a mapping. Write a list or a plain string under value and the op runs, succeeds, logs nothing and changes nothing. The same happens if you leave value at its empty default. That is the quietest failure in the control group; when a rule turns out to lack the values you expected, check the shape of this block first.

Keys are taken literally, so a dot in a key name is part of the name and does not write into nested data. Dotted keys are also fragile: when an op set to Trap Errors actually fails, every key with a dot in its name is stripped out of the stash, at the top level and inside nested mappings, before the job asks anyone what to do. Name them opts_retries rather than opts.retries in a rule that traps anywhere.

Cost and failure

The op ends by resolving ${...} placeholders across the whole stash, throwing the result away without storing it. You never see the resolved values, but you do see the two ways that pass can fail.

On the small stashes most rules carry it costs nothing. On a job that has loaded a large file index or thousands of changesets it is not free, and it gives up after 30 seconds with a message about the data structure being too large.

It also stops the rule when values anywhere in the stash reference each other in a ${...} loop, even when neither value came from this op. The error names the variable and the chain of placeholders it followed to get back there.

Nothing is written to the job log. During a rollback the op runs again and copies the same block over whatever the forward pass left, which is usually what you want for defaults and rarely what you want for results. Clear Run Rollback on the Options tab when it is not.

Combining with other ops

Put it at the top of a rule to establish defaults, then let SET VAR override the ones that depend on the job. Later writes win, because this op does not protect what it copied.

Branch on the merged values with IF var condition THEN, and read nested entries with dotted paths such as opts.retries.

To remove a key rather than overwrite it, use DELETE hashkey.

To scope a set of values to one part of the tree rather than the whole rule, see STASH LOCAL and its limitations.

Examples

Seed a group of defaults for a deployment rule.

value:
  deploy_user: foo_deploy
  retries: 3
  dry_run: 0

Set a nested block of options in one op. Remember that this replaces any existing opts entirely.

value:
  opts:
    timeout: 600
    keep_going: 1
    log_level: debug