holger build target — guide (how to use it)
Class:
guide· sibling: design · for-idiots.
The holger build target is dwarves' pipeline that builds holger's three deployment executables (embedded · mini · full). This is how you drive it.
Resolve the plan (compile-free — the CI check), locally
$ dwarves holger-build ../holger
holger build target (holger-tiers) against ../holger — 3 tier(s), 3 resolved, 0 missing:
✓ embedded → bin holger-embedded · cargo build -p holger-server-cli --bin holger-embedded --features embedded --no-default-features --profile release
✓ mini → bin holger-mikro · cargo build -p holger-server-cli --bin holger-mikro --features mini --no-default-features --profile release
✓ full → bin holger-full · cargo build -p holger-server-cli --bin holger-full --features full --no-default-features --profile release
- The
<path>argument is holger's repo root (default../holger, the side-by-side checkout convention). Its.nornir/build-variants.tomlis read. - Exit codes:
0= all three tiers resolve;1= a tier is unwired (holger renamed/dropped it);2= holger declares no build-space at that path. This makes the verb a gate — wire it into a check that must stay green. - It does NOT build holger. It resolves the plan and prints the exact
cargoargv each tier would run.
From Rust (the library surface)
use dwarves::holger_build;
use nornir_build_thing::BuildVariantSet;
// The pipeline as data (one Variant step per tier).
let pipeline = holger_build::pipeline(); // name = "holger-tiers"
// Resolve against holger's declared build-space (discovers .nornir/build-variants.toml).
let res = holger_build::resolve_against_repo(std::path::Path::new("../holger"))?;
assert!(res.is_complete()); // all three tiers wire up
println!("{}", res.state_json()); // the observable seam
// Or resolve against a set you already hold:
let set = BuildVariantSet::discover(std::path::Path::new("../holger"))?.unwrap();
let res = holger_build::resolve(&set);
Over the wire (the server RPC — remote-driven)
The holger build target is remote-controllable off the dwarf.v1 forge service via the ResolveHolgerBuild RPC — the CLI verb's wire twin (same resolution, no compile). A thin client sends a HolgerBuildRequest and reads back the 3-tier plan:
rpc ResolveHolgerBuild(HolgerBuildRequest) returns (HolgerBuildReply)
HolgerBuildRequest { holger_root } # empty ⇒ $DWARVES_HOLGER_REPO, else ../holger
HolgerBuildReply { tiers[], resolved, missing, complete, found }
HolgerTier { tier, step, resolved, bin, package, command_line }
complete=trueiff all three tiers resolve; a dropped/renamed tier comes backresolved=falsewithcomplete=false(the gate).found=falsewhen holger declares no build-space atholger_root— an empty plan, not an error (mirrors the CLI's exit 2); a malformed descriptor ⇒InvalidArgument.- Bearer-gated like every
dwarf.v1RPC (the sharednornir-serviceinterceptor); it never compiles holger — a remotedwarves run --realover holger is the build.
Drive it against a running server (--server — the thin-client verb)
The same holger-build verb goes THIN with a global --server <addr>: it drives the ResolveHolgerBuild RPC over a real gRPC round-trip and prints the identical 3-tier report + exit code as the local run. The <path> is resolved on the server's filesystem.
$ dwarves --server 127.0.0.1:7900 --token "$DWARVES_SERVER_TOKEN" holger-build /srv/holger
holger build target (holger-tiers) via 127.0.0.1:7900 against /srv/holger — 3 tier(s), 3 resolved, 0 missing:
✓ embedded → bin holger-embedded · cargo build -p holger-server-cli --bin holger-embedded --features embedded --no-default-features --profile release
✓ mini → bin holger-mikro · cargo build -p holger-server-cli --bin holger-mikro --features mini --no-default-features --profile release
✓ full → bin holger-full · cargo build -p holger-server-cli --bin holger-full --features full --no-default-features --profile release
--server(or$DWARVES_SERVER) switches to the RPC path;--token(or$DWARVES_SERVER_TOKEN, then~/.dwarves/token) supplies the bearer.- Same exit codes as the local verb:
0all resolve ·1a tier unwired ·2the server found no build-space at that path. - Needs a
dwarvesbuilt--features server(the thin client). The local verb stays available with no--server— the two are additive doors onto one resolution.
Actually building the tiers (the run-time half)
The real build is nornir-build-thing's job, driven through the forge's RealRunner:
let runner = holger_build::runner("../holger".into()); // RealRunner over holger's set
// dwarves run --real (or the server with DWARVES_REAL_RUNNER=1) walks the pipeline
// DAG through this runner; each Variant step → build_variant → a real cargo build +
// a provenance attestation. Container/VM steps (none here) defer to the demo fallback.
A store-backed run (the holger feature + DWARVES_HOLGER_DIR) captures each tier's executable and records a manifest of the set.
What it does NOT do
- It does not publish or deploy anything — it builds the executables.
- The plan check never compiles holger; the real build is opt-in (
--real) and heavy. - dwarves owns the pipeline; the
cargo builditself is alwaysbuild_variant.