Load Job Items into Stash
Turns the changesets riding on the job into a flat list of files, and records the project, repository and revision structure behind them. Almost every other op in a deployment rule reads one of the values it leaves in the stash, so it runs once, early, right after Init Job Home and before any checkout.
It works out which files the job touches. It does not copy anything to disk. That is the job of Checkout Job Items and its siblings, which read the structure this op built.
Configuration¶
This op has no configuration form. Its config tab is a free-form YAML editor, and one key in it does
something: rename_mode. It is on unless you set it to 0, and it controls the environment-marker
handling described under paths and environment markers. Turn it
off and every file is kept with its marker left in the path, which is almost never what you want in
a deployment rule. Everything else you type into that editor is ignored.
What ends up in the list¶
Two sources feed the same list, per project.
Files attached to the changeset topics come first. Each one gets a path built from the project name, the checkout directory configured on the file field, and the file name. When the same project and path appear more than once, the highest version wins and the rest are discarded.
Repository items come second. The job's revisions are grouped by repository, and each repository produces its own file list. Revisions carried by a release attached to the job are folded in too, but only when the release revision belongs to a repository under the same project. A release revision pointing at a repository from a different project is ignored.
How each repository decides its file list¶
The Revision Mode setting on the repository resource drives this, and it changes what the job
deploys more than anything else on this page.
| Revision Mode | File list |
|---|---|
Diff with Environment |
the difference between the newest of the job's revisions and the environment tag |
Individual Commits |
the files touched by each revision in turn, merged by path, newest wins |
Diff with Environment is the default. It needs the environment tag to exist in the repository. If
the tag is missing, or none of the job's revisions can be reached from it, the job fails with a
message naming the repository and the tag and asking whether you are redeploying to the environment.
Promote jobs have a special case. When the newest revision in the job is already the commit the environment tag points at, there is nothing to diff. The op looks back through earlier jobs for the commit that tag pointed at before, and if it finds one, it warns in the job log and diffs against that instead. If it finds nothing, the job fails saying no last job was detected for the commit and it cannot be redeployed. That is what you see when you try to redeploy a commit that is already live and no previous job recorded the older position.
The Tags Mode setting on the repository decides which tag name counts as "the environment tag".
| Tags Mode | Tag looked for |
|---|---|
Only environment |
the environment code on its own |
Release + environment |
a release prefix taken from the releases and changesets on the job, then the environment |
Project + environment |
the project name lowercased and dashed, then the environment |
Only environment is the default. A repository whose tag naming does not match its Tags Mode fails
the same way a missing tag does.
Paths and environment markers¶
A repository item ends up with three paths. The full path starts with the project name, then the
repository's Relative path, then the path inside the repository. There is also a path relative to
the checkout root without the project name, which is what the deploy ops use, and the original path
inside the repository, which is what the checkout uses to pull the file. Leave Relative path empty
on the repository resource and the repository's own name takes its place in those first two paths.
A file attached to a changeset topic gets one path instead: the project name, the checkout directory set on the file field, then the file name.
File names may carry an environment marker in braces, for example config{PROD}.xml. This op
resolves them:
- a name with no marker is kept as is
- a name marked for the job's environment is kept and the marker is stripped out of the path
- a name marked for any other environment is dropped
Both the stripping and the dropping stop happening if you set rename_mode to 0 in the config
editor.
The drop is silent. Nothing in the job log says a file was excluded because it belonged to another environment, so a file that mysteriously fails to deploy is worth checking for a stray marker.
Only real environment names count as markers. {ALL} and {ANY} are not environments, so a file
called setup{ALL}.sql keeps the literal {ALL} in its name here.
Rename Environment Items and Files is the op that strips those two, and it
does so on disk after checkout.
What lands in the stash¶
| Variable | Holds |
|---|---|
items |
every item from every project, in one flat list |
project_items |
the same items keyed by project, the structure Load Nature Items later adds to |
project_changes |
the project, repository, revision and top-revision structure |
item_name_list |
the bare file names, no directories, deduplicated |
item_name_list_comma |
those names joined with commas |
item_name_list_quote |
those names each single-quoted and separated by spaces |
items is deduplicated by full path, so a file reached through two changesets appears once. Because
the path starts with the project name, two projects can carry a file at the same relative path and
both survive.
Neither items nor the name lists comes out in a predictable order. They are built from a lookup
keyed by path, so the order changes between runs of the same job. Sort them yourself if the order
matters.
The three name lists hold file names only, with the directory stripped. Two different files both
called config.xml collapse into one entry. Use them for a quick grep or a command line argument,
not as a file inventory.
item_name_list_quote is built by wrapping quotes around the joined names, so an empty job gives
you '', a single pair of empty quotes rather than nothing at all. A command line built from it
receives one empty argument. item_name_list_comma comes back as an empty string in that case.
A second run replaces items, project_changes and the three name lists outright. project_items
is the exception: it is filled in per project, so an entry written by an earlier run for a project
that is not in the job any more stays where it is.
Failure and logging¶
A changeset with no project assigned fails the job, and the message names the changeset so you can find it. The repository failures described above stop the job as well.
On success the log gets one line, Found N items for this job, with the full path list attached.
Open it from the monitor to see exactly what the job decided to work on. The per-repository grouping
detail is debug level.
A job with no changesets is not an error. The list comes back empty, the log says zero items, and every op downstream quietly does nothing. That is the most common cause of a deployment rule that runs green and deploys nothing.
Put a name in Return Key and you get a value with one key, project_count, holding the number of
projects the op grouped changesets into. It counts projects, not files, so it stays at 1 for a job
whose single project contributed no items at all.
Combining with other ops¶
The usual order is Init Job Home, this op, then a checkout.
Checkout Job Items reads items and copies each one into the job
directory. Checkout Job Environment and
Checkout Job Environment (all repos) read project_changes instead and
work at repository level.
Load Nature Items needs project_items, so it goes after this op and
before any nature branch. FOR projects with changes DO iterates the
same project set.
Rename Environment Items and Files goes after the checkout, since it works on files already on disk.
To check the outcome before committing to a deploy, follow with
IF var condition THEN testing items with IS EMPTY.
Examples¶
The opening of a deployment rule that checks out what the changesets touched.
JOB STEP: INIT
Init Job Home
Load Job Items into Stash
Checkout Job Items
Stop early when the job has nothing to deploy, rather than running a full pipeline for no files.
Load Job Items into Stash
IF var condition THEN
When: All
items IS EMPTY
FAIL
Message: nothing to deploy, no items were loaded
Pass the file names to a command without building the list yourself.
Load Job Items into Stash
Run command or local script
Command: tar czf bundle.tgz ${item_name_list_quote}