Skip to content

Latest commit

 

History

History
80 lines (60 loc) · 4.37 KB

File metadata and controls

80 lines (60 loc) · 4.37 KB

Contributing to multicalc

5-minute quickstart

  1. Fork and clone.
  2. cargo test
  3. cargo clippy --all-targets — the lint wall (no unwrap/expect/panic/unsafe) is CI-enforced, so run it before pushing.
  4. cargo fmt.

That's it. You do not need QEMU or bare-metal toolchains for most contributions — CI runs the multi-target embedded matrix on your PR for you. If you want the bare-metal targets locally anyway, the setup lives in ci/README.md (optional).

Workflow

  • Fork, branch in your fork, PR against main. One focused change per PR.
  • Every behavior-facing change adds a line under ## [Unreleased] in CHANGELOG.md (grouped Added/Changed/Fixed/Removed), in the same PR.
  • CI must be green: host tests (x86_64 + aarch64), clippy, the four bare-metal QEMU smoke runs, and the flash/stack budget gates. If a budget gate trips, see the raise protocol in ci/README.md — never raise tolerance_pct.

Picking something to work on

  • good first issue — scoped and mentored; each states what to do, where in the code, and how to test it. Comment on the issue to claim it so nobody double-works.
  • help wanted — a PR here will be accepted if it meets the bar below.

What makes a PR easy to merge

  • No panics on library paths — fallible ops return typed per-module errors (LinalgError, DiffError, IntegrateError, SolveError), never unwrap. Clippy enforces this.
  • Stay generic over the scalar — inside generic code, never call an f64-only function (it silently drops the autodiff payload). Use the Numeric trait surface.
  • Tests: f64 assertions may use golden values; f32 correctness is asserted via mathematical identities (e.g. reconstruction, round-trips), not goldens.
  • Docs: public APIs get a doc example; behavior notes (NaN policy, iteration budgets) live on the item.

Where does a check go?

The workspace has several test and demo layers. Each has one job; adding a check means picking the layer that matches and not duplicating another's.

Layer Purpose Must not
doctests one minimal runnable demo per public item become the correctness suite
src/**/test.rs inline white-box tests of pub(crate) internals only (LU/lmpar) test public API
tests/suite/ the correctness suite: public API, edge cases, proptests re-declare problems/helpers inline
demos/examples/basics/ copy-pasteable, headless, terminating demos; multicalc-only imports exit 0 without ≥1 sanity assert!; touch a sink
demos/examples/showcase/ live Rerun demos; measured numbers only panic on edge cases (errors render as demo states); hardcode a perf claim
tools/qa cross-implementation goldens (numpy/mpmath/MINPACK); .md accuracy tables generated from the fixtures duplicate self-consistency tests; hand-edit the generated tables
tools/embedded-smoke on-target FP-path + stack/text budgets; goldens only via generated fixtures.rs hand-write golden values

Shared problem definitions and tolerance helpers live in tools/testkit, so a problem is declared once and reused across tests/suite/, the QA crate, and embedded-smoke.

The QA fixtures are regenerated with tools/qa/gen/generate.sh, which needs Python 3.12. See Regeneration for what it sets up and when to rebuild the lock file.

Releasing

Releases are automated from main:

  1. When that PR merges, the release workflow publishes to crates.io and creates a vX.Y.Z tag and GitHub release whose notes come from the matching changelog section.
  2. The Cargo.toml version and the top dated changelog heading must match; a bump with no changelog entry fails the release.

Before step 1, build the docs the way docs.rs will and skim the result — docs.rs only rebuilds on a publish, so a broken page stays broken until the next release:

RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc -p multicalc --no-deps --all-features

The --cfg docsrs flag is nightly-only and turns on the "Available on crate feature alloc only" badges. Check that the alloc-gated items (ParticleFilter, Jacobian::get_on_heap) are present and badged.

Thank you for all the contributions!