Anodizer
A Rust-native release automation tool. The same declarative, config-driven release pipeline that GoReleaser provides for Go — built for Rust.
Anodizer reads a declarative config file and executes a full release pipeline: build, archive, checksum, changelog, sign, release, publish, and announce — all from a single anodizer release command.
Written by Claude; maintained by us.
See What works (with proof) for a per-feature status — every "live" claim links to a real published artifact you can verify yourself.
Features
Build
- Cross-platform builds via
cargo-zigbuild,cross, or nativecargo build - Per-build hooks (pre/post), environment variables, feature flags, and target overrides
- UPX binary compression with per-target filtering
- Workspace support with per-crate independent release cadences
Package
- Archives in tar.gz, tar.xz, tar.zst, zip, gz, or raw binary format with OS-specific overrides
- Linux packages (.deb, .rpm, .apk, .archlinux, .ipk) via nFPM with full lifecycle scripts
- Snapcraft snaps with prime-dir architecture
- macOS DMG disk images and PKG installers
- Windows MSI and NSIS installers
- Flatpak bundles
- Makeself self-extracting archives
- Source RPMs (.src.rpm)
- Source archives with file filtering
- SBOM generation (CycloneDX/SPDX)
- Checksums with SHA-256, SHA-512, SHA3, BLAKE2b, BLAKE2s, BLAKE3, CRC32, MD5, and more
Sign
- GPG and cosign signing for binaries, archives, checksums, Docker images, and SBOMs
- Multiple independent signing configurations
- Conditional signing via template expressions
Publish
- GitHub/GitLab/Gitea Releases with asset uploads, draft/prerelease detection, header/footer templates
- crates.io with dependency-aware ordering and index polling
- Homebrew formula and cask generation
- Scoop manifest generation
- Chocolatey package generation
- Winget manifest generation
- AUR PKGBUILD and .SRCINFO generation
- Krew plugin manifest generation
- Nix derivation generation
- MCP registry server-manifest publishing (Model Context Protocol)
- npm package publishing
- Docker multi-arch images via
docker buildx - Blob storage uploads (S3, GCS, Azure)
- Artifactory, Cloudsmith, Fury, Docker Hub
- Custom publisher commands
Announce
- Discord, Slack, Telegram, Teams, Mattermost
- Email, Reddit, Twitter/X, Mastodon, Bluesky, LinkedIn
- OpenCollective, Discourse
- Generic webhooks with custom headers and templates
Advanced
- Tera templates (Jinja2-like) with GoReleaser-compatible
{{ .Field }}syntax - Nightly builds with date-based versioning
- Config includes for shared configuration
- Split/merge CI for fan-out parallel builds
- Monorepo support with independent workspaces
- Auto-tagging from commit message directives
- Reproducible builds with
mod_timestampandbuilds_info - JSON Schema for editor autocomplete and validation
Installation
Homebrew (macOS/Linux)
Cargo
From source
Quick Start
# Generate a starter config from your Cargo workspace
# Validate your config
# Check that required tools are available
# Build a snapshot (no publishing)
# Dry run (full pipeline, no side effects)
# Create a tag and release
For CI-based releases, set GITHUB_TOKEN (or ANODIZER_GITHUB_TOKEN) as a secret — the release pipeline picks it up automatically.
Configuration
Anodizer uses .anodizer.yaml (or .anodizer.toml) in your project root. Add a schema comment for editor autocomplete:
# yaml-language-server: $schema=https://tj-smith47.github.io/anodizer/schema.json
project_name: myapp
defaults:
targets:
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
- x86_64-apple-darwin
- aarch64-apple-darwin
- x86_64-pc-windows-msvc
cross: auto
crates:
- name: myapp
path: "."
tag_template: "v{{ Version }}"
builds:
- binary: myapp
archives:
- name_template: "{{ ProjectName }}-{{ Version }}-{{ Os }}-{{ Arch }}"
files:
release:
github:
owner: myorg
name: myapp
publish:
crates:
enabled: true
homebrew:
tap:
owner: myorg
name: homebrew-tap
See the full configuration reference and the template reference for all available fields, variables, and filters.
GitHub Actions
name: Release
on:
push:
tags:
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- name: Install anodizer
run: cargo install anodizer
- name: Release
run: anodizer release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CLI Reference
Commands
anodizer release Full release pipeline
anodizer build Build binaries only (snapshot mode)
anodizer check Validate configuration
anodizer init Generate starter config
anodizer changelog Generate changelog only
anodizer completion <shell> Shell completions (bash/zsh/fish/powershell)
anodizer healthcheck Check external tool availability
anodizer man Generate man pages
anodizer jsonschema Output JSON Schema for .anodizer.yaml
anodizer tag Auto-tag from commit directives
anodizer publish Run publish stages from completed dist/
anodizer announce Run announce stage from completed dist/
anodizer continue Merge split build artifacts and resume pipeline
Global Flags
-f, --config <path> Path to config file (overrides auto-detection)
--verbose Enable verbose output
--debug Enable debug output
-q, --quiet Suppress non-error output
Release Flags
--crate <name> Release a specific crate (repeatable)
--all Release all crates with unreleased changes
--force Force release even without changes
--snapshot Build without publishing
--nightly Nightly release with date-based version
--dry-run Full pipeline, no side effects
--clean Remove dist/ directory first
--skip=<stages> Skip stages (comma-separated)
--token <token> GitHub token (overrides env vars)
--timeout <duration> Pipeline timeout (default: 60m)
-p, --parallelism <n> Max parallel build jobs (default: CPU count)
--auto-snapshot Auto-enable snapshot if repo is dirty
--single-target Build only for the host target triple
--split Fan-out: build only, output artifacts JSON
--merge Fan-in: merge split artifacts, run post-build
--draft Set the release as a draft
--release-notes <path> Custom release notes file
--release-header <path> Custom release header file
--release-footer <path> Custom release footer file
--workspace <name> Release a specific monorepo workspace
--fail-fast Abort on first publish error
Documentation
Full documentation is available at tj-smith47.github.io/anodizer.
License
MIT