Quick Start
Get your first release running in 5 minutes
1. Install anodizer
cargo install anodizer2. Generate a config
In your project root (where Cargo.toml lives):
anodizer init > .anodizer.yaml
This reads your Cargo.toml and generates a starter config with sensible defaults. init discovers your project_name, every [[bin]] target across the workspace, the GitHub owner/name from your origin remote, and a default archive name_template — so the generated config builds and releases without further edits. Anything it can derive is left out of the file as an implicit default; you only write config to override a default or to add a publisher (a tap, a registry) it can't infer.
3. Validate the config
anodizer check config
This validates your .anodizer.yaml against the schema — checks for missing fields, invalid target triples, dependency cycles, and more.
Anodizer rejects unknown config keys, so a typo like dockrs_v2: or
fromats: fails fast at load time instead of being silently ignored. Migrating
from GoReleaser? Paste your config in as-is — anodizer accepts the GoReleaser
field names disable, docker_v2, layouts, and name_template (snapshot) as
back-compat aliases for their canonical anodizer spellings (skip,
dockers_v2, layout, version_template). disable and name_template are
deprecation-warned at load so you can migrate at your own pace; docker_v2 and
layouts are accepted silently.
4. Do a dry run
anodizer release --dry-run
This runs the full pipeline without any side effects — no GitHub release created, no packages published, no images pushed. --dry-run plans and renders every stage (templates, manifest contents, the publisher PRs it would open) but skips the real build and every network write, so it's fast and offline. Use it to confirm your config resolves before spending a real build.
5. Do a snapshot build
anodizer release --snapshot
Unlike --dry-run, a snapshot performs the real build, archive, checksum, and signing stages — it just skips every stage that writes to a remote (GitHub release, crates.io, taps, registries, images). It also derives a snapshot version (the default appends -SNAPSHOT; the template can fold in the commit hash) instead of requiring a release tag, so you can snapshot an untagged working tree. Use it to test that your binaries compile for every target and that archive formats and checksums come out right. Both --dry-run and --snapshot run the emission cross-check — each publisher's would-be output (a binstall download URL, a Nix asset map) is rendered in-memory and compared against the run's registered artifacts, catching a class of "release succeeds but is silently wrong" bugs locally. The check is only meaningful under --snapshot, where real built archives back the comparison; under --dry-run the artifacts are placeholder registrations, so it confirms the emission renders but not that it points at real bytes.
6. Release for real
export GITHUB_TOKEN="ghp_..."
anodizer release --crate myapp
This runs the full pipeline: build, archive, checksum, changelog, GitHub release with asset uploads, and any configured publishers. Each publisher reads its own credential from the environment — GITHUB_TOKEN (needs contents:write for the release, plus pull_request:write only if a Homebrew cask or other tap is set to the PR workflow), CARGO_REGISTRY_TOKEN for crates.io, and so on. A homebrew_casks entry commits the cask directly to its tap repo on every release; set pull_request.enabled under the entry's repository to open a PR per release instead, so review and merge happen on your terms.
Tap repos must already exist. If you configure
homebrew_casks(or a Scoop bucket, AUR repo, etc.), create the target repo — e.g. an empty<owner>/homebrew-tap— before your first release; anodizer writes into it but never creates it. The release token needscontents:writefor the default direct push, pluspull_request:writeonly if the tap uses the PR workflow (pull_request.enabled).
Preflight checks run before any publishing.
--strictpromotes preflight warnings — an under-scoped token, or a feature you configured that would silently skip — into hard errors, so a misconfigured CI run fails at the top instead of half-publishing.--strict-preflightis a back-compat alias for--strict; both also block when a publisher's remote state can't be determined (Unknown).
What next?
- Configuration Reference — all config fields explained
- Template Reference — template variables and filters
- GitHub Actions — automate releases in CI