APPLY NATURE
Runs the path patterns of one nature resource over the items the job loaded, and leaves the matching
ones in the stash under nature_items. One op in the palette picks that list up on its own:
Deploy SQL from Nature Items, which runs every file in it against a database connection. Anywhere
else, the list is something you test or walk yourself.
The Nature Items modes on Ship File Remotely and
Load files/items into stash do not read it. They read
nature_item_paths, which this op never writes and only
IF EXISTS nature THEN fills, so either of them placed after this op
finds an empty list and moves nothing.
It is a plain filtering step with nothing nested inside it. IF EXISTS nature THEN wraps a block, sets its own values for the length of that block and hands back what was there before. IF ANY nature THEN tests whether a nature was detected and writes nothing. This op sets one value and moves on, so the list it produces stays in place for the rest of the rule.
Fields¶
Nature¶
The nature resource whose Include and Exclude patterns you want applied. The combo lists one entry per nature and you can pick only one. Selecting a second replaces the first.
The list also carries entries named variable: ${name}, because the picker shows variables
alongside resources. Do not pick one here. This op uses the stored value as typed and never expands
${...}, so a variable entry turns into a resource lookup for the literal text and stops the rule.
Only a real nature works.
The field accepts a blank value and the designer saves it without complaint, but a blank nature stops the rule at that point with a missing-resource error. So does a nature that was deleted after the rule was written.
How items are matched¶
Each item the job loaded is tested against the Include patterns held on the nature, under Paths. The patterns are regular expressions, matched case-insensitively and anywhere in the path, and the first one that matches is enough. The item is then tested against the Exclude patterns, and one match there drops it again. Exclude always wins.
An item path is built as a leading slash, the project name, the repository checkout path and then
the path inside the repository. A file stored as db/create.sql in a repository of project foo is
tested as /foo/db/create.sql, and as /foo/src/main/db/create.sql when that repository has a
checkout path of src/main. Patterns anchored with ^db/ or ^foo/ therefore match nothing.
Anchor on the tail instead, with something like \.sql$, or leave the pattern unanchored.
Named capture groups in an Include pattern are kept: whatever a group captures is attached to the matched item as one of its own values, which is how a nature can pass a version or a schema name to code that reads the list afterwards.
The result is deduplicated, so an item touched by two changesets appears once. It comes back in no particular order, which is not the order of the changeset, so nothing downstream should rely on the first entry being the first file changed.
The silent cases¶
A nature with no Include patterns matches nothing. The op then sets nature_items to an empty list
and carries on, with no error and no warning. A row left blank on the nature does not widen the
filter either, because blank rows are dropped before anything is matched, so a nature whose only
Include row is empty behaves as a nature with no patterns at all. The same empty result comes back
when no item matches, and when the rule never loaded any items in the first place, which is the
usual cause: put Load Job Items into Stash above this op.
There is no log line at all. Nothing appears in the monitor to say the nature was applied or how many items it kept, so an empty result looks exactly like a nature that was never reached.
Despite the name, the variables defined on the nature resource do not reach the stash. Nothing new
appears under their names, so no ${...} in the rest of the rule can see them. When you need
per-nature values, define them as project variables scoped to the nature and use
IF EXISTS nature THEN, which does load them, or point
SET VAR to CI at the nature and read its fields.
What lands in the stash¶
nature_items is the only value written, and it is written whether or not anything matched. It is
not scoped and not restored: a second APPLY NATURE overwrites the list from the first, and the last
one to run is the one the rest of the rule sees. The entries are item resources carrying a path, a
change status and any values captured by the patterns.
Rules that mix this op with IF EXISTS nature THEN need care. That op
sets nature_items to its own list for the length of its block, so the list built here is invisible
inside the block and comes back when the block ends.
Once this op has run, Deploy SQL from Nature Items has no way back to the full item list. That op
works on every item in the job while nature_items is unset and switches to the filtered list as
soon as it exists, including when the filter kept nothing.
Failure and rollback¶
A missing or unreadable nature stops the rule. A malformed pattern on the nature stops it as well, before any item is tested. Neither leaves a partial list behind.
The op runs on the rollback pass too, by default, and recomputes the same list from the items the
job holds at that moment. Untick Run Rollback on the node when a rollback should keep the list a
later op built.
Combining with other ops¶
Order is Load Job Items into Stash, then APPLY NATURE, then whatever
reads the list. Check the outcome with
IF var condition THEN on nature_items using IS EMPTY or
NOT EMPTY. A LOG Message that mentions ${nature_items} inside a sentence
stops the rule with an unexpected-reference error instead of printing the paths, because the value
holds resources rather than text.
FOREACH CI is not the way to walk it. That op reloads every entry
from the database by its resource id, and items built from repository revisions are created during
the job and never saved, so they have no id and the rule stops with a missing id error before the
first pass. To act on one item at a time, read nature_items in
Server CODE.
Examples¶
Keep only the packaged builds of a job and skip the rest of the rule when there are none.
Nature: war_files
IF var condition THEN
When: All
nature_items NOT EMPTY
Narrow a job to its database scripts and run them against one connection, with the files already on disk.
Load Job Items into Stash
Checkout Job Items
APPLY NATURE Nature: sql_scripts
Deploy SQL from Nature Items Database: bar_db