tj-smith47/Anodizer Action

GitHub Action for Anodizer — a Rust-native release automation tool

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Stale
License
None
namedescriptionrequireddefault
versionAnodizer version to install from GitHub releases. Accepts an exact tag (e.g. "v0.1.1"), the literal "latest" (newest stable release), or the literal "nightly" (newest release whose tag matches `*-nightly`, i.e. `vX.Y.Z-<sha>-nightly`). Semver ranges such as "~> v2" are NOT supported — pass an explicit tag, "latest", "nightly", or use `from-artifact` / `from-source`. Must not be combined with `from-artifact`, `from-source`, or `from-branch` — the action fails when an explicit version is set alongside any of them. nolatest
from-artifactDownload a pre-built anodizer binary from a workflow artifact instead of GitHub releases. Set to the artifact name (e.g. "anodizer-linux"). For cross-workflow downloads, also set `artifact-run-id`. no
artifact-run-idWorkflow run ID to download the artifact from. Use "auto" to automatically resolve the latest successful run of `artifact-workflow` for the current commit. Use a numeric ID for explicit control. Omit to download from the current workflow run. no
artifact-workflowWorkflow filename to search when `artifact-run-id` is "auto" (e.g. "ci.yml"). Ignored otherwise. noci.yml
from-sourceBuild anodizer from source in the current workdir (bootstrap mode). Rust is auto-installed; you do not need to also set `install-rust: true`. Useful when `from-artifact` is only available for one platform and the current runner needs a platform-native binary. nofalse
from-branchShallow-clone `tj-smith47/anodizer` at the given branch name and build it from source. Accepts a branch name only (e.g. "my-feature", "main"). The repository is hardcoded to `tj-smith47/anodizer`; do not include an owner prefix, repo name, or commit SHA — branch names only. Rust is auto-installed. Mutually exclusive with `version`, `from-artifact`, and `from-source`. no""
installExplicit comma-separated list of build/pipeline dependencies to install, bypassing auto-detection. Use this when the job does NOT run the pipeline (so `anodizer tools` has nothing to report) — e.g. a `--preflight-secrets` key-load check — or to force a specific tool on. Supported: nfpm, makeself, snapcraft, rpmbuild, cosign, syft, zig, node, cargo-zigbuild, upx, nsis, create-dmg, flatpak, alejandra, linuxdeploy, rcodesign, wix, wix3, pkgbuild, xmllint. `wix` is the WiX v4 dialect (`wix build`, the dotnet global tool on Windows); `wix3` is the WiX v3 dialect (candle+light via the choco wixtoolset package). Both install `wixl` (msitools) on Linux. Uses the platform's native package manager (apt on Linux, brew on macOS, choco on Windows); some deps fall back to direct downloads when no packaged version exists. no
auto-installDerive and install the external tools the configured pipeline needs by asking the engine itself — `anodizer tools --json` — rather than re-parsing the config in shell (which drifts from anodizer's truth). The run's scope flags (`--publish-only`, `--skip`, `--publishers`, `-f/--config`) are read from `args` and forwarded, so the installed set matches exactly the stages this job runs (a publish-only job never installs build-only tools, and `--skip=npm` drops node). Each reported binary is mapped to the matching installer; tools already on PATH or provided by the runner (git, gpg, ssh, docker, cargo) are left alone, and a required tool with no install recipe is reported as a warning instead of being silently skipped. Set `install:` instead when the job does not run the pipeline. nofalse
install-rustInstall the stable Rust toolchain (dtolnay/rust-toolchain).nofalse
reclaim-diskReclaim large, build-irrelevant runner caches before heavy build/packaging so disk-tight runners don't fail with "No space left on device" (the macOS determinism harness assembles installers twice plus hdiutil scratch volumes). "auto" (default) reclaims the preinstalled caches a Rust release pipeline never uses — iOS/tvOS/watchOS simulator runtimes on macOS, large preinstalled SDKs on Linux — but ONLY on GitHub-hosted runners; a self-hosted runner's disk is never touched. "true" forces reclamation on any runner; "false" disables it. noauto
resolve-workspaceResolve the triggering tag to a crate name using `anodizer resolve-tag`. Set to "true" on tag-triggered release workflows. Populates the `workspace`, `crate-path`, and `has-builds` outputs. nofalse
docker-registryContainer registry to log in to (e.g. "ghcr.io"). When set, the action logs in, and sets up QEMU + buildx for multi-platform builds. no
docker-usernameRegistry username (defaults to github.actor via GITHUB_ACTOR env).no
docker-passwordRegistry password or token (e.g. secrets.GITHUB_TOKEN).no
upload-distUpload the dist tree (the configured `dist:` directory, default `dist/`) as a workflow artifact named "dist-$RUNNER_OS" after running anodizer. Set to "true" in split build jobs. With `preserve-dist: 'true'` it instead uploads `preserved-dist/` as "dist-<shard-label>", so same-OS shards on a determinism matrix don't collide. nofalse
download-distDownload and merge dist-* artifacts before running anodizer. Set to "true" in merge jobs. Merges all artifacts matching "dist-*" into the dist tree (the configured `dist:` directory, default `dist/`). nofalse
gpg-private-keyGPG private key contents to import for signing. The key is piped into `gpg --batch --import`. no
apk-private-keyPEM-format RSA private key for signing apk packages produced by nfpm. Required if your `.anodizer.yaml` configures `nfpm[].apk.signature` (apk-tools uses its own RSA-PSS scheme, not OpenPGP, so the GPG key consumed by `gpg-private-key` does not work here). The private key is written to a temp file with mode 0600 and the path is exported as `APK_PRIVATE_KEY_PATH` for subsequent steps and the anodizer config to consume. The matching public key is derived via `openssl rsa -pubout`, exported as `APK_PUBLIC_KEY_PATH`, and copied into `./dist/` as `<repo>-apk-signing-key.rsa.pub` so consumers can attach it as a release asset via `release.extra_files`; apk verifiers install that file under `/etc/apk/keys/` before `apk add`-ing a signed package.no""
cosign-keyCosign private key contents. Written to `cosign.key` in the workdir with mode 0600. Pair with `COSIGN_PASSWORD` in the env. no
argsArguments to pass to anodizer (e.g. "release --snapshot"). Do NOT embed secrets or tokens here — this value appears in workflow logs. Pass secrets via the `env:` block (e.g. `GITHUB_TOKEN`, `COSIGN_PASSWORD`). no
workdirWorking directory (below repository root).no.
install-onlyOnly install anodizer without running it.nofalse
determinismRun the determinism harness (`anodizer check determinism`) on this shard. When true, the action: installs Rust (if not already), provisions the `anodizer` binary — built from source by default, or downloaded when `version` names an explicit tag (a consumer validating its own release reproducibility runs the same released binary that will publish it) — installs the harness dependency set (zig, cargo-zigbuild, upx, nfpm, makeself, snapcraft, syft, cosign on Linux; upx, syft, cosign on macOS/Windows), derives the configured-target CSV for the current RUNNER_OS via `anodizer targets --json`, `rustup target add`s those triples, and invokes the harness. Intended to be the entire body of a per-OS harness shard on a 3-OS matrix [ubuntu-latest, macos-latest, windows-latest]. Mutually exclusive with `args`. nofalse
determinism-runsN for `anodizer check determinism --runs=N`.no2
determinism-stagesStages to validate (comma-separated). When unset, defaults to the stages configured-and-installable on the current RUNNER_OS: Linux gets `build,source,upx,archive,nfpm,makeself,snapcraft,sbom,sign,checksum`; macOS and Windows get `build,source,upx,archive,sbom,sign,checksum` (no nfpm/makeself/snapcraft — apt is Linux-only and apk/deb/rpm signing isn't provisioned on the non-Linux shards). Explicit values override. Beyond the default set the harness also accepts `cargo-package`, `docker`, `msi`, `nsis`, `dmg`, `pkg`, `srpm`, and the `installers` family selector (expands to nfpm,makeself,srpm,msi,nsis,dmg,pkg). no""
determinism-targetsExplicit target CSV override. When unset, the action filters `anodizer targets --json` to entries matching the current RUNNER_OS. Set when your shard runs on a non-standard runner label. no
determinism-crateScope the harness to a single workspace crate via `anodizer check determinism --crate <name>`. Required when the release workflow fans out per crate (e.g. matrix over `fromJson(needs.tag.outputs.crates)`) so each shard's preserved dist lands under its own `<crate>/` subdir for collision-free merge in the downstream publish job. no""
preserve-distHave the determinism harness preserve its hermetic dist tree to `./preserved-dist/` so a downstream `release: --publish-only` job can publish directly from the byte-stable artifacts. Manifests get a `-<shard-label>` suffix (`context-<label>.json`, etc.) so sharded matrix uploads don't collide under `merge-multiple: true`. Requires `determinism: 'true'` and `shard-label`. nofalse
shard-labelPer-shard suffix appended to preserved-dist manifests. The caller names each shard explicitly; the action does not derive labels. Required when `preserve-dist: 'true'`. no""
namedescription
artifactsBuild result artifacts JSON (contents of dist/artifacts.json).
metadataBuild result metadata JSON (contents of dist/metadata.json).
release-urlURL of the created GitHub release (extracted from metadata.json).
workspaceCrate name resolved from the triggering tag (requires resolve-workspace: true).
crate-pathPath to the resolved crate directory (requires resolve-workspace: true).
has-buildsWhether the resolved crate has binary builds configured (requires resolve-workspace: true).
split-matrixJSON matrix for `strategy.matrix` covering all configured build targets. Produced from the anodizer config when `install-only: true`. Each entry has `os`, `target`, and `artifact` fields.
cratesJSON array of crate names that `anodizer tag` produced tags for in this run. Empty array `[]` when nothing was tagged. Use as `fromJson(steps.<id>.outputs.crates)` to drive downstream matrix strategies.
versionsJSON object mapping crate name to bumped version, from `anodizer tag`. Empty `{}` when nothing was tagged. Consume with `fromJson(steps.<id>.outputs.versions).<crate>` or bracket-form for hyphenated crate names: `fromJson(steps.<id>.outputs.versions)['my-crate']`.
new-tagTag `anodizer tag` created this run (e.g. `v1.2.3`), for single-crate and lockstep-workspace repos. Empty when no tag was cut. Per-crate workspaces surface tags via `crates`/`versions` instead.
old-tagPrevious tag `anodizer tag` bumped from. Empty when there was none (first release).
partSemver part bumped by `anodizer tag`: `major` | `minor` | `patch` | `none` | `custom`.
tagged`'true'` when this run cut a new tag (`new-tag` is non-empty and differs from `old-tag`), `'false'` on a no-op run. Gate downstream release jobs on this for single-crate / lockstep repos.
head-shaCommit SHA at HEAD after `anodizer tag --push` (the tag target — the version-sync bump commit, or the original HEAD when no bump was needed). Check this out in downstream jobs so the tree matches the tag.
irreversibly-published`'true'` when the run's summary (`dist/run-*/summary.json`, or `dist/<crate>/run-*/summary.json` in per-crate workspaces) records a one-way-door publisher (crates.io, chocolatey, winget, snapcraft, ...) whose publish landed — the version is burned at a registry that never accepts the same version twice, so a tag rollback can only orphan the live release, never enable a clean same-version re-cut. `'false'` when only reversible publishers (github-release assets, blobs, tap/bucket/index commits) succeeded, or when nothing was proven published (including when no summary exists). Forensic signal: the default failure handling is anodizer's in-process `release.on_failure` policy, which already refuses to roll back past one-way doors. Workflows adding a custom destructive recovery step must gate it on this output: `if: steps.<id>.outputs.irreversibly-published != 'true'`.
irreversibly_publishedDeprecated snake_case alias of `irreversibly-published` (same value); retained so existing workflows keep working. New workflows should read `irreversibly-published`.