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

nordisk/dwarves

.nornir/cicd-market-inspiration.md

CI/CD market inspiration — what dwarves borrows (anchor: TeamCity)

Why this doc. dwarves is the nordisk TeamCity-in-Rust. Survey the CI/CD field — long-popular tools and new-and-beloved ones — and pull the genuinely good ideas, even from tools we dislike. dwarves' differentiators stay: pipelines are Rust xtasks (zero YAML), the DAG is presented by facett (facett-plandag/facett-brokkrview — a visual edge YAML tools don't have), and everything is remote-controllable + robot-tested in code.

Established tools

Tool Beloved feature Borrow → dwarves
TeamCity (anchor) Build chains (snapshot + artifact deps), agent requirements, pre-tested / personal builds, investigations/mute brokkr [[pipeline.depends]] = the chain; content-addressed artifacts flow along DAG edges; agent requirements → jera worker-group capability match; pre-tested = run the DAG on a worktree before landing; "investigation" = attach an owner + mute to a red node (funnel/plan-DAG already has assignment).
Jenkins ubiquity, plugin ecosystem, scripted pipelines lesson = don't be Jenkins (Groovy/plugin sprawl); our "plugins" are just Rust crates. Keep the declarative brokkr.toml seed + the programmable xtask.
GitLab CI needs: DAG (out-of-order), dynamic child pipelines, runners + tags ready-frontier drain (already sindri); dynamic pipelines = an xtask emits its DAG at runtime (native, since it's code); runner tags → jera group/label match.
GitHub Actions matrix fan-out, reusable workflows/composite actions, self-hosted runner labels, environments + required reviewers matrix = BuildVariantSet (target×feature×profile); reusable = brokkr pipeline templates; runner labels → jera worker-groups; environments + approval gates → dwarves release gates (manual/approval node before ship).
CircleCI orbs (reuse), test splitting/parallelism, fast caches test-splitting across jera agents (gatling within an agent, jera across agents); layer/action cache already in brokkr (ActionCache).
Buildkite ⭐ self-hosted agents + hosted control-plane — you own the compute, they own orchestration THE model for dwarves: dwarves-server = control plane (schedule/observe), dwarves agent = your machines run the work. Maps 1:1 onto the jera-multi-machine build below.
Argo / Tekton k8s-native DAG, Task/Pipeline CRDs, step-as-container container/VM steps via draupnir (KVM/OCI/Redfish) submitted as jera jobs — get k8s-style isolation without owning k8s.
Azure DevOps (borrow selectively) YAML templates (parameterized reuse), environments + gate checks, artifact feeds/retention template reuse → brokkr pipeline templates; gate checks (approval / external-signal before a stage) → release gates; artifact feeds → holger (the registry) with retention. Skip the rest.

New & beloved

Tool Why loved Borrow → dwarves
Dagger ⭐ pipelines-as-code in a real language + content-addressed caching, runs anywhere validates our thesis: Rust xtask pipelines, zero YAML. Steal the caching model (cache by input digest — brokkr already does content-addressed).
Earthly repeatable containerized builds (Earthfile), strong caching reproducibility = draupnir container step + content-addressed artifacts; byte-identical re-run is already the bench/roundtrip law.
Depot / Namespace / Blacksmith fast remote builders + shared remote cache, ephemeral runners remote builders = jera worker-groups on beefy boxes (Loki/Odin); shared cache = the content-addressed action cache served from the warehouse.
Woodpecker lean, self-hostable, open Drone-style the "small & self-hosted" ethos — dwarves is one binary + agents, no SaaS.

dwarves synthesis — the top features to build (mapped)

  1. Distributed agents / worker-groups (jera multi-machine) — the keystone; sketch below. (Buildkite/GHA/TeamCity-agents/Depot)
  2. DAG with needs + matrix fan-out — brokkr DAG + BuildVariantSet; sindri drains the ready frontier. (GitLab/GHA)
  3. Build chains: snapshot + artifact deps across pipelines — [[pipeline.depends]], content-addressed artifacts along edges. (TeamCity)
  4. Dynamic pipelines — an xtask emits its own DAG at runtime. (GitLab child pipelines)
  5. Approval / environment gates — a manual/external-signal gate node before ship. (GHA environments / Azure gates)
  6. Pre-tested / personal builds — run the DAG on a worktree branch before it lands. (TeamCity)
  7. facett presents the DAG — facett-plandag/facett-brokkrview render the live pipeline (stations light up); the visual edge over every YAML tool. (our own)
  8. Content-addressed cache + reproducible container steps — already seeded; extend with a warehouse-served shared cache. (Dagger/Earthly/Depot)

Two standing differentiators: pipelines are Rust xtasks (zero YAML); the whole thing is remote-controllable and robot-tested in code (self-driving, per the autotest law).

jera multi-machine — design sketch (the keystone build item, ties H1)

Today jera = local job ledger + process/VM/container runners; brokkr's AgentPool is in-process. Target = the Buildkite model: hosted control-plane + your own agents, over gRPC.

control plane:  dwarves-server  (sindri scheduler + brokkr DAG + jera ledger)
                      │  gRPC (bearer + dwarves-workspace header)
   ┌──────────────────┼───────────────────────┐
 dwarves agent      dwarves agent           dwarves agent      ← your machines
 --group loki       --group odin            --group nuc
 caps=[gpu,12c]     caps=[32c]              caps=[6c]

Verdict: jera-multi-machine is the #1 dwarves build item and the biggest single lever — it's what turns dwarves from a single-box forge into a real CI/CD fleet, and (per the reuse-first law) it must be built into jera as the shared Agent/GrpcAgent seam, not bolted onto dwarves alone.