Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/dwarves

.nornir/release-deps-consume-for-idiots.md

release / deps — for idiots

Class: for-idiots · the zero-knowledge walkthrough. What it IS: release-deps-consume-design.md · how to use it: release-deps-consume-guide.md.

The problem

When you publish a bunch of Rust crates that depend on each other, order matters: a crate must be published after the crates it depends on. And you should not bother re-publishing a crate whose code has not changed since last time.

nornir already had smart code that works both of these out. But that code was written so only nornir could use it — dwarves (the thing that actually runs builds and releases) couldn't reach it. We fixed that: dwarves now borrows the same code (it does not copy it).

What you can do now

Two new commands (build with --features release):

dwarves release .

Looks at a workspace and prints the publish order in waves:

wave 0: the crates nothing depends on (publish these first)
wave 1: the crates that only needed wave 0
wave 2: …and so on

It also reminds you of the rule: a crate is skipped only if it is already published and its code is byte-for-byte the same as what's published. It does not actually publish anything — that final, riskier step still belongs to nornir.

dwarves release . --check-size

Before uploading, dwarves now weighs each crate. crates.io will not take a crate bigger than 10 MiB, and when one is too big it answers with a plain "503" — the same answer it gives when the server is having a bad day. So the operator retries a publish that can never work. That is exactly what happened on 2026-09-02: three attempts, one hour, and the real answer was "korp is 12.8 MiB".

So dwarves packages each crate itself first and says:

size: korp@0.1.0 packages to 7.0 MiB (592 file(s)) — within 10.0 MiB

and if a crate is too big it stops the whole release before anything is uploaded and tells you what is making it big:

  biggest directories in the .crate (uncompressed):
       7.2 MiB  src/  (115 files)
       2.3 MiB  assets/  (10 files)
  biggest files in the .crate (uncompressed):
     763.9 KiB  assets/korp_logo.png

Then you either ship less (exclude = [...] in Cargo.toml) or ask crates.io to raise the limit for that crate and tell dwarves the new number with --max-upload-mib.

This runs on its own before a real --execute; --check-size is how you ask for it during a dry run.

dwarves deps <folder-of-repos>

Point it at a folder that holds several repos side by side. It draws the dependency picture and prints the order to build them:

build order (deps-first): leaf → mid → app

meaning: build leaf first, then mid, then app.

Why "borrow, don't copy"?

If dwarves wrote its own copy of this logic, the two copies would drift apart and one day disagree. By calling the exact same shared code, dwarves and nornir can never disagree about publish order or what's changed. One brain, two front doors.