# Developing Run `prek install` once; it wires both the pre-commit and the commit-msg stage, and until someone runs it a commit here is checked by nobody. The pre-commit stage runs `cargo fmt`, `cargo clippy` and `cargo doc` across the whole workspace, so against a cold `target/` it is minutes, and `cargo doc` is wired to `docs/*.md` as well as to the Rust sources, so a documentation-only commit pays for it too. Against a warm one it is seconds. Keeping it seconds is what `scripts/lint.sh` is for: lint by hand with that rather than a bare `cargo clippy`. Cargo caches a check against the flags it was given, so the two are separate cached results over the same source, and alternating between them re-checks every crate in the workspace each way. The `file size` hook counts the lines in each staged file: over 5000 it refuses the commit, and over 2000 it prints the file and lets the commit through. Both numbers are at the top of `scripts/check-file-size.py`. Two hooks call a tool rustup does not ship, so install each once: `cargo install cargo-deny` and `cargo install --locked --features cli cargo-about`. The first judges the dependency graph against `deny.toml`; the second writes `THIRD-PARTY-NOTICES.txt`, the licence text the image carries beside the binary. A dependency change that moves the graph fails the `notices` hook until `scripts/gen-notices.sh` is run and its result staged. The commit-msg stage checks that the subject is a Conventional Commit and stamps the `Change-Id` trailer that stacked pull requests are matched by; that trailer is what a `--no-verify` commit gives up along with the checks, and a commit made without one has to be rewritten to get one. The test suite runs from `scripts/ci.sh []`: it runs the hooks over every file rather than a staged set, replays the commit-msg stage over every commit in `..HEAD`, checks that brand images are up to date via `scripts/build-brand.sh --check`, and then runs `cargo test --workspace --all-features --no-fail-fast`. A branch is checked when a person runs it. ## The runner `.tangled/workflows/ci.yml` runs `scripts/ci.sh` on a push to `main` and on each pull request round. Tangled runs pipelines on a spindle, and a spindle is self-hosted: it is a service somebody runs, registered to their own account and attached to this repository from its settings page. Until one is attached to this repository, the workflow is a file and a person runs the script. The workflow carries three things a laptop already has: `npm ci` in both `site/` and `policy-site/`, because `scripts/build-site.sh` refuses without `site/node_modules`; `wasm-bindgen-cli` at the version `Cargo.lock` resolved, because it and the `wasm-bindgen` crate talk a private ABI to each other; and `cargo-about` at the version the workflow names, which has to be the one that last wrote `THIRD-PARTY-NOTICES.txt`, because another version writes different notices and the `notices` hook fails. Its compiler is the one `rust-toolchain.toml` pins, as a laptop's is. It also raises `CARGO_BUILD_JOBS`: `.cargo/config.toml` holds cargo to two jobs for a machine that is also running an editor and several agents, and a runner is that machine's opposite. A spindle ends a workflow after `SPINDLE_NIXERY_PIPELINES_WORKFLOW_TIMEOUT`, five minutes by default, and this one runs far longer; whoever runs the spindle sets it.