Skip to main content

What anodizer builds

Artifacts the `anodizer release` pipeline produces: binaries, archives, packages, installers, containers, and signing material.

What anodizer builds

Output formats and the builds[] / archives[] / dockers_v2[] / signs[] keys that drive them. Native binaries for 6 targets ship on every release (linux amd64/arm64, darwin amd64/arm64, windows amd64/arm64), built with cargo + cargo-zigbuild + cross.

Live configuration

Build / archive / nfpm / dockers_v2 / sign blocks from cfgd/.anodizer.yaml (snapshot 2026-05-24) — every key referenced in the tables below is wired here.

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

# Per-crate (one workspace shown):
builds:
  - binary: cfgd
    mod_timestamp: "{{ CommitTimestamp }}"

archives:
  - name_template: "{{ ProjectName }}-{{ Version }}-{{ Os }}-{{ Arch }}"
    formats: [tar.gz]
    format_overrides:
      - { os: windows, formats: [zip] }
    files: [LICENSE, README.md]

universal_binaries:
  - { name_template: "{{ ProjectName }}", replace: false }

checksum:
  name_template: "{{ ArtifactName }}.sha256"
  algorithm: sha256
  split: true

# Top-level:
upx:
  - id: default
    enabled: true
    args: ["--best", "--lzma"]
    targets: [x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu,
              x86_64-apple-darwin, x86_64-pc-windows-msvc]

nfpms:
  - id: cfgd
    formats: [deb, rpm, apk]
    maintainer: "TJ Smith <tj@jarvispro.io>"
    contents:
      - { src: LICENSE,   dst: /usr/share/doc/cfgd/LICENSE }
      - { src: README.md, dst: /usr/share/doc/cfgd/README.md }

# dockers_v2: pushes a multi-arch image index in one step (no separate manifest).
dockers_v2:
  - id: cfgd
    dockerfile: Dockerfile.agent.release
    images: ["ghcr.io/tj-smith47/cfgd"]
    tags: ["{{ Version }}", "v{{ Version }}", "latest"]
    sbom: true

signs:
  - { id: cosign-checksum, artifacts: checksum, cmd: cosign }
  - { id: cosign-source,   artifacts: source,   cmd: cosign }
docker_signs:
  - { id: cosign-images, artifacts: manifests, cmd: cosign }
binary_signs:
  - { id: cosign-bin,    artifacts: binary,    cmd: cosign }

sboms:
  - { id: default, cmd: syft, artifacts: archive, documents: ["{{ .ProjectName }}-{{ .Version }}.cdx.json"] }

Build

KeyStatusNotes
builds[].targets → per-target os / arch✅ Verifiedv0.23.0 assets cover 6 targets (*-linux-amd64.tar.gz to *-windows-arm64.zip)
universal_binaries[]✅ Verifiedcfgd v0.3.5 ships cfgd-0.3.5-darwin-all.tar.gz via lipo
upx[]✅ Verifiedanodizer-0.23.0-linux-amd64.tar.gz (UPX-packed)
builds[].overrides✅ Verifiedcfgd .anodizer.yaml (format_overrides for windows zip)
builds[].hooks.pre / post✅ Verifiedanodizer .anodizer.yaml (archive hooks.before / hooks.after)
builds[].mod_timestamp✅ Verifiedanodizer .anodizer.yaml (metadata.mod_timestamp: "{{ CommitTimestamp }}")
builds[].builder: prebuilt (no-compile)🤝 Help wantedcrates/stage-build/src/run.rs imports a pre-built binary; crates/stage-build/src/tests.rs covers unit paths; no production .anodizer.yaml uses builder: prebuilt yet
report_sizes✅ Verifiedanodizer .anodizer.yaml (report_sizes: true)

Archives and checksums

