Skip to main content

anodizer.yml config

Top-level anodizer.yml keys, Tera template helpers, lifecycle hooks, and monorepo configuration.

anodizer.yml config

Top-level configuration keys and the Tera helpers available inside any template string. Tera syntax is GoReleaser-compatible.

Live configuration

Top of cfgd/.anodizer.yaml (snapshot 2026-05-24) — every top-level / monorepo / git key in the tables below is wired here.

version: 2
project_name: cfgd
dist: ./dist
report_sizes: true

env:
  - REGISTRY=ghcr.io
  - RELEASE_TYPE=stable

variables:
  repo_url: "https://github.com/tj-smith47/cfgd"
  description: "Declarative, GitOps-style machine configuration management"

git:
  tag_sort: "-version:refname"
  ignore_tags: ["nightly"]
  ignore_tag_prefixes: ["draft-"]
  prerelease_suffix: "-"

tag:
  default_bump: none
  branch_history: full
  tag_prefix: "v"
  release_branches: [master]
  initial_version: "0.3.5"

metadata:
  description: "Declarative, GitOps-style machine configuration management"
  homepage: "https://github.com/tj-smith47/cfgd"
  license: MIT
  maintainers: ["TJ Smith"]
  mod_timestamp: "{{ CommitTimestamp }}"
  full_description: { from_file: README.md }
  commit_author: { name: TJ Smith, email: tj@jarvispro.io }

# 4 workspace entries — independent release cadences, dep-aware ordering.
workspaces:
  - { name: cfgd-core,     crates: [{ name: cfgd-core,     tag_template: "core-v{{ Version }}",     ... }] }
  - { name: cfgd,          crates: [{ name: cfgd,          tag_template: "v{{ Version }}",          depends_on: [cfgd-core], ... }] }
  - { name: cfgd-operator, crates: [{ name: cfgd-operator, tag_template: "operator-v{{ Version }}", depends_on: [cfgd-core], ... }] }
  - { name: cfgd-csi,      crates: [{ name: cfgd-csi,      tag_template: "csi-v{{ Version }}",      depends_on: [cfgd-core], ... }] }

partial:
  by: os

Top-level config

