anodizer 0.2.0

A Rust-native release automation tool inspired by GoReleaser
Documentation

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 native cargo 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_timestamp and builds_info
  • JSON Schema for editor autocomplete and validation

Installation

Homebrew (macOS/Linux)

brew install tj-smith47/tap/anodizer

Cargo

cargo install anodizer

From source

git clone https://github.com/tj-smith47/anodizer.git
cd anodizer
cargo install --path crates/cli

Quick Start

# Generate a starter config from your Cargo workspace
anodizer init > .anodizer.yaml

# Validate your config
anodizer check

# Check that required tools are available
anodizer healthcheck

# Build a snapshot (no publishing)
anodizer release --snapshot

# Dry run (full pipeline, no side effects)
anodizer release --dry-run

# Create a tag and release
git tag -a v0.1.0 -m "v0.1.0"
git push origin v0.1.0

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: [LICENSE, README.md]
    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: ["v*"]

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