Skip to content

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).

The toolchain is pinned in rust-toolchain.toml (stable Rust). To build and run example apps you also need the WASM target:

Terminal window
rustup target add wasm32-unknown-unknown
Terminal window
# Build the whole workspace (debug)
cargo build
# Release build
cargo build --release
# Typecheck without producing artifacts
cargo check --workspace

Building the example WASM apps is a separate step (apps compile to wasm32-unknown-unknown):

Terminal window
# Build one app
cargo build -p kv-store --target wasm32-unknown-unknown --release
# Build all example apps
./scripts/build-all-apps.sh

merod is the node daemon; each node is initialized once, then run. To bring up two nodes that talk to each other:

  1. Initialize and run the first node:

    Terminal window
    merod --node node1 init --server-port 2428 --swarm-port 2528
    merod --node node1 run
  2. Initialize the second node and point it at the first’s swarm address:

    Terminal window
    merod --node node2 init --server-port 2429 --swarm-port 2529
    merod --node node2 config --swarm-addrs /ip4/127.0.0.1/tcp/2528
    merod --node node2 run
  3. Drive nodes from the CLI with meroctl, or turn up logging with RUST_LOG:

    Terminal window
    RUST_LOG=debug merod --node node1 run
Terminal window
# Run the full workspace test suite
cargo test
# CI runs with output shown
cargo test -- --nocapture

These are the checks CI enforces; run them before pushing.

Terminal window
# Formatting (must pass)
cargo fmt --check
# Lint — the no-warnings gate
cargo clippy --workspace --all-targets --features calimero-storage/testing -- -D warnings
# Tests
cargo test
# Dependency policy — only needed if you changed dependencies
cargo deny check licenses sources

Commits follow a structured, changelog-friendly format:

Terminal window
<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 master branch.
  • 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.

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.rs declares mod get; and the file lives at crates/meroctl/src/cli/app/get.rs. (Rare, documented exceptions exist, e.g. crates/node/src/sync/mod.rs.)
  • Import organization follows the StdExternalCrate pattern: 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 nested use.
  • 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.toml dependencies sorted alphabetically; prefer imports over fully-qualified paths; follow standard Rust naming conventions.
LocationWhat’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.mdVersioning 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.