KeyStatusNotes
project_name✅ Verifiedanodizer .anodizer.yaml (project_name: anodizer)
dist✅ Verifiedanodizer .anodizer.yaml (dist: ./dist)
env✅ Verifiedanodizer .anodizer.yaml (env: - RELEASE_TYPE=stable)
env_files✅ Verifiedcrates/core/src/config/mod.rs (env_files config field)
variables✅ Verifiedcfgd .anodizer.yaml (variables.repo_url + .description)
template_files[]✅ Verifiedinstall.sh (rendered + attached on every cfgd release)
includes[].from_file✅ Verifiedcrates/core/src/config/mod.rs (IncludeSpec, parsed from includes:)
includes[].from_url🤝 Help wantedNo live config pulls a remote include
before✅ Verifiedcfgd .anodizer.yaml (before.hooks runs cargo fmt --check, clippy, test)
after✅ Verifiedcfgd .anodizer.yaml (after.hooks echo)
build.hooks.pre✅ Verifiedcfgd .anodizer.yaml (archive hooks.before)
build.hooks.post✅ Verifiedcfgd .anodizer.yaml (archive hooks.after)
snapshot.name_template✅ Verifiedanodizer .anodizer.yaml (snapshot.version_template)
--auto-snapshot✅ Verifiedanodizer ci.yml (snapshot build on every master push)
nightly.*✅ Verifiedcfgd .anodizer.yaml (nightly: {name_template: "cfgd-nightly", tag_name: nightly}) + cfgd nightly.yml (fired by cron: '0 4 * * *')
metadata.homepage✅ Verifiedcfgd .anodizer.yaml (metadata.homepage: https://github.com/tj-smith47/cfgd)
metadata.license✅ Verifiedcfgd .anodizer.yaml (metadata.license: MIT)
metadata.description✅ Verifiedcfgd .anodizer.yaml (metadata.description)
metadata.maintainers✅ Verifiedcfgd .anodizer.yaml (metadata.maintainers)
metadata.mod_timestamp✅ Verifiedanodizer .anodizer.yaml (metadata.mod_timestamp: "{{ CommitTimestamp }}"; applied as mtime of dist/metadata.json and dist/artifacts.json)
report_sizes✅ Verifiedanodizer .anodizer.yaml (report_sizes: true; prints per-artifact and total sizes in the release summary)

Templates

Tera engine, GoReleaser-compatible syntax. Every template string in the config is rendered.

HelperStatusNotes
{{ .Field }}✅ Verifiedcrates/core/src/template/vars.rs (every {{ .Project }} / .Version / .Tag / .Os / .Arch binding)
{{ .Var.* }}✅ Verifiedcfgd .anodizer.yaml ({{ Var.repo_url }} + {{ Var.description }})
{{ .PrefixedTag }}✅ Verifiedcrates/core/src/template/vars.rs (PrefixedTag binding)
{{ .Artifacts }}✅ Verifiedcfgd .anodizer.yaml ({{ .Artifacts }} inside docker_manifests.image_templates)
{{ .Metadata }}✅ Verifiedcrates/core/src/template/vars.rs (Metadata binding)
{{ .IsMerging }}✅ Verifiedcrates/core/src/template/vars.rs (IsMerging binding)
{{ .IsRelease }}✅ Verifiedcrates/core/src/template/vars.rs (IsRelease binding)
String / path / version / env / filter helpers✅ Verifiedcrates/core/src/template/base_tera.rs (tolower, toupper, dir, base, abs, etc.)
sha*, blake2*, blake3, crc32, md5✅ Verifiedcrates/core/src/template/base_tera.rs (register_hash_fn! macro)
readFile, mustReadFile✅ Verifiedcrates/core/src/template/base_tera.rs (readFile / mustReadFile registrations)
time, .Now.Format✅ Verifiedcrates/core/src/template/base_tera.rs (time function + Now binding)
mdv2escape✅ Verifiedcrates/core/src/template/base_tera.rs (mdv2escape filter)
urlPathEscape✅ Verifiedcrates/core/src/template/base_tera.rs (urlPathEscape filter)
in✅ Verifiedcrates/core/src/template/base_tera.rs (in filter)
reReplaceAll✅ Verifiedcrates/core/src/template/base_tera.rs (reReplaceAll filter)

Monorepo

KeyStatusNotes
monorepo.tag_prefix✅ Verifiedcfgd .anodizer.yaml (tag_template: core-v{{ Version }} / v{{ Version }} / operator-v / csi-v)
monorepo.dir✅ Verifiedcfgd .anodizer.yaml (path: crates/cfgd-core, crates/cfgd, crates/cfgd-operator, crates/cfgd-csi)
cargo_workspace detection✅ Verifiedcfgd .anodizer.yaml (4 workspaces: cfgd-core, cfgd, cfgd-operator, cfgd-csi)
depends_on✅ Verifiedcfgd .anodizer.yaml (depends_on: [cfgd-core] on the three downstream crates)

Publisher resilience

KeyStatusNotes
publish.on_error⏳ Pendinganodizer .anodizer.yaml (defaults.publish.on_error runs a cmd per failed publisher before rollback; failure context arrives as ANODIZER_PUBLISHER/ANODIZER_ERROR/ANODIZER_VERSION/ANODIZER_TAG/ANODIZER_GROUP/ANODIZER_REQUIRED/ANODIZER_ROLLED_BACK env vars on the hook process — read these instead of interpolating untrusted error text into the shell string — with matching template vars for trusted values). Workspace-wide; per-crate entries append before defaults. Awaits a real failure to prove live
defaults.publish.cargo.retain_on_rollback⏳ Pendinganodizer .anodizer.yaml (retain_on_rollback: true under defaults.publish.cargo — crates.io publishes are permanent; retain even if a downstream publisher rolls back)
schemastore.retain_on_rollback / mcp.retain_on_rollback⏳ Pendinganodizer .anodizer.yaml (retain_on_rollback: true on the top-level schemastore and mcp keys — external catalogs; retain even if downstream publishers roll back)

Tag configuration

KeyStatusNotes
tag.default_bump✅ Verifiedanodizer .anodizer.yaml (default_bump: none — chore/docs/ci-only ranges produce no release)
tag.bump_minor_pre_major✅ Verifiedanodizer .anodizer.yaml (bump_minor_pre_major: true — breaking changes stay in 0.x until 1.0 is deliberate)
tag.tag_prefix✅ Verifiedcfgd .anodizer.yaml (tag_prefix: "v")
tag.release_branches✅ Verifiedanodizer .anodizer.yaml (release_branches: [main, master])
tag.initial_version✅ Verifiedcfgd .anodizer.yaml (initial_version: "0.3.5")
git.tag_sort✅ Verifiedanodizer .anodizer.yaml (tag_sort: smartsemver)
git.ignore_tag_prefixes✅ Verifiedanodizer .anodizer.yaml (ignore_tag_prefixes: ["draft-"])
git.prerelease_suffix✅ Verifiedanodizer .anodizer.yaml + cfgd .anodizer.yaml (prerelease_suffix: "-" — strips trailing pre-release suffixes from version strings)
git.ignore_tags✅ Verifiedanodizer .anodizer.yaml + cfgd .anodizer.yaml (ignore_tags: ["nightly"] — excludes transient tags from version resolution)
version_files⏳ Pendingcfgd .anodizer.yaml (version_files: [docs/installation.md, chart/cfgd/Chart.yaml]; version string rewritten in-place at tag time). Wired in config; awaits next cfgd release for live proof

Defaults

KeyStatusNotes
defaults.targets✅ Verifiedanodizer .anodizer.yaml (6 targets: linux x86_64/aarch64, macOS x86_64/aarch64, Windows x86_64/aarch64)
defaults.cross✅ Verifiedanodizer .anodizer.yaml (cross: auto)
defaults.builds.flags✅ Verifiedanodizer .anodizer.yaml (flags: [--release])
defaults.archives.formats✅ Verifiedanodizer .anodizer.yaml (formats: [tar.gz], format_overrides: windows→zip)
defaults.archives.hooks✅ Verifiedanodizer .anodizer.yaml (hooks.before + hooks.after with Tera vars)
defaults.checksum.algorithm✅ Verifiedanodizer .anodizer.yaml (algorithm: sha256)
defaults.publish.cargo✅ Verifiedanodizer .anodizer.yaml (cargo: {} — presence opts every crate into crates.io)
defaults.publish.on_error⏳ Pendinganodizer .anodizer.yaml (on_error: [{cmd: "echo ..."}])
partial.by✅ Verifiedanodizer .anodizer.yaml + cfgd .anodizer.yaml (partial.by: os — shards the CI matrix by OS; enables the determinism fan-out build strategy)

Changelog

KeyStatusNotes
changelog.use✅ Verifiedanodizer .anodizer.yaml (use: git)
changelog.title✅ Verifiedanodizer .anodizer.yaml (title: "Changelog")
changelog.header✅ Verifiedanodizer .anodizer.yaml (header: "# Changelog for {{ ProjectName }}")
changelog.footer✅ Verifiedanodizer .anodizer.yaml (footer: "_Generated by anodizer._")
changelog.sort✅ Verifiedanodizer .anodizer.yaml (sort: asc)
changelog.abbrev✅ Verifiedanodizer .anodizer.yaml (abbrev: 12)
changelog.format✅ Verifiedanodizer .anodizer.yaml (format: "* {{ .SHA }} {{ .Message }} ({{ .AuthorUsername }})")
changelog.divider✅ Verifiedanodizer .anodizer.yaml (divider: "---")
changelog.filters.exclude✅ Verifiedanodizer .anodizer.yaml (excludes ^docs:, ^ci:, ^chore:, ^style:)
changelog.groups✅ Verifiedanodizer .anodizer.yaml (Features/Bug Fixes/Performance/Others groups with regexp + order)
changelog.files.per_crate⏳ Pendingcfgd .anodizer.yaml (changelog.files.per_crate: true)

Build artifacts

KeyStatusNotes
source.enabled✅ Verifiedanodizer .anodizer.yaml (enabled: true)
source.format✅ Verifiedanodizer .anodizer.yaml (format: tar.gz)
source.name_template✅ Verifiedanodizer .anodizer.yaml ("{{ ProjectName }}-{{ Version }}-source")
source.prefix_template✅ Verifiedanodizer .anodizer.yaml ("{{ ProjectName }}-{{ Version }}/")
source.files✅ Verifiedanodizer .anodizer.yaml (globs: crates/**/*.rs, Cargo.toml, Cargo.lock, LICENSE, README.md)
sboms[].id✅ Verifiedanodizer .anodizer.yaml (id: default)
sboms[].documents✅ Verifiedanodizer .anodizer.yaml ("{{ .ArtifactName }}.cdx.json")
sboms[].artifacts✅ Verifiedanodizer .anodizer.yaml (artifacts: archive)
upx[].enabled✅ Verifiedanodizer .anodizer.yaml (enabled: true)
upx[].binary✅ Verifiedanodizer .anodizer.yaml (binary: upx)
upx[].args✅ Verifiedanodizer .anodizer.yaml (["--best", "--lzma"])
upx[].compress✅ Verifiedanodizer .anodizer.yaml (compress: "9")
upx[].lzma✅ Verifiedanodizer .anodizer.yaml (lzma: true)
upx[].targets✅ Verifiedanodizer .anodizer.yaml (4 targets; excludes macOS ARM + Windows ARM — UPX unsupported there)
binstall.enabled✅ Verifiedanodizer .anodizer.yaml (enabled: true — per-target pkg_url overrides auto-derived from archive name_template)
checksum.name_template✅ Verifiedanodizer .anodizer.yaml ("{{ ArtifactName }}.sha256")
checksum.split✅ Verifiedanodizer .anodizer.yaml (split: true — one .sha256 sidecar per artifact instead of a combined file)

Signing

KeyStatusNotes
signs[].id✅ Verifiedanodizer .anodizer.yaml (id: default)
signs[].artifacts✅ Verifiedanodizer .anodizer.yaml (artifacts: checksum — GPG signs each .sha256 sidecar)
signs[].cmd✅ Verifiedanodizer .anodizer.yaml (cmd: gpg)
signs[].args✅ Verifiedanodizer .anodizer.yaml (--batch --local-user {{ Env.GPG_FINGERPRINT }} --output {{ Signature }} --detach-sig {{ Artifact }})
signs[].if✅ Verifiedanodizer .anodizer.yaml (skips in snapshot mode; runs in harness mode for determinism proof)
binary_signs[].artifacts✅ Verifiedanodizer .anodizer.yaml (artifacts: binary — cosign signs each binary blob)
binary_signs[].cmd✅ Verifiedanodizer .anodizer.yaml (cmd: cosign sign-blob --key=env://COSIGN_KEY --bundle={{ Signature }} --yes {{ Artifact }})
binary_signs[].if✅ Verifiedanodizer .anodizer.yaml (same snapshot/harness guard as signs)
docker_signs[].artifacts✅ Verifiedanodizer .anodizer.yaml (artifacts: manifests — cosign signs OCI manifests)
docker_signs[].cmd✅ Verifiedanodizer .anodizer.yaml (cmd: cosign sign --key=env://COSIGN_KEY --yes {{ Artifact }})
docker_signs[].if✅ Verifiedanodizer .anodizer.yaml (same snapshot/harness guard)

Packaging

KeyStatusNotes
nfpm[].id✅ Verifiedanodizer .anodizer.yaml (id: default)
nfpm[].formats✅ Verifiedanodizer .anodizer.yaml (formats: [deb, rpm, apk])
nfpm[].vendor/maintainer/homepage✅ Verifiedanodizer .anodizer.yaml (metadata fields propagated to all three formats)
nfpm[].bindir✅ Verifiedanodizer .anodizer.yaml (bindir: /usr/bin)
nfpm[].section/priority/epoch/release/umask✅ Verifiedanodizer .anodizer.yaml (Debian/RPM packaging metadata)
nfpm[].mtime✅ Verifiedanodizer .anodizer.yaml (mtime: "{{ CommitDate }}" — reproducible package mtime)
nfpm[].recommends/suggests✅ Verifiedanodizer .anodizer.yaml (recommends git, suggests upx; an earlier provides: [anodizer] self-provide was removed — apk rejects a package that provides its own name)
nfpm[].file_name_template✅ Verifiedanodizer .anodizer.yaml ("{{ ProjectName }}_{{ RawVersion }}_{{ Os }}_{{ Arch }}")
nfpm[].contents✅ Verifiedanodizer .anodizer.yaml (LICENSE + README.md installed to /usr/share/doc/anodizer/)
nfpm[].deb.signature.key_file✅ Verifiedanodizer .anodizer.yaml ("{{ .Env.GPG_KEY_PATH }}", type: origin)
nfpm[].rpm.signature.key_file✅ Verifiedanodizer .anodizer.yaml (same GPG key; also sets group + packager)
nfpm[].apk.signature.key_file✅ Verifiedanodizer .anodizer.yaml ("{{ .Env.APK_PRIVATE_KEY_PATH }}" — RSA-PSS, not OpenPGP)
snapcrafts[].name/title/summary/description✅ Verifiedanodizer .anodizer.yaml (live in v0.7.0 — 2026-06-09; amd64 + arm64 revisions published to Snap Store)
snapcrafts[].base✅ Verifiedanodizer .anodizer.yaml (base: core24; live in v0.7.0)
snapcrafts[].grade/confinement✅ Verifiedanodizer .anodizer.yaml (grade: stable, confinement: strict; live in v0.7.0)
snapcrafts[].publish✅ Verifiedanodizer .anodizer.yaml (publish: true; live in v0.7.0)
snapcrafts[].channel_templates✅ Verifiedanodizer .anodizer.yaml (["latest/stable"]; live in v0.7.0)
snapcrafts[].apps✅ Verifiedanodizer .anodizer.yaml (app with home, network, network-bind plugs; live in v0.7.0)
appimages[].desktop⏳ Pendinganodizer .anodizer.yaml (assets/anodizer.desktop)
appimages[].icon⏳ Pendinganodizer .anodizer.yaml (assets/logo.png)
appimages[].filename⏳ Pendinganodizer .anodizer.yaml ("{{ ProjectName }}-{{ Version }}-{{ Arch }}.AppImage")
appimages[].update_information⏳ Pendinganodizer .anodizer.yaml (`gh-releases-zsync
makeselfs[].id✅ Verifiedanodizer .anodizer.yaml (id: default)
makeselfs[].name✅ Verifiedanodizer .anodizer.yaml ("anodizer Installer")
makeselfs[].script✅ Verifiedanodizer .anodizer.yaml (scripts/makeself-install.sh)
makeselfs[].filename✅ Verifiedanodizer .anodizer.yaml ("{{ ProjectName }}-{{ Version }}-{{ Os }}-{{ Arch }}-installer.run")
srpm.enabled✅ Verifiedanodizer .anodizer.yaml (enabled: true)
srpm.package_name✅ Verifiedanodizer .anodizer.yaml (package_name: anodizer)
srpm.spec_file✅ Verifiedanodizer .anodizer.yaml (spec_file: anodizer.spec)
srpm.file_name_template✅ Verifiedanodizer .anodizer.yaml ("{{ ProjectName }}-{{ RawVersion }}-1.src.rpm")

Release

KeyStatusNotes
release.github.owner/name✅ Verifiedanodizer .anodizer.yaml (owner: tj-smith47, name: anodizer)
release.draft✅ Verifiedanodizer .anodizer.yaml (draft: false)
release.prerelease✅ Verifiedanodizer .anodizer.yaml (prerelease: auto)
release.make_latest✅ Verifiedanodizer .anodizer.yaml (make_latest: auto)
release.mode✅ Verifiedanodizer .anodizer.yaml (mode: keep-existing)
release.target_commitish✅ Verifiedanodizer .anodizer.yaml ("{{ .Commit }}")
release.discussion_category_name✅ Verifiedanodizer .anodizer.yaml ("Announcements")
release.replace_existing_draft✅ Verifiedanodizer .anodizer.yaml (replace_existing_draft: true)
release.replace_existing_artifacts✅ Verifiedanodizer .anodizer.yaml (replace_existing_artifacts: true)
release.name_template✅ Verifiedanodizer .anodizer.yaml ("{{ ProjectName }} {{ Tag }}")
release.header✅ Verifiedanodizer .anodizer.yaml ("## What's new in {{ .Tag }}")
release.footer✅ Verifiedanodizer .anodizer.yaml (credits anodizer with 🦀)
release.include_meta✅ Verifiedanodizer .anodizer.yaml (include_meta: true)
release.extra_files✅ Verifiedanodizer .anodizer.yaml (APK signing public key + man page, both with allow_empty: true)

Package managers

KeyStatusNotes
publish.cargo (via defaults)✅ Verifiedanodizer crates.io (all workspace crates published in dependency order)
publish.cargo.wait_for_workspace_deps✅ Verifiedanodizer .anodizer.yaml (inherited from defaults.publish.cargo: {} — waits for sparse index propagation)
publish.cargo.retain_on_rollback⏳ Pendinganodizer .anodizer.yaml (retain_on_rollback: true in defaults.publish.cargo)
publish.aur.git_url✅ Verifiedanodizer .anodizer.yaml (ssh://aur@aur.archlinux.org/anodizer-bin.git)
publish.aur.name/description/license/depends✅ Verifiedanodizer .anodizer.yaml
publish.aur.private_key✅ Verifiedanodizer release.yml (AUR_SSH_KEY secret)
publish.nix.repository✅ Verifiedanodizer .anodizer.yaml (tj-smith47/nix-pkgs)
publish.nix.formatter✅ Verifiedanodizer .anodizer.yaml (formatter: alejandra)
publish.nix.extra_install/post_install✅ Verifiedanodizer .anodizer.yaml (installs man page; echoes setup hint)
publish.scoop.repository✅ Verifiedanodizer .anodizer.yaml (tj-smith47/scoop-bucket)
publish.scoop.depends/shortcuts✅ Verifiedanodizer .anodizer.yaml (depends: git; shortcuts: anodizer.exe)
publish.winget.package_identifier✅ Verifiedanodizer .anodizer.yaml (TJSmith.Anodizer)
publish.winget.dependencies✅ Verifiedanodizer .anodizer.yaml (Microsoft.VCRedist.2015+.x64 — required for MSVC binaries)
publish.winget.update_existing_pr✅ Verifiedanodizer .anodizer.yaml (update_existing_pr: true)
publish.chocolatey.title/summary/authors/owners✅ Verifiedanodizer .anodizer.yaml
publish.chocolatey.republish_in_moderation✅ Verifiedanodizer .anodizer.yaml (republish_in_moderation: true)
homebrew_casks[].repository/directory✅ Verifiedanodizer .anodizer.yaml (tj-smith47/homebrew-tap, Casks/)
homebrew_casks[].binaries✅ Verifiedanodizer .anodizer.yaml (binaries: [anodizer])
homebrew_casks[].generate_completions_from_executable✅ Verifiedanodizer .anodizer.yaml (calls anodizer completion <shell> at cask install for bash/zsh/fish)
homebrew_casks[].manpages✅ Verifiedanodizer .anodizer.yaml (anodizer.1 downloaded from release extra_files)
homebrew_casks[].caveats✅ Verifiedanodizer .anodizer.yaml ("Run anodizer init...")
homebrew_casks[].dependencies✅ Verifiedanodizer .anodizer.yaml (formula: git)

Distributions

KeyStatusNotes
blobs[].provider⏳ Pendinganodizer .anodizer.yaml (provider: s3; arc-anodizer runner has cluster-internal access to MinIO)
blobs[].bucket⏳ Pendinganodizer .anodizer.yaml (anodizer-releases)
blobs[].endpoint⏳ Pendinganodizer .anodizer.yaml ("{{ Env.MINIO_ENDPOINT }}"http://minio.jarvispro.svc.cluster.local:9003)
blobs[].region⏳ Pendinganodizer .anodizer.yaml (region: us-east-1 — compatibility placeholder; MinIO ignores region)
blobs[].s3_force_path_style⏳ Pendinganodizer .anodizer.yaml (s3_force_path_style: true — required for MinIO path-style addressing)
blobs[].disable_ssl⏳ Pendinganodizer .anodizer.yaml (disable_ssl: true — the in-cluster MinIO endpoint is plain http; without it the S3 client rejects the non-https endpoint)
blobs[].directory⏳ Pendinganodizer .anodizer.yaml (directory: "{{ Tag }}")
cloudsmiths[].organization✅ Verifiedanodizer .anodizer.yaml (organization: jarvispro)
cloudsmiths[].repository✅ Verifiedanodizer .anodizer.yaml (repository: anodizer)
cloudsmiths[].formats✅ Verifiedanodizer .anodizer.yaml ([deb, rpm, alpine])
cloudsmiths[].distributions✅ Verifiedanodizer .anodizer.yaml (deb/rpm: any-distro/any-version; alpine: alpine/any-version)
cloudsmiths[].republish✅ Verifiedanodizer .anodizer.yaml (republish: true — prevents MD5 conflict on re-cut)
dockerhub[].username🤝 Help wantedanodizer .anodizer.yaml (skip: true — DockerHub repo not yet created; description-sync only, not image publishing)
dockerhub[].description🤝 Help wantedanodizer .anodizer.yaml (configured but disabled via skip: true)
artifactories[].target🤝 Help wantedanodizer .anodizer.yaml (skip: true — no Artifactory instance)
artifactories[].method🤝 Help wantedanodizer .anodizer.yaml (method: PUT, disabled)
npms[].scope✅ Verifiedanodizer .anodizer.yaml (scope: "@tj-smith47"); the per-platform binary packages publish live under that scope (@tj-smith47/anodizer-{darwin,linux,win32}-* on npm)
npms[].metapackage/bin/mode✅ Verifiedanodizer .anodizer.yaml (metapackage: anodizer, bin: anodizer, mode: optional-deps — biome/git-cliff pattern); the live anodizer metapackage resolves the matching binary via 8 optionalDependencies (npm view anodizer optionalDependencies)
mcp.name/title/description/homepage✅ Verifiedanodizer .anodizer.yaml
mcp.repository✅ Verifiedanodizer .anodizer.yaml (source: github)
mcp.packages✅ Verifiedanodizer .anodizer.yaml (registry_type: oci, identifier: ghcr.io/tj-smith47/anodizer, transport: stdio)
mcp.auth✅ Verifiedanodizer .anodizer.yaml (auth.type: github-oidc; requires id-token: write on release job)
mcp.retain_on_rollback⏳ Pendinganodizer .anodizer.yaml (retain_on_rollback: true)
schemastore.repository✅ Verifiedanodizer .anodizer.yaml (tj-smith47/schemastore)
schemastore.schemas✅ Verifiedanodizer .anodizer.yaml (matches .anodizer.yaml + .anodizer.yml; URL: tj-smith47.github.io/anodizer/schema.json)
schemastore.retain_on_rollback⏳ Pendinganodizer .anodizer.yaml (retain_on_rollback: true)

Post-release

KeyStatusNotes
verify_release.enabled⏳ Pendinganodizer .anodizer.yaml (enabled: true)
verify_release.assert_assets⏳ Pendinganodizer .anodizer.yaml (assert_assets: true — every produced artifact must appear as an uploaded release asset)
verify_release.install_smoke⏳ Pendinganodizer .anodizer.yaml (install_smoke: {} — installs each nfpm package in a container and runs <bin> --version). Auto-detects the Docker topology (bind-mount, or docker cp under a separate-filesystem dind). Also configured in cfgd .anodizer.yaml
verify_release.glibc_ceiling⏳ Pendinganodizer .anodizer.yaml (glibc_ceiling: "2.36" — fails if any .deb requires glibc > 2.36)
attestations.enabled✅ Verifiedanodizer .anodizer.yaml (enabled: true); the v0.12.3 release ships the produced attestation-subjects.json asset
attestations.mode✅ Verifiedanodizer .anodizer.yaml (mode: subjects — writes dist/attestation-subjects.json; anodizer-action feeds it to actions/attest-build-provenance). Live: the 19 KB attestation-subjects.json attached to v0.12.3
attestations.artifacts🤝 Help wantedNot configured — defaults to all artifact kinds when mode: subjects
milestones[].repo✅ Verifiedanodizer .anodizer.yaml (tj-smith47/anodizer)
milestones[].close🤝 Help wantedanodizer .anodizer.yaml (close: false — wired but disabled; no milestones configured)
milestones[].fail_on_error⏳ Pendinganodizer .anodizer.yaml (fail_on_error: true — milestone errors fail the release instead of vanishing; the flip from false awaits a live release, and close: false means the publisher currently does nothing)
milestones[].name_template✅ Verifiedanodizer .anodizer.yaml (name_template: "{{ Tag }}")

Announce

KeyStatusNotes
announce.gate_on✅ Verifiedanodizer .anodizer.yaml (gate_on: required_publishers — announce only after all required publishers succeed)
announce.webhook.enabled✅ Verifiedanodizer .anodizer.yaml (enabled: true — posts JSON to tj.jarvispro.io/webhooks/anodizer)
announce.webhook.endpoint_url✅ Verifiedanodizer .anodizer.yaml
announce.webhook.content_type✅ Verifiedanodizer .anodizer.yaml (application/json)
announce.webhook.message_template✅ Verifiedanodizer .anodizer.yaml (JSON payload with project, tag, url)
announce.webhook.headers✅ Verifiedanodizer .anodizer.yaml (X-Anodizer-Source: release)
announce.webhook.skip_tls_verify✅ Verifiedanodizer .anodizer.yaml (skip_tls_verify: false)
announce.webhook.expected_status_codes✅ Verifiedanodizer .anodizer.yaml ([200, 202])
announce.email.enabled✅ Verifiedanodizer .anodizer.yaml (enabled: true)
announce.email.host/port/username/from/to✅ Verifiedanodizer .anodizer.yaml (Gmail SMTP, port 587, STARTTLS)
announce.email.subject_template✅ Verifiedanodizer .anodizer.yaml
announce.email.encryption✅ Verifiedanodizer .anodizer.yaml (encryption: starttls)
announce.discord🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.slack🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.telegram🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.teams🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.mattermost🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.reddit🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.twitter🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.mastodon🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.bluesky🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.linkedin🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.discourse🤝 Help wantedanodizer .anodizer.yaml (enabled: false)
announce.opencollective🤝 Help wantedanodizer .anodizer.yaml (enabled: false)

Platform-specific (disabled)

KeyStatusNotes
flatpaks[].skip🤝 Help wantedanodizer .anodizer.yaml (skip: true — no Flatpak runtime configured; app_id: io.github.tj_smith47.Anodizer, runtime: org.freedesktop.Platform/24.08)
app_bundles[].skip🤝 Help wantedanodizer .anodizer.yaml (skip: true — no macOS app bundle signing identity)
dmgs[].skip🤝 Help wantedanodizer .anodizer.yaml (skip: true — needs app_bundle first)
pkgs[].skip🤝 Help wantedanodizer .anodizer.yaml (skip: true — no macOS PKG signing identity)
msis[].skip🤝 Help wantedanodizer .anodizer.yaml (skip: true — no WiX source .wxs)
nsis[].skip🤝 Help wantedanodizer .anodizer.yaml (skip: true — no NSIS script)
notarize.skip🤝 Help wantedanodizer .anodizer.yaml (skip: true — no Apple Developer credentials)