Contributing
Help is welcome with reproducible bug reports, focused fixes, tests, and clear documentation. For a new feature or a substantial change, discuss the direction in GitHub Discussions or Discord before investing in an implementation. Small, obvious fixes can go straight to a pull request.
Set up the repository
git clone https://github.com/aubepkg/aube
cd aube
mise install
mise run buildUse the Rust toolchain declared by the project and the tools pinned in mise.toml. mise run activates the Cargo build-cache wrapper. If you run Cargo directly, activate mise in your shell first.
The debug binary is target/debug/aube. BATS tests use that binary; release builds are for profiling and benchmarks.
Run the relevant checks
mise run test
mise run lint
mise run test:bats test/install.batsmise run lint runs the repository's hk checks, including formatting and Clippy. mise run lint-fix applies supported fixes. The equivalent core Cargo checks are:
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --checkBATS tests use the project's mise-managed Node and rush for parallel runs. Use mise run test:bats for the full shell suite. Supply specific .bats files for a focused run. The registry helper installs Verdaccio if it is unavailable.
Release validation also includes cargo deny --locked check advisories bans licenses sources, which covers RustSec advisories as well as license, ban, and source policy.
Work on documentation
mise run docs:dev
mise run docs:buildThe site lives under docs/; navigation and styles live in docs/.vitepress/. The build validates internal page links and social-preview metadata. Use node scripts/check-docs.mjs to check local Markdown links and built-site fragment targets after a docs build.
Some references are generated:
| Output | Edit this source |
|---|---|
docs/cli/*.md and nested command pages | Command help in crates/aube/src/; examples and navigation in scripts/patch-generated-cli-docs.mjs |
docs/settings/index.md | crates/aube-settings/settings.toml and its docs generator |
| Error-code data | crates/aube-codes/src/ |
| Benchmark charts and README ratios | benchmarks/results.json, regenerated by mise run bench:bump |
Run mise run render after changing generated reference sources. Keep command examples copyable, explain which file holds a setting, and describe current behavior separately from proposals. Historical release notes and vendored third-party documentation should retain their original content.
Prepare a pull request
Keep the scope focused and describe the problem, resulting behavior, and validation. CI must pass, and automated review comments must be addressed before maintainer review. Changes may be declined when they do not fit the project's scope; discussing substantial changes early reduces that risk.
Use Conventional Commits for commit messages and PR titles:
fix(install): preserve locked versions during repairdocs: clarify dependency build approvalsfeat(resolver): support a new dependency protocol
Start the description with a lowercase imperative verb. Keep subjects concise; PR titles determine release version bumps. Do not add tool branding or a PR number to the title. Open pull requests ready for review, and include the AI-assistance disclosure required by the repository instructions when applicable.
The offline Verdaccio test registry
The BATS suite does not talk to registry.npmjs.org. Everything it installs comes from a pre-seeded local Verdaccio instance under test/registry/.
Layout
test/registry/config.yaml— Verdaccio config. Nouplinksblock, noproxy:on thepackages['**']entry — local-only by design.test/registry/start.bash— sourced bytest/setup_suite.bash. Boots Verdaccio onlocalhost:4873before the suite, tears it down after.test/registry/storage/— Verdaccio's on-disk storage. Committed to git. Each subdirectory is an npm package: apackage.jsonpackument plus one.tgzper version the fixture needs. The.verdaccio-db.jsonindex that Verdaccio regenerates on startup is.gitignored.
Each BATS test writes registry=http://localhost:4873 into a per-test .npmrc (see test/test_helper/common_setup.bash), so aube picks up the fake registry via its normal NpmConfig loader without any special plumbing in the Rust code.
Adding a new package to the fixture set
Say a new test needs cowsay. Because Verdaccio is local-only, the fixture set has to contain every package (and every transitive dep) the test will install. The recipe:
Temporarily restore the
npmjsuplink intest/registry/config.yaml:yamlstorage: ./storage uplinks: npmjs: url: https://registry.npmjs.org/ cache: true packages: '**': access: $all publish: $all proxy: npmjsRun the test that exercises the new package. Verdaccio will proxy the request upstream on the first hit and save the tarball and packument into
test/registry/storage/<pkg>/. Transitive deps get pulled in the same way as the resolver walks the graph.bashcargo build ./test/bats/bin/bats test/your_new_test.batsRevert the uplink changes in
test/registry/config.yamlso it's back to local-only.Re-run the full suite offline to prove the fixture set is complete and nothing still reaches for the network:
bash./test/bats/bin/bats test/Commit the new files under
test/registry/storage/along with your test. Check the diff for surprises — Verdaccio sometimes fetches additional versions beyond what the test asked for; drop anything unneeded to keep the fixture set small.
Picking test packages
- Prefer tiny packages with few transitive deps. Every new package inflates the committed fixture set.
- For
aube dlx/exec/runtests, prefer packages with a stable, deterministic stdout (e.g.semver <version>echoes its input). Tests that rely on help output are brittle because clap flags and trailing args can swallow--help/--version. - If you need a package whose binary name differs from its package name (to exercise
aube dlx -p),whichshipsnode-whichand is only a few KB includingisexe.
Why no uplink in CI?
Keeping the fixture set committed means:
- CI runs are hermetic and don't flake on npmjs.org outages or rate limits.
- Test failures are reproducible on any checkout of a given commit.
- Offline development works without caveats.
The tradeoff is the ~8 MB of .tgz files under test/registry/storage/ and the manual seeding step above. For a package manager project that feels like the right tradeoff — we're exercising real tarball extraction and linking, so mock registries aren't an option.