anodizer
A Rust-native release pipeline — GoReleaser parity, signed and deterministic by default.
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. The same declarative, config-driven release pipeline that GoReleaser provides for Go — built for Rust.
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)
# Auto-tag from commit directives
# (Conventional Commits: feat: → minor, fix: → patch, BREAKING CHANGE: → major)
# Or force a specific tag value:
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:
cargo:
homebrew:
repository:
owner: myorg
name: homebrew-tap
See the full configuration reference and the template reference for all available fields, variables, and filters.
Real-world adoption: cfgd
cfgd — declarative, GitOps-style machine configuration management — is anodizer's first real-world adopter and dogfoods every shipped publisher. It's a 4-crate workspace (shared lib + CLI + Kubernetes operator + CSI driver) that ships to crates.io (dependency-aware ordering), GitHub Releases, Homebrew, Scoop, Chocolatey, Winget, the Snap Store, Krew, GHCR, and via cargo binstall — all from one .anodizer.yaml and one tag push.
A condensed slice of cfgd's .anodizer.yaml:
workspaces:
- name: cfgd-core
crates:
- name: cfgd-core
tag_template: "core-v{{ Version }}"
version_sync:
- name: cfgd
crates:
- name: cfgd
depends_on:
version_sync:
universal_binaries:
- name_template: "{{ ProjectName }}"
replace: false
binstall:
enabled: true
pkg_url: "https://github.com/tj-smith47/cfgd/releases/download/v{{ Version }}/cfgd-{{ Version }}-{ target }.tar.gz"
pkg_fmt: tgz
# ... cfgd-operator, cfgd-csi
Every cell of What works (with proof) links to a real published cfgd artifact for the feature in question — that's the verification surface.
GitHub Actions
Anodizer ships a first-party action, tj-smith47/anodizer-action, which is what this repo dogfoods in its own release.yml:
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: Release
uses: tj-smith47/anodizer-action@v1
with:
version: latest
auto-install: true # auto-detect nfpm/makeself/snapcraft/cosign/etc from .anodizer.yaml
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
For split/merge fan-out, GPG key import, registry login, and per-platform variants, see anodizer-action and the live .github/workflows/release.yml in this repo.
CLI Reference
anodizer release Full release pipeline (--snapshot, --dry-run, --split/--merge, --publish-only, --rollback-only)
anodizer tag Auto-tag from commit directives
anodizer check Validate configuration + run determinism harness
anodizer init Generate starter .anodizer.yaml
anodizer healthcheck Probe external tools (nfpm, cosign, ...)
Full reference: anodizer --help or the docs site.
Documentation
Full documentation is available at tj-smith47.github.io/anodizer.
Operator guides:
- Release resilience guide - three-group publisher dispatch, Submitter gate, rollback, replay-from-run
- Determinism guide - byte-stability contract,
anodizer check determinismharness, runtime allow-list
License
MIT