JOB STEP
Marks the ops inside it as belonging to one step of a job. The block runs when the job reaches the step the op is named after, and stays closed on every other pass.
A job does not run its pipeline rule once. It runs the whole rule again for each step, from CHECK
through to POST, and each pass executes only the JOB STEP block whose name matches the step it is
currently on. That is the single most important thing to know about pipeline rules, and it has a
blunt consequence: any op you drop outside every JOB STEP block runs five times, once per step.
Configuration¶
This op has no configuration form. Double-clicking it opens the op properties, where the Config tab
carries the one value that decides which step the block belongs to. The Options tab is the standard
one, and Enabled is the option that matters here: untick it and the block, with everything nested
inside it, is left out of the rule entirely.
Name¶
The step this block belongs to. The match is an exact string comparison against the job's current
step, so case matters, stray spaces matter, and ${...} placeholders are not expanded before the
comparison. A name with a variable in it renders expanded in the job log and still never matches, so
the log looks right while the block stays shut.
The names that mean anything are the five a job walks through, in this order:
| Name | When it runs |
|---|---|
CHECK |
before the job exists, while the user waits |
INIT |
after the job is created, while the user waits |
PRE |
preparation: build, package, test |
RUN |
the work that changes an environment, at the scheduled time |
POST |
always, including after a failure in PRE or RUN |
Pipeline rules covers what belongs in each one. A new pipeline rule is created with all five blocks already in the tree.
Any other name is accepted by the designer and never matches anything. The block and everything
under it sits there looking correct and never runs. The same is true of any JOB STEP block in a
rule that is not a pipeline: an event rule, a form rule or a web service rule has no current step, so
the block stays shut on every run.
Two blocks may carry the same name. Both run, in tree order, which is a reasonable way to separate a
long RUN into readable sections. Nesting one JOB STEP inside another is pointless: the inner
block can only match when its name equals the outer one, and then it adds nothing.
Rollback¶
When a step fails and something in the job registered a need for rollback, the
job starts over in rollback mode from the earliest step that registered that need, PRE before
RUN, and walks forward again to POST. The blocks run a second time, with the job in rollback
mode. A need registered from anywhere other than PRE or RUN does not name a starting step, and
the rollback pass then begins at RUN.
CHECK and INIT never take part in rollback. Work done there is not unwound.
Which ops run on that second pass is decided per op, on their Options tab: Run Forward and
Run Rollback control the direction, and Needs Rollback? is what registers the need in the first
place. An op with Needs Rollback? left at No Rollback Necessary everywhere means a failing job
reports the error and stops without any rollback pass at all.
What shows in the job log¶
Every log entry carries the step it came from, and the log viewer groups entries by step. A step that
ends cleanly reports Job step RUN finished ok, and one that does not reports
Job step RUN finished with error.
The block's own name is logged before its name is compared against the current step, so a block that never matches still writes its name into the log on every pass with nothing underneath it. That is how a misspelled name gives itself away: the name shows up under all five steps and is empty under every one of them.
Combining with other ops¶
Inside a block, everything else in the palette behaves normally. The step only decides whether the block opens.
Pair it with IF ROLLBACK inside a RUN or PRE block to give the
forward pass and the rollback pass different bodies, rather than splitting them across two rules.
Put FAIL inside CHECK to reject a job before it is created, where the
message goes straight back to the user in the web interface. The same op inside RUN stops a job
that is already underway and hands over to the rollback logic.
Keep CALL rule inside a block rather than beside one, or the called rule runs once per step.
Examples¶
A minimal pipeline. The build happens before the scheduled window, the deployment inside it, and the notification whatever the outcome.
JOB STEP CHECK
IF var condition THEN
When: Any
changesets IS EMPTY
FAIL Nothing to deploy
JOB STEP PRE
Run command or local script (build)
JOB STEP RUN
Run a Remote Script (deploy)
JOB STEP POST
Send notification by email
Splitting a long step into two named blocks, both of which run.
JOB STEP RUN
...database migration ops...
JOB STEP RUN
...application deployment ops...