You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: COOKBOOK.md
+68-2Lines changed: 68 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -689,7 +689,7 @@ target "local" local:
689
689
-`phase "install" when "action == 'install'":` groups all install steps. Every step in the block gets `when "action == 'install'"` injected automatically.
690
690
-`phase "rollback" when "action == 'rollback'":` groups rollback steps — they are completely skipped during an install run.
691
691
-`set stateless = true` means the graph has no state file, so a previous install run can't cause rollback steps to be skipped on the next run.
692
-
-`run:` multiline blocks join lines with `&&` — if any line fails, the rest do not run.
692
+
-`run:` multiline blocks run under `set -e; set -o pipefail` — if any line fails, the rest do not run.
693
693
-`skip if:` multiline blocks join conditions with `&&` — all must exit 0 to skip.
**`phase` only gates the steps inside it.** Steps outside a `phase` block are not affected by its `when` condition. A skipped step counts as done for `first` purposes, so a step that depends on a phase step will still run even when the phase condition is false:
702
+
703
+
```
704
+
phase "install" when "action == 'install'":
705
+
[configure]:
706
+
...
707
+
708
+
[post-configure]: # outside the phase — runs regardless of action
709
+
first [configure]
710
+
...
711
+
```
712
+
713
+
If `[post-configure]` should also be gated, put it inside the `phase` block — it will inherit the `when` condition automatically. Or add an explicit `when "action == 'install'"` to it directly.
714
+
701
715
---
702
716
703
717
## Patterns (continued)
704
718
719
+
### Conditional branching by runtime value
720
+
721
+
When the branch to take depends on a fact discovered at runtime (which subnet the host is on, which OS family, etc.), use paired `skip if $` steps — each skips when the host doesn't match, and both converge to a shared downstream step:
722
+
723
+
```
724
+
[configure for subnet X]:
725
+
skip if $ ip addr show | grep -qv '10\.0\.1\.'
726
+
run:
727
+
...
728
+
729
+
[configure for subnet Y]:
730
+
skip if $ ip addr show | grep -qv '10\.0\.2\.'
731
+
run:
732
+
...
733
+
734
+
[post-configure]:
735
+
first [configure for subnet X], [configure for subnet Y]
736
+
run:
737
+
...
738
+
```
739
+
740
+
On a subnet-X host, `[configure for subnet Y]` is skipped — a skip counts as done for `first` purposes, so `[post-configure]` runs after whichever branch actually executed.
741
+
742
+
**If the configure step fails:** the default `on_fail = stop` halts the graph, so `[post-configure]` never runs. If you use `if fails warn` to allow the graph to continue past a failure, add a sentinel guard to `[post-configure]`:
743
+
744
+
```
745
+
[configure for subnet X]:
746
+
skip if $ ip addr show | grep -qv '10\.0\.1\.'
747
+
if fails warn
748
+
run:
749
+
...
750
+
touch /tmp/.subnet-x-done
751
+
752
+
[configure for subnet Y]:
753
+
skip if $ ip addr show | grep -qv '10\.0\.2\.'
754
+
if fails warn
755
+
run:
756
+
...
757
+
touch /tmp/.subnet-y-done
758
+
759
+
[post-configure]:
760
+
first [configure for subnet X], [configure for subnet Y]
761
+
skip if $ ! { test -f /tmp/.subnet-x-done || test -f /tmp/.subnet-y-done; }
762
+
run:
763
+
...
764
+
```
765
+
766
+
The sentinel file is only written on success, so `[post-configure]` skips itself when neither configure step completed.
767
+
768
+
**When to use `phase` instead:** if the branch is driven by a variable known at invocation time (not discovered at runtime), `phase "name" when "COND":` is cleaner — pass `--set action=install` and let the phase block gate the whole group.
769
+
705
770
### Multiline commands without shell glue
706
771
707
772
Long one-liners are hard to review and error-prone to edit. Use `run:` to split them across lines:
@@ -719,7 +784,7 @@ Long one-liners are hard to review and error-prone to edit. Use `run:` to split
719
784
chmod 600 /etc/nginx/certs/server.key
720
785
```
721
786
722
-
Lines are joined with `&&` — if `openssl` fails, `chmod` does not run. To continue past a failure, append `|| true` to that line.
787
+
Lines run under `set -e; set -o pipefail` — if `openssl` fails, `chmod` does not run. To continue past a failure, append `|| true` to that line.
723
788
724
789
### `always run:` for service restarts
725
790
@@ -754,6 +819,7 @@ Quick lookup: which feature solves your problem?
0 commit comments