๐ Command line
rundot RUNBOOK [--dry] [--step | --no-step] [--show-code] # run a runbook
rundot run RUNBOOK [--dry] [--step | --no-step] [--show-code] # the same, in full
rundot check RUNBOOK # find problems without running anything
rundot inputs RUNBOOK # list the inputs a runbook needs
rundot library # list the books in your runbook library
rundot backends # list the languages rundot can run
rundot --version
rundot on its own shows this list.
Naming a runbook
RUNBOOK is a file, or the name of a book in your runbook library:
rundot RELEASING.md # the file RELEASING.md, here
rundot rebuild-frontend # the book rebuild-frontend.md, in your library
- If
RUNBOOKis a file that exists, that's the runbook, so a file is never hidden by a book with the same name. - Otherwise, if it has no
/, it's the book<name>.mdin your library. The.mdis optional. - Otherwise it's a usage error, which names both places rundot looked:
Error: Invalid value for 'RUNBOOK': no runbook 'rebuild-frontend': no such file here, and no rebuild-frontend.md in the library at /home/you/runbooks
rundot run
Runs a runbook, step by step.
rundot RELEASING.md
You don't need to type run: anything after rundot that isn't a command is a runbook. Options go before or after it, so rundot RELEASING.md --dry is the same as rundot --dry RELEASING.md. Use rundot run check to run a book called check.md, since rundot check is the command.
- Checks the runbook, as
rundot checkdoes. Errors stop it here. - Collects the inputs. See Inputs.
- Shows the plan and asks
Start? [y/N]. - Runs each step in order, streaming each block's output as it's printed. Each block shows its language and when it started, then what it printed, then its exit code and how long it took. A line it wrote to stderr has a red
โ.
VERSION (The version to release, e.g. 1.2.0): 1.2.0
โญโ Release my-package โโโโโโโโโโโโโโโโโโโโโโฎ
โ directory /home/you/Projects/my-package โ
โ inputs VERSION=1.2.0 โ
โ steps 1. Run the tests โ
โ 2. Tag the release โ
โ 3. Publish on GitHub โ
โ blocks 2 run blocks โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Start? [y/N] y
1/3 Run the tests โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sh ยท 10:02:13.482
โ ...
โ โ exit 0 ยท 4.2s
2/3 Tag the release โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sh ยท 10:02:17.705
โ โ exit 0 ยท 0.1s
3/3 Publish on GitHub โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โญโ confirm โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ Create a GitHub release from tag 1.2.0. โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Continue? [y/N] y
โญโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ finished ok ยท 12.8s โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโฏ
transcript: logs/release-1.2.0.md
directory is where blocks will run. See Where blocks run.
The run stops at the first block that fails:
1/1 Build โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sh ยท 10:02:13.482
โ Building
โ make: *** [build] Error 2
โ โ exit 2 ยท 0.0s
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ failed at "Build" (exit 2) ยท 0.0s โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Only y answers Start? and Continue? with yes. Anything else, including enter, ends the run as aborted.
--show-code
Shows each block's code above what it printed:
โ sh ยท 10:02:13.482
โ echo "Building"
โ output
โ Building
โ โ exit 0 ยท 0.0s
--dry always shows the code.
Picking a book
With no runbook, rundot run asks which book from your library to run:
$ rundot run
1. rebuild-frontend Rebuild the frontend
2. update-project-deps Update a project's dependencies
Run which? (q to quit) 1
Answer with a number. --dry and --step work too. Answer q, or press enter, to stop without running anything.
--dry
Shows what the runbook would do, without running anything.
rundot --dry RELEASING.md
- Every block is shown with its inputs filled in.
- There's no
Start?,confirmblocks don't wait, and no transcript is written. - Secrets and input blocks aren't asked for.
VERSION (The version to release, e.g. 1.2.0): 1.2.0
โญโ Release my-package โโโโโโโโโโโโโโโโโโโโโโฎ
โ directory /home/you/Projects/my-package โ
โ inputs VERSION=1.2.0 โ
โ steps 1. Run the tests โ
โ 2. Tag the release โ
โ 3. Publish on GitHub โ
โ blocks 2 run blocks โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
dry run: nothing will be run
1/3 Run the tests โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sh
โ make test
โ not run
2/3 Tag the release โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sh
โ git tag 1.2.0
โ not run
3/3 Publish on GitHub โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โญโ confirm โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ Create a GitHub release from tag 1.2.0. โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ dry run, nothing was run โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
--step
Asks before running each run block.
rundot --step RELEASING.md
1/2 Build โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sh ยท 10:02:13.482
โ Run this block? [y]es / [s]kip / [q]uit y
โ Building
โ โ exit 0 ยท 0.0s
2/2 Publish โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sh ยท 10:02:13.486
โ Run this block? [y]es / [s]kip / [q]uit s
โ โท skipped
โญโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ finished ok ยท 0.0s โ
โฐโโโโโโโโโโโโโโโโโโโโโโโฏ
y runs the block, s skips it, and q ends the run as aborted. The code isn't shown unless you add --show-code. With --dry, --step does nothing, since nothing runs.
A runbook that should always be run this way can set step: true in its frontmatter, so you don't need to remember --step. To run one of those straight through, pass --no-step.
Pressing Ctrl-C
- A running block gets the Ctrl-C too, and rundot waits for it to stop.
- If a block ignores it, press Ctrl-C again to stop the block and everything it started.
- The run ends as
โ interrupted at "<step>".
rundot check
Finds problems in a runbook without running anything.
rundot check RELEASING.md
RELEASING.md: ok
Each problem is shown with its line, so your editor can jump to it:
broken.md:6: error: input VERSION is declared twice (first on line 4)
broken.md:8: warning: input BRANCH is never used
broken.md:12: error: run blocks must be inside a step (a ## heading)
broken.md:19: error: <TAG> isn't a declared input
broken.md:21: error: syntax error near unexpected token `fi'
4 errors, 1 warning
Errors stop the runbook running:
- a missing
title, or a frontmatter value of the wrong type - an input without a
nameordescription, a name that isn't UPPER_SNAKE_CASE or is declared twice, or apatternthat isn't a valid regular expression - a
defaultorchoicesthat can't work. See Defaults and Choices. - a placeholder that isn't a declared input, or a secret used as a placeholder
- an
inputblock that isn't valid YAML, or is used before it's asked for - a block before the first
##heading - a
runblock in a language no backend runs, or apythoncommand that isn't installed - a syntax error in a shell or Python block
Warnings don't:
- a frontmatter or input key rundot doesn't know, often a typo
- an input nothing uses
- a Python
SyntaxWarning, and shellcheck findings if it's installed
rundot inputs
Lists the inputs a runbook needs, so you know what to have ready.
rundot inputs PUBLISHING.md
VERSION The version being released, e.g. 1.2.0
pattern: ^\d+\.\d+\.\d+$
BRANCH The branch to release from
default: main
PR The number GitHub gave the pull request
pattern: ^\d+$
asked in "Open the pull request"
OTP The code from your authenticator app
pattern: ^\d{6}$
secret
asked in "Publish"
Inputs from input blocks come last, with the step that asks for them. Frontmatter inputs are listed even if the rest of the runbook is broken.
rundot library
Lists the books in your runbook library, with each one's title and description.
$ rundot library
library: /home/you/runbooks
rebuild-frontend Rebuild the frontend
Clean install the frontend's dependencies, then rebuild it.
update-project-deps Update a project's dependencies
A book whose frontmatter can't be read is still listed, with why.
rundot backends
Lists the languages rundot can run, and the package each comes from.
$ rundot backends
python python, py rundot.backends.python:PythonBackend (rundot 0.2.0)
shell sh, bash, shell rundot.backends.shell:ShellBackend (rundot 0.2.0)
Exit codes
| Code | Meaning |
|---|---|
0 |
The run finished, or check found no errors. |
1 |
A block failed, the run was aborted or interrupted, check found errors, or the runbook couldn't be read. |
2 |
The command was used wrongly, e.g. a runbook that doesn't exist. |