Gunnar

nordisk/dwarves

.nornir/brokkr-for-idiots.md

# ⚒ brokkr — for idiots

> **📍 THIS DOC LIVES IN `dwarves` (moved from `nornir/.nornir/`, 2026-07-22, move=delete).**
> The code it documents is dwarves' own (`crates/dwarves/src/…`), so the doc follows the
> code. nornir keeps only the read-only viz surface that renders this engine's output.
> Source links below are dwarves-repo-relative.


> **Class:** `idiot`. Every step, nothing assumed. Goal: write a **15-line `brokkr.toml`**, run `nornir brokkr run`, and watch it build + go green. If you already know your way around a terminal, read [`brokkr-guide.md`](brokkr-guide.md) instead — this one spells out every keystroke. The *what* is in [`brokkr-design.md`](brokkr-design.md).

**brokkr** is nornir's build robot. You write down what your project's build should
do — in one small text file — and brokkr runs those steps in the right order and
tells you green or red. You never write a build script; you *describe* the build and
brokkr does the rest.

You press **Enter** after every command.

---

## Step 1 — check you have nornir

Open a terminal (the black window where you type). Type and press **Enter**:
```
nornir --version
```
If that prints a version number, you are good.

## Step 2 — make a folder to play in

```
cd ~
mkdir -p brokkr-demo
cd brokkr-demo
```

## Step 3 — write the 15-line `brokkr.toml`

Open a text editor and make a file called **`brokkr.toml`** in this folder, with
exactly this inside (you can copy-paste it):

```toml
[pipeline]
name = "hello-ci"

[[pipeline.stage]]
name = "build"
[[pipeline.stage.step]]
name = "compile"
run = { container = { name = "rust:1.85", cmd = ["echo", "building"] } }

[[pipeline.stage]]
name = "test"
[[pipeline.stage.step]]
name = "unit"
needs = ["compile"]
run = { container = { name = "rust:1.85", cmd = ["echo", "testing"] } }
```

What this says, in plain words:
- The pipeline is called **hello-ci**.
- It has two **stages**: `build`, then `test`.
- `build` has one **step**, `compile`.
- `test` has one step, `unit`, and `unit` **needs** `compile` — so `compile` runs
  first, and `unit` only runs after it finishes.

That is the whole idea: **steps**, and which step **needs** which. brokkr works out
the order.

## Step 4 — check the file is sane

Type and press **Enter**:
```
nornir brokkr validate
```
You should see something like:
```
✓ pipeline 'hello-ci' is valid — 2 stage(s), 2 step(s)
```
If instead you see a red `✗` with a message, read the message — it tells you exactly
what is wrong (a typo in a step name, a `needs` pointing at a step that doesn't
exist, an empty command). Fix it and run `validate` again.

## Step 5 — see the plan (the order brokkr will use)

```
nornir brokkr plan
```
It prints the steps in the order they will run:
```
plan 'hello-ci' (2 steps, topo order):
  [build] compile (container)
  [test]  unit (container) needs ["compile"]
```
`compile` is first because `unit` needs it. brokkr figured that out from your file.

## Step 6 — RUN IT and watch it go green

```
nornir brokkr run
```
You should see:
```
run 'hello-ci' passed — 2/2 steps (…​ ms)
  passed compile — …
  passed unit — …
```
**`passed` and `2/2` means green.** brokkr ran your two steps in order and both
succeeded. That's it — you built a CI pipeline and ran it.

> This first run uses the built-in **demo runner**, which pretends to do each step
> and always succeeds — perfect for learning the shape without waiting on a real
> build. When you want it to *actually* build a Rust binary, add `--real`:
> `nornir brokkr run --real` (then `variant` steps really compile with cargo).

## Step 7 — see the record and get a badge

Every run is written down. List them:
```
nornir brokkr history
```
Make a little status picture (green "passing" / red "failing") you can put in a
README:
```
nornir brokkr badge hello-ci > badge.svg
```
Open `badge.svg` in a browser — it's a small green pill saying **passing**.

---

## What "red" looks like (and why it's good)

If a step's command fails, that step goes **red** (`failed`), and any step that
**needs** it is marked **skipped** — brokkr won't run a test whose build broke. The
whole run reports red and `nornir brokkr run` exits with an error code, so a bigger
script around it knows the build failed. That is exactly what you want from CI:
**green means everything worked; red means stop and look.**

## If something goes wrong

- **"no brokkr.toml found"** → you are in the wrong folder, or the file isn't named
  exactly `brokkr.toml`. `cd` into the folder that has it.
- **red `✗` on `validate`** → read the message; it names the exact problem. Common
  ones: two steps with the same `name`, a `needs` naming a step that isn't there, or
  a `container` step with an empty `cmd`.
- **a step went red on `run`** → its command returned an error. With the demo runner
  that shouldn't happen; with `--real`, it means the real build/test failed — look at
  the step's summary line.

That's the whole journey: **write a small file → validate → plan → run → green.**
No build scripts, no server, no setup — just a description of your build and one
command.