FormatStatusNotes
tar.gz✅ Verifiedanodizer-0.23.0-linux-amd64.tar.gz
zip✅ Verifiedanodizer-0.23.0-windows-amd64.zip
tar.xz, tar.zst, tgz✅ Verifiedanodizer-0.23.0-linux-amd64-extra.tar.xz, anodizer-0.23.0-linux-amd64-extra.tar.zst, anodizer-0.23.0-windows-amd64-extra.tgz (second archives[] entry with formats: [tar.xz, tar.zst] + tgz override)
source.format✅ Verifiedanodizer-0.23.0-source.tar.gz
makeselfs[]✅ Verifiedanodizer-0.23.0-linux-amd64-installer.run (4 platforms)
KeyStatusNotes
checksum.algorithm✅ VerifiedLockstep. sha256 default → the combined anodizer_0.23.0_checksums.txt. Full list: sha1/224/256/384/512, sha3-*, blake2s/2b, blake3, crc32, md5
checksum.split✅ VerifiedPer-crate. cfgd .anodizer.yaml (checksum.split: true on the cfgd workspace) — cfgd v0.6.1 ships a .sha256 sidecar next to every asset instead of one combined file. anodizer runs the combined mode

Linux packages

FormatStatusNotes
.deb✅ Verifiedanodizer_0.23.0_linux_amd64.deb (amd64 + arm64)
.rpm✅ Verifiedanodizer_0.23.0_linux_amd64.rpm (amd64 + arm64)
.apk✅ Verifiedanodizer_0.23.0_linux_amd64.apk
.src.rpm✅ Verifiedanodizer-0.23.0-1.src.rpm
.snap⏳ PendingDogfooded through 0.9.1: snapcraft.io/anodizer serves that revision from 2026-06-13, the newest either project ever landed. Current releases don't upload — anodizer execs host cargo/docker/gpg, which needs classic confinement, and the Snap Store denied the request, so snapcrafts[].publish is false. See Where you install it
archlinux, ipk, termux.deb🤝 Help wantednFPM dispatch covered; not shipped live
KeyStatusNotes
nfpms[].scripts✅ Verifiedcrates/core/src/config/nfpm.rs (preinstall / postinstall / preremove / postremove fields)
nfpms[].contents✅ Verifiedcfgd .anodizer.yaml (contents: ships LICENSE + README.md to /usr/share/doc/cfgd/)
NFPM_PASSPHRASE env chain✅ Verifiedcrates/stage-nfpm/src/builders.rs (three-level lookup chain)

macOS and Windows installers (built on Linux CI)

These formats are assembled on an ordinary Linux runner — no macOS or Windows host in the build matrix. Anodizer's own dogfood config wires all five (anodizer .anodizer.yaml, app_bundles: / dmgs: / pkgs: / msis: / nsis: blocks), built unsigned in CI. Code-signing and notarization still require the platform's own credentials; the bundles themselves do not. As of v0.23.0 all of them — including the Linux-desktop .AppImage and .flatpak bundles — ship as live release assets (amd64 + arm64).

FormatStatusBuilt on Linux via
.app bundle✅ Verifiedanodizer_amd64.dmg ships the bundle (in-process directory + Info.plist assembly, no external tool); app_bundles:. See app-bundle docs
.dmg✅ Verifiedanodizer_amd64.dmg + anodizer_arm64.dmg via genisoimage / mkisofs; dmgs:. See dmg docs
.pkg✅ Verifiedanodizer_amd64.pkg + anodizer_arm64.pkg via flat XAR toolchain (xar + mkbom), byte-reproducible TOC; pkgs:. See pkg docs
.msi✅ Verifiedanodizer_amd64.msi + anodizer_arm64.msi via wixl (msitools); msis:. See msi docs
.exe (NSIS)✅ Verifiedanodizer_x64-setup.exe + anodizer_arm64-setup.exe via makensis; nsis:. See nsis docs
.AppImage✅ Verifiedanodizer-0.23.0-amd64.AppImage + anodizer-0.23.0-arm64.AppImage, each with a .zsync delta-update sidecar, via linuxdeploy; appimages:. See appimage docs
.flatpak✅ Verifiedanodizer_0.23.0_linux_amd64.flatpak + anodizer_0.23.0_linux_arm64.flatpak single-file bundles; flatpaks: (org.freedesktop.Platform 24.08 runtime with host-surface finish_args). Flathub distribution itself is still open — see Where you install it
KeyStatusNotes
notarize.macos🤝 Help wantedCross-platform (rcodesign). Implementation requires sign.certificate (P12 file), sign.password, and notarize.{issuer_id, key, key_id}, i.e. an Apple Developer Program membership. Not dogfoodable on Linux runners without a paid Apple account
notarize.macos_native🤝 Help wantedNeeds Apple Developer cert on a macOS runner

Container images

