Development Workflow
This page is the practical loop: build, run, test, and the conventions your PR
has to satisfy before it merges. Commands here are the same ones CI runs (see
.github/workflows/ci-checks.yml).
Prerequisites
Section titled “Prerequisites”The toolchain is pinned in rust-toolchain.toml (stable Rust). To build and run
example apps you also need the WASM target:
rustup target add wasm32-unknown-unknown# Build the whole workspace (debug)cargo build
# Release buildcargo build --release
# Typecheck without producing artifactscargo check --workspaceBuilding the example WASM apps is a separate step (apps compile to
wasm32-unknown-unknown):
# Build one appcargo build -p kv-store --target wasm32-unknown-unknown --release
# Build all example apps./scripts/build-all-apps.shRun local nodes
Section titled “Run local nodes”merod is the node daemon; each node is initialized once, then run. To bring up
two nodes that talk to each other:
-
Initialize and run the first node:
Terminal window merod --node node1 init --server-port 2428 --swarm-port 2528merod --node node1 run -
Initialize the second node and point it at the first’s swarm address:
Terminal window merod --node node2 init --server-port 2429 --swarm-port 2529merod --node node2 config --swarm-addrs /ip4/127.0.0.1/tcp/2528merod --node node2 run -
Drive nodes from the CLI with
meroctl, or turn up logging withRUST_LOG:Terminal window RUST_LOG=debug merod --node node1 run
# Run the full workspace test suitecargo test
# CI runs with output showncargo test -- --nocaptureThe pre-PR gate
Section titled “The pre-PR gate”These are the checks CI enforces; run them before pushing.
# Formatting (must pass)cargo fmt --check
# Lint — the no-warnings gatecargo clippy --workspace --all-targets --features calimero-storage/testing -- -D warnings
# Testscargo test
# Dependency policy — only needed if you changed dependenciescargo deny check licenses sourcesCommit & PR conventions
Section titled “Commit & PR conventions”Commits follow a structured, changelog-friendly format:
<type>(<scope>): <short summary>The <type> is mandatory and must be one of build, ci, docs, feat,
fix, perf, refactor, or test. The <scope> is optional and names the
affected area. The summary uses imperative, present tense, no leading
capital, and no trailing period — e.g. fix(sync): drop stale handshake on timeout.
For pull requests:
- The project uses a fork-and-pull workflow; base your PR on the
masterbranch. - A PR should focus on either functionality or style, not both.
- PRs must follow the template, with Description, Test plan, and Documentation update sections, and link any related issue.
- Maintainers squash-and-merge approved PRs; resolve each review conversation as you address it.
The repo’s own Definition of Done before opening a PR: cargo fmt --check
passes, cargo clippy -- -D warnings passes, cargo test passes,
cargo deny check licenses sources passes if you touched dependencies, and
relevant docs (README, AGENTS.md, crate docs) are updated.
Style rules
Section titled “Style rules”The full guide is in STYLE.md; the rules that trip people up most:
- No
mod.rs. Export submodules from a file named after the module instead.crates/meroctl/src/cli/app.rsdeclaresmod get;and the file lives atcrates/meroctl/src/cli/app/get.rs. (Rare, documented exceptions exist, e.g.crates/node/src/sync/mod.rs.) - Import organization follows the
StdExternalCratepattern: standard library, then external crates, then local crate/parent module, then local module declarations. Use module-granularity imports — don’t merge imports from the same crate into one nesteduse. - Error handling leans on
eyre(use eyre::Result as EyreResult;). Avoid.unwrap()/.expect(); prefer?and.map_err(). If an unwrap is truly safe, justify it with a// SAFETY:comment. - No dead code. Everything in a PR must be used — no unused functions,
imports, or commented-out blocks. Use
#[allow(dead_code)]only with a comment explaining why. - Keep
Cargo.tomldependencies sorted alphabetically; prefer imports over fully-qualified paths; follow standard Rust naming conventions.
Where design docs live
Section titled “Where design docs live”| Location | What’s there |
|---|---|
docs/adr/ | Architecture Decision Records (numbered, e.g. 0001-shared-storage-concurrent-rotation.md). |
docs/design/ | Design documents for larger efforts (e.g. the unified-causal-log cutover/flip plans). |
docs/RELEASE.md | Versioning and release process (versions are managed by cargo-workspaces). |
AGENTS.md (root + per-package) | Quick orientation and conventions for each area of the tree; a good first read for any crate. |
architecture/ | Generated per-crate-group reference pages describing the actor model and crate internals. |