For development rules, see DEVELOPMENT.md
A strict, modern Rust project template for Mae-Technologies services. Focused on code quality, safety, security, and reliability.
- Nightly Rust toolchain with
rustfmt,clippy, andmiri(rust-toolchain.toml) - Strict Clippy rules —
unwrap_usedandexpect_useddenied via[lints.clippy]inCargo.toml(applies only to user-written code, not external macro expansions likeserde_json::json!) - Miri for detecting undefined behavior in tests
- cargo-deny for license compliance, vulnerability scanning, yanked crate blocking, and source restrictions
- ARC-based GitHub Actions CI (
ci.yml) — runs on PRs tomain/productionon self-hostedmae-runnernodes; three jobs: config read, integrity (smoke-test), and integration (full service stack) - Git pre-push hook — runs format, tests, coverage, Clippy, cargo-deny, and TruffleHog secret scan before every push
- Git pre-commit hook — checks for unsynced rust_template changes
sync_rust_template.sh— syncs template files into a target service repo; bumpsmaeto latest; removes deprecated files
Unwrap/expect enforcement is done via Cargo.toml [lints.clippy], not clippy.toml disallowed-methods:
[lints.clippy]
unwrap_used = "deny"
expect_used = "deny"disallowed-methods fires on external macro expansions (including serde_json::json!), so we use clippy::unwrap_used instead, which only fires on user-written code.
Test code is exempt via clippy.toml:
allow-unwrap-in-tests = true
allow-expect-in-tests = trueRuns on PRs targeting main or production using self-hosted mae-runner ARC nodes.
| Job | Purpose |
|---|---|
config |
Reads configuration/base.yaml + configuration/test.yaml and exports service credentials as job outputs |
integrity |
Runs scripts/smoke-test.sh (format, clippy, coverage, deny, TruffleHog) |
integration |
Spins up Postgres, Neo4j, RabbitMQ, Redis; runs scripts/int-test.sh |
Key config files:
.ci/ci_env.toml— test runner engine (nextest,cargo,miri,nothing), CLI flags, env vars, coverage thresholdconfiguration/base.yaml— base service configconfiguration/test.yaml— CI overrides applied on top ofbase.yaml
Services use a single-stage dev image (no cargo-chef pre-cook). The dev container:
- Installs
cargo-watchandsqlx-cli - Mounts source via Docker Compose Watch
- On start: runs
dev-boot.sh→cargo fetch→cargo watch→dev-run.sh(migrate +cargo run)
dev-run.sh handles migration failures gracefully — if migrations fail, the watcher stays alive and retries on the next file change.
Syncs template files into a target Rust service repo. Run from the target service root with RUST_TEMPLATE_DIR pointing at your local clone of this repo.
| Flag | Description |
|---|---|
--force / -f |
Overwrite existing config files, workflow, hooks, DEVELOPMENT.md, and configuration/ files |
--private NAME |
Generate a proprietary LICENSE file for NAME; accepts RUST_OWNER env var as fallback |
--name NAME |
MIT license for NAME; accepts RUST_OWNER env var as fallback |
--lib |
Library crate — skip Dockerfile.* sync |
--skip-mae-bump |
Skip bumping the mae dependency to latest |
--test / -t |
Skip pre-flight checks — useful for local testing |
- Config files —
clippy.toml,deny.toml,rust-toolchain.toml,rustfmt.toml,.gitignore - Workflow —
.github/workflows/ci.yml - Configuration —
configuration/base.yaml,configuration/test.yaml,configuration/dev.yaml .ci/files — all files under.ci/(e.g.,ci_env.toml)scripts/—smoke-test.sh,int-test.sh,dev-boot.sh,dev-run.sh- Pre-push hook —
.git-hooks/→.git/hooks/ - DEVELOPMENT.md — copied from template
[lints.clippy]— enforced in targetCargo.toml(idempotent)- LICENSE — generated from
--privateor--name .cargo/config.toml— setsgit-fetch-with-cli = true.rust_template_version— version stamp- README.md — prepends a
DEVELOPMENT.mdlink if not already present maedep bump — bumpsmaeto latest published version if present inCargo.toml
On every sync, the following deprecated files are deleted from the target service if present:
.github/workflows/cooked-crab.yaml.github/workflows/rust-integrity-guard.yaml.ci/ci_tests.sh.ci/ci_tests.env
cargo new my-service
cd my-service
export RUST_TEMPLATE_DIR=/path/to/rust_template
bash $RUST_TEMPLATE_DIR/sync_rust_template.sh --private "1000482371 ONTARIO CORPORATION"
git config core.hooksPath .git-hookscd /path/to/rust_template && git pull
cd /path/to/my-service
bash $RUST_TEMPLATE_DIR/sync_rust_template.sh --force --private "1000482371 ONTARIO CORPORATION"bash $RUST_TEMPLATE_DIR/sync_rust_template.sh --lib --private "1000482371 ONTARIO CORPORATION"