KeyStatusNotes
dockers_v2[]✅ Verifiedghcr.io/tj-smith47/anodizer carries 34 semver tags plus latest, each a linux/amd64 + linux/arm64 index pushed in one buildx invocation; cfgd's three images (cfgd, cfgd-operator, cfgd-csi) cover the per-crate shape
dockers_v2[].images → multi-registry push✅ Verifiedanodizer .anodizer.yaml lists two registries under one entry (ghcr.io/tj-smith47/anodizer plus a private registry.jarvispro.io/anodizer mirror), so a single buildx run pushes every tag to both. Only the GHCR half is publicly checkable
docker_manifests[]🤝 Help wantedNo dogfood config declares one: dockers_v2 already pushes a multi-arch index, so a separate manifest step has nothing to stitch (# No docker_manifests needed marks all three sites in cfgd .anodizer.yaml). The key exists for the case of stitching images that were not built by dockers_v2 in the same run, which none of our projects has
dockers_v2[].build_args / labels / annotations✅ Verifiedcfgd .anodizer.yaml (build_args.VERSION + org.opencontainers.image.* annotations)
dockers_v2[].sbom: true✅ Verifiedcfgd .anodizer.yaml (sbom: true on all three dockers_v2 images)
docker_digest.name_template✅ Verifiedcfgd .anodizer.yaml (docker_digest.name_template: "cfgd_{{ .Tag }}.digest")
dockers_v2[].use: buildx✅ Verifiedcrates/stage-docker/src/detect.rs (buildx is the default backend)
dockers_v2[].use: podman / docker_manifests[].use: docker / podman🤝 Help wantedLinux-only backend selectors. No live release exercises the non-buildx path
docker_hub.description✅ VerifiedLive at hub.docker.com/r/tsmthtj/anodizer — the dockerhub: publisher syncs description + full_description (from README.md) each release; at v0.15.5 (run 28882554907) it read the remote repo and logged skipped dockerhub PATCH … description / full_description match remote (summary: dockerhub … succeeded)

Signing

KeyStatusNotes
signs[] (cosign, keyless)✅ VerifiedSingle-crate and per-crate. brontes signs its source tarball keyless — Fulcio OIDC, no key secret: brontes-0.3.0-source.tar.gz.sig via brontes .anodizer.yaml (signs[].if: "{{ not IsSnapshot }}"); cfgd the same, per checksum sidecar: cfgd v0.3.5 cosign bundle
binary_signs[] / docker_signs[] (cosign, keyful)✅ VerifiedLockstep. anodizer signs with a stored key, not keyless: --key=env://COSIGN_KEY in anodizer .anodizer.yaml, with COSIGN_KEY / COSIGN_PASSWORD supplied by release.yml and nightly.yml. The image half is publicly checkable: ghcr.io/tj-smith47/anodizer carries 37 cosign .sig tags alongside its image tags
signs[] (gpg)✅ Verifiedanodizer_0.23.0_checksums.txt.sig
signs[].artifacts✅ Verifiedcfgd .anodizer.yaml (signs: declares artifacts: checksum and artifacts: source slots). The artifacts: source selector is proven live by brontes: brontes-0.3.0-source.tar.gz.sig
docker_signs[].artifacts: manifests✅ VerifiedBoth shapes wire it: anodizer .anodizer.yaml (lockstep, one image) and cfgd .anodizer.yaml (per-crate, three). The signatures are the .sig tags sitting beside each image tag on ghcr.io/tj-smith47/anodizer
Cosign TUF warm-up lock + warm-cache fast path✅ Verified (tests)crates/stage-sign/src/tuf_cache.rs — keyless cosign's first run initializes its sigstore TUF trust root under a host-level advisory flock so parallel cold starts don't race; a warm cache (go-tuf or sigstore-go layout) skips the serialized first sign entirely. Validated locally by racing 8 parallel keyless sign-blob invocations on a warm cache; awaits a live multi-shard release for public proof
sboms[]✅ VerifiedCycloneDX via syft. anodizer-0.23.0.cdx.json. sboms[].artifacts: source (SBOM over the source tarball instead of build outputs) is proven live by brontes: brontes-0.3.0.cdx.json
${artifact} / ${document} substitution✅ Verifiedcrates/stage-sbom/src/stage.rs ($artifact, $artifactID, $document, $document<N> substitution into the SBOM tool's argv)