name: setup-soldr author: zackees description: Extraction-ready Soldr setup action. Installs one soldr binary, bootstraps rustup when needed, provisions the resolved Rust toolchain, and restores a cacheable runner-local Soldr root. branding: icon: terminal color: green inputs: enable: description: > When "true" (default), install the real soldr binary and run the full setup. When "false", skip the soldr download/verify and write a passthrough stub at the soldr binary path that forwards `soldr ` to ` ` (as if `soldr` were omitted from the command line). Internal subcommands soldr-aware code paths query (`version`, `cache`, `status`) return stub JSON so the rest of the action keeps working. The Rust toolchain is still provisioned; cache layers naturally no-op because the build-cache dir stays empty. Useful for A/B testing soldr's effect on a workflow without rewriting it. required: false default: "true" version: description: > Soldr version or tag to install. Defaults to the soldr release this setup-soldr build is vendor-locked to (resolved with no network lookup; bumped on every soldr release). Pass `latest` to resolve the newest release at run time instead. required: false default: "0.9.27" repo: description: Internal override for the Soldr source repository used by integration branches. required: false default: zackees/soldr ref: description: Internal override that builds Soldr from a Git ref instead of downloading a release asset. required: false default: "" source-path: description: Internal development override that builds Soldr from a pinned local Git checkout (for example `_vender/soldr`) instead of downloading a release asset. The checkout must include its required submodules. Production consumers should leave this empty. required: false default: "" token: description: GitHub token used for authenticated release metadata and asset download requests. required: false default: ${{ github.token }} cache: description: > Umbrella switch for all caching layers. Default "true" (caches managed normally). Set to "false" to disable every layer in one go: setup-cache (soldr binary + rustup state including `~/.rustup/update-hashes/` for fast `rustup update` no-ops, see setup-soldr#102), build-cache (zccache compilation cache), target-cache (Rust target/ artifacts), and cargo-registry-cache. Also exports `SOLDR_BUILD_CACHE_MODE=off` / `SOLDR_TARGET_CACHE_MODE=off` so soldr skips its zccache wrapping entirely — the daemon won't be invoked and no per-session stats are written. Use this when you want a clean uncached build (CI A/B test, debugging cache-related regressions, etc.). For finer control, leave `cache: true` and flip individual layer inputs. required: false default: "true" save-cache-remote: description: > auto | true | false. Remote-only durable cache write policy, for example the ci-lint plan's cache_save output. With auto (default), save-cache and the triggering event decide as before. true or false sets the remote write decision; ignored under act/act2 so local automatic saves remain warm. save-cache=false always disables saves everywhere, including local runners. Restores are unaffected. required: false default: "auto" save-cache: description: > Governs every durable Actions-cache save this action performs (cook base/delta, build-cache, target-cache, solo-toolchain, cargo-registry, soldr-mini, blessed prepare, dylint caches). "auto" (default) saves unless the triggering event is `pull_request`: GitHub scopes such entries to `refs/pull/N/merge`, so no other run can restore them, yet they count against the repository's 10 GB budget. "true" always saves; "false" never saves. Restores and cooking on a miss happen regardless; only uploads are skipped. Trade-off: a PR that changes the dependency closure cooks cold and does not persist the result. See setup-soldr#527. required: false default: "auto" cache-dir: description: Override the runner-local cache/state root used for the installed soldr binary and any managed rustup state rehydrated by this action. required: false default: "" cache-key-suffix: description: Optional extra suffix appended to the cache key. required: false default: "" key: description: 'Build-cache key override. "auto" opts into Phase 1 nearest clean ancestor selection; other cache families retain their identity keys.' required: false default: "" auto-key: description: 'Treat an omitted key as "auto" for the source-dependent build-cache pilot. Requires actions: read. Default remains disabled.' required: false default: "false" auto-key-trusted-writers: description: > Phase 1 pilot only: newline-separated explicitly reviewed immutable writer jobs, owner/repo/.github/workflows/file.yml@FULL_SOURCE_SHA:RUN_ID:ATTEMPT:JOB_ID. Review the pinned post action and complete transitive executable source before authorizing a writer. Unknown writers use legacy restore; matching stdout alone never authorizes a donor. required: false default: "" cache-preset: description: > One-line cache policy umbrella. Fills any cache-affecting input that the consumer leaves unset; explicit fine-grained inputs always win (so setting `target-cache: true` keeps that, even under `cache-preset: minimal`). Valid values: - "minimal": build-cache=false, target-cache=false, cargo-registry-cache=true, prebuild-deps=soldr-cook (dependency rematerialization only). - "foundation": build-cache=true, target-cache=false, cargo-registry-cache=true, prebuild-deps=soldr-cook (the current default; no behavior change). - "full": build-cache=true, target-cache=true, cargo-registry-cache=true, prebuild-deps=soldr-cook, build-cache-mode=thin (heavy, opt-in). Empty default keeps each fine-grained input on its historical default (foundation policy). The resolved preset is surfaced via the `cache-preset-effective` output. (#251) required: false default: "" toolchain: description: Override the exact Rust toolchain channel string. When empty, toolchain-file is used if present, otherwise stable. required: false default: "" toolchain-file: description: Toolchain file to read when toolchain is not explicitly set. required: false default: rust-toolchain.toml trust-mode: description: Optional value for SOLDR_TRUST_MODE. required: false default: "" linker: description: > Linker override forwarded as SOLDR_LINKER for `soldr cargo ...` builds (requires soldr 0.7.19+). Empty (the default) opts the workflow into `fast` — mold-if-on-PATH-else-rust-lld on Linux, rust-lld on macOS and Windows — and emits a one-time GitHub Actions warning so the override is visible in CI logs. Soldr's own native default is no injection (smaller artifact cache, slower link); pass `platform-default` (or `default`) to opt out and keep whatever cargo config / rust-toolchain.toml specifies. Other accepted values pass through verbatim to SOLDR_LINKER: `ld`, `mold`, `rust-lld`, `fast`. Unknown values raise an error. When the input is left empty and the workflow has already exported any `CARGO_TARGET__LINKER` or `CARGO_TARGET__RUSTFLAGS` env var (typical for cross-compile setups), setup-soldr defers to the user's values and skips the `fast` default to avoid clobbering them. See issue #108. required: false default: "" compile-priority: description: > Compiler/linker child-process priority forwarded as ZCCACHE_COMPILE_PRIORITY (requires zccache 1.4.6+). Setup-soldr defaults to `high` because GitHub Actions runners are dedicated to CI and have no foreground workload to yield to — zccache's own native default is `low` (designed for interactive dev). Accepted values: `normal`, `low`, `idle`, `high`. Set to empty string to opt out and let zccache pick its native default. required: false default: "high" timestamps: description: Prefix setup-soldr diagnostic and streamed command output with elapsed mm:ss timestamps. required: false default: "true" timestamp-format: description: > Format used by the timestamp prefix when `timestamps: true`. Accepted values: `mmss` (default - the historical `MM:SS` prefix, e.g. `00:08 message`) and `seconds` (two-decimal seconds since step start, e.g. `8.04 message`). The `seconds` format is monotonic and lets you subtract two adjacent prefixes to read the cost of an operation directly. Has no effect when `timestamps: false`. (#387 Feature 2) required: false default: "mmss" lockfile: description: Optional Cargo.lock path used for Rust artifact cache keying. Empty infers Cargo.lock next to target-dir, then workspace Cargo.lock. required: false default: "" build-cache: description: > Restore and save Soldr/zccache build cache state across workflow runs. Empty (default) resolves to "true" unless `cache-preset` overrides it (e.g. `cache-preset: minimal` resolves it to "false"). Set explicitly ("true"/"false") to override any preset. (#251) required: false default: "" build-cache-save-min-compiles: description: > Delta-aware build-cache save gate (issues #230 / #214). When a build cache was restored this run (exact or restore-key fallback) and the session recorded fewer than this many new compiles (zccache misses), setup-soldr skips re-saving the build-cache — the restored entry already holds everything, so re-uploading the (often multi-GiB) payload under a fallback key just duplicates it and dominates the Windows post step. Default "1": skip only when literally nothing new was compiled (the safe floor). Raise it (e.g. "10") to also skip tiny deltas, or set "0" to disable the gate and always save. Never gates a cold seed (no restore) or an unreadable compile count, so a real cache is always seedable. Per-phase save timings (compress vs upload) are logged regardless. required: false default: "1" job-status: description: > Set it to the `job.status` expression in the workflow (README shows the line). The runner re-evaluates a step's `with:` inputs for its post step, so the post step then sees the job's status at the end of its steps. (An action's own input default cannot read the `job` context, so this must come from the workflow.) When it is `failure` or `cancelled`, the post step saves no build outputs (build-cache and target-cache): a failed build's store may be partial, and an exact-hit key is never re-saved, so saving it poisons the key (#559). Empty (the default) keeps the old always-save behaviour. required: false default: "" save-on-failure: description: > "true" saves build-cache and target-cache even when the job failed or was cancelled (the behaviour before #559). Default "false". required: false default: "false" target-cache-save-min-compiles: description: > Delta-aware target-cache save gate (#255). Mirror of `build-cache-save-min-compiles` for the Rust `target/` artifact cache: when the target-cache was restored from a fallback key and the session recorded fewer than this many new compiles, skip the target-cache save — the restored entry already holds everything, so re-saving under a new key just re-uploads a duplicate multi-GiB payload. Default "1": skip only when literally nothing new was compiled. Raise to also skip tiny deltas, or set "0" to disable the gate. Never gates an exact-key hit (those already short-circuit) or a cold seed (no restore). Has no effect when `target-cache` is off (the default). required: false default: "1" build-cache-mode: description: > Rust build cache mode. "thin" (the resolved default when `target-cache` is opted in) is the bounded dependency-artifact shape. "once" preserves the legacy full-snapshot-on-miss behavior that restores only the local rust-plan bundle on later hits without resaving the full target tree. "full" opts into normal whole-target restore/save behavior and should be treated as unbounded. Empty default resolves to "thin" when `target-cache: true` is set (either explicitly or via `cache-preset: full`); otherwise empty resolves to "once" — which is unused when target-cache is off but is still surfaced via the `SETUP_SOLDR_BUILD_CACHE_MODE` env var for downstream tools that read it. (#251) required: false default: "" seed-isolated-build-cache: description: > Optional newline- or comma-separated list of isolated SOLDR_CACHE_DIR roots to pre-seed from the build-cache this action restores (issue #240). Use this when a later self-test phase deliberately switches to a fresh SOLDR_CACHE_DIR for daemon isolation (e.g. coverage / integration jobs following zccache#430/#421) — without seeding, that isolated phase discards the warm build-cache and recompiles from scratch every run. setup-soldr copies ONLY the content-addressed zccache artifact store (the same file classes the build-cache save keeps: artifacts and their in-place compiler stdout/stderr replay metadata) into `/cache/zccache` for each listed root. Live daemon state — logs, sockets, pidfiles, lock/temp files, and standalone diagnostics — is never copied, so the isolated daemon keeps its own session. Best-effort: seed failures are logged, never fatal. Default empty (no seeding). required: false default: "" zccache-seed-strict: description: > When "true", fail setup if setup-soldr cannot seed soldr's pinned zccache install from the vendored or managed release source. Default "false" keeps the seed best-effort and allows soldr's normal managed fallback path. Enable this in repos where a later zccache `cargo install` fallback is unacceptable. required: false default: "false" target-cache: description: > DEPRECATED AND INERT with soldr >= the release containing zackees/soldr#3001. Soldr removed its target cache entirely: the `rust_plan` machinery that consumed SOLDR_TARGET_CACHE_* was deleted, so this layer has nothing left to drive and setting it has no effect. It remains declared so existing workflows do not fail on an unexpected input, and it still functions for a pinned older soldr. Use `soldr cook` instead -- it is the durable dependency cache, and zackees/soldr#2996 measured it both smaller and faster than the target cache it replaces (497.4 MiB vs 635.0 MiB on one lane, 378.4 s saved per warm run). Empty (default) resolves to "false" unless `cache-preset: full` overrides it. (#251 cache-preset) required: false default: "" target-cache-mode: description: > DEPRECATED AND INERT -- see `target-cache`. Translated into build-cache-mode; "hot" maps to "thin", "full" maps to "full", and "off" disables Rust target artifact caching. With a soldr that has dropped the target cache, every value behaves the same: nothing happens. required: false default: "" target-dir: description: > Cargo target directory. Its only remaining consumers are cache-key shaping and the cook layer; the Rust artifact cache plan it was named for no longer exists (see `target-cache`). required: false default: target target-cache-profile: description: > Thin-slice pruning policy for the target/ cache. Values: - thin-v1 (default): legacy slice, keeps .rlib/.rmeta/proc-macro outputs - thin-v2: aggressive prune (fingerprints + dep-info + final outputs only), relies on zccache compilation cache to repopulate library bytes - thin-v3: ownership-aware cache contract. Currently uses the safe `zccache-all-v1` fallback until Soldr can prove a complete cook package/artifact closure; its cache keys are separate from thin-v1 and thin-v2. thin-v1 remains the default. Use thin-v2 or thin-v3 only with a Soldr release that advertises the matching plan schema. thin-v3 deliberately falls back to zccache-all until complete cook ownership is available. required: false default: thin-v1 target-cache-strip-debuginfo: description: > When "true", requests that soldr strip debug-info-bearing artifacts from the target-cache before saving. Forward-compatible: requires soldr#237 to take effect; current soldr releases ignore the flag. Default "" (unset - soldr default applies). required: false default: "" target-cache-include-incremental: description: > When "false", requests that soldr exclude target/*/incremental/ directories from the target-cache. Forward-compatible: requires soldr#237 to take effect. Default "" (unset - soldr default applies). required: false default: "" target-cache-include-build-script-binaries: description: > When "false", requests that soldr exclude target/*/build/*-{hash}/build-script-build binaries from the target-cache. Forward-compatible: requires soldr#237 to take effect. Default "" (unset - soldr default applies). required: false default: "" target-cache-compress: description: > Compression codec used when packing the target-cache tar archive. Values: "auto" (let soldr decide), "zstd" (force zstd), or "none" (uncompressed). Default "zstd". Forward-compatible: requires a soldr release that consumes SOLDR_TARGET_CACHE_COMPRESS; older soldr releases ignore the setting and fall back to their built-in behavior. required: false default: "zstd" target-cache-compress-level: description: > Compression level used when target-cache-compress is "zstd" (or "auto" and soldr selects zstd). Accepts integers 1-22. Empty (the default) picks the runner profile: "3" on GitHub-hosted runners, "1" on a local runner (ACT=true, e.g. act/act2 under bosn), which has no cache budget and a fast disk. An explicit value always wins on both. Forward-compatible: requires a soldr release that consumes SOLDR_TARGET_CACHE_COMPRESS_LEVEL. required: false default: "" cache-payload-warn-bytes: description: > Soft notice threshold for tar-backed cache saves, measured before compression. Accepts bytes or KiB/MiB/GiB/TiB suffixes. When exceeded, setup-soldr emits a notice with the largest files so oversized payloads such as multi-GiB zccache archives are visible in CI. Empty (the default) picks the runner profile: 512MiB on GitHub-hosted runners, 4GiB on a local runner (ACT=true, e.g. act/act2 under bosn). An explicit value always wins on both. required: false default: "" cache-payload-max-bytes: description: > Hard limit for tar-backed cache saves, measured before compression. Empty (the default) picks the runner profile: 6GiB on GitHub-hosted runners, 0 (no cap) on a local runner (ACT=true, e.g. act/act2 under bosn), which has no Actions-cache budget. An explicit value always wins on both. The GitHub 6GiB matches the realistic zccache footprint for a medium-large Rust workspace (zccache CI itself was running at 4-5 GiB and chronically hitting the previous 2GiB cap → build-cache became enabled-but-inert, see setup-soldr#279). Set to 0 to disable the limit. When exceeded, cache-payload-oversize-action decides whether setup-soldr skips the save or fails the post step. The GitHub Actions Cache service caps individual entries at ~10 GiB and per-repo total at 10 GiB; 6GiB sits comfortably below both. required: false default: "" cache-payload-oversize-action: description: > Behavior when cache-payload-max-bytes is exceeded. "skip" logs a warning and does not upload the cache entry. "fail" treats the oversized payload as a cache packaging error. Ignored when no payload cap applies (cache-payload-max-bytes is 0, or empty on a local runner). required: false default: "skip" cache-encrypt-key: description: > Optional 256-bit AES key used to encrypt every managed cache layer's `.tar.zst` archive with AES-256-GCM before upload, and to verify + decrypt the same archives on restore. Accepts the key as 64-char hex, 44-char base64, or 43-char base64url. Pass via a GitHub Actions secret reference in your workflow (see the "Release-grade usage: encrypted cache" section of the README for a copy-pasteable example). setup-soldr immediately marks the value as a secret so it cannot leak into log output. Use this on release pipelines to prevent cache poisoning: an attacker who can write to the Actions Cache for this repo (forked PR with cache-write scope, leaked GITHUB_TOKEN, etc.) cannot plant a malicious tarball under one of setup-soldr's cache keys without possessing the AES key — the GCM tag verification will fail and the tampered archive is rejected. Empty (default) keeps the historical plaintext path; encryption adds a per-archive disk read+write pass (~5 s per GiB on a typical SSD) so it should remain opt-in. Mixed-mode tolerant: a legacy plaintext entry is accepted with a warning when the key is set, and an encrypted entry restored without a key is treated as a cold miss (lets you rotate keys without wiping the cache). See #387 Feature 1. required: false default: "" cache-encrypt-on-failure: description: > What to do when an encrypted cache entry fails authentication (wrong `cache-encrypt-key`, tampered ciphertext, or AAD mismatch). `error` (default) raises a hard error in red so the release run stops before consuming the bad cache. `skip` logs the failure and treats the entry as a cold miss, letting the run continue with a fresh build. Has no effect when `cache-encrypt-key` is empty. required: false default: "error" cache-payload-top-n: description: > Number of largest files and directories retained in cache payload stats, stats-json, and the final step summary. Set to 0 to suppress top-entry lists while keeping aggregate bytes/files/skipped counts. required: false default: "10" source-mtime-normalize: description: > Opt-in. When "true", rewrite the mtime of tracked Rust build-input files under the GitHub Actions workspace to each file's last-commit timestamp before the target-cache restore runs. This keeps Cargo fingerprints stable across fresh checkouts of the same SHA so restored target caches can be reused as a no-op. Files with no git history are left alone, so real source edits still invalidate fingerprints. Defaults to "false". required: false default: "false" cargo-registry-cache: description: > When "true", setup-soldr manages a separate actions/cache step for ~/.cargo/registry. The legacy-v1 codec stores registry plus the companion ~/.cargo/.global-cache and ~/.cargo/git payloads in one tar+zstd archive. The opt-in Soldr-v2 codec stores registry in a Soldr archive for parallel extraction and keeps only those two companions in a second tar+zstd archive. Windows 2025 benchmark run 31089551078 measured Soldr-v2 at 25,881.275 ms versus legacy-v1 at 9,669.428 ms (0.37x), so legacy-v1 remains the default. Set SOLDR_CARGO_REGISTRY_VIA_SOLDR=1 to opt into v2; unset or 0/false/no/off selects legacy-v1. Encryption, a source-ref build, or Soldr older than 0.7.47 retains legacy-v1. When zstd is absent on Windows, v2 fetches the pinned, SHA-256-verified upstream zstd 1.5.7 executable into RUNNER_TEMP. The Cargo GC database prevents each job from seeing fresh access times and conservatively retaining everything; ~/.cargo/git contains bare mirrors and checkouts for git-source crate dependencies. Missing companions are silently skipped. See setup-soldr#102. Also exports SOLDR_SKIP_CARGO_REGISTRY_SAVE=1 so the zccache CLI's built-in cargo-registry save (honored in zccache >=1.4.4) no-ops and the payload is not double-saved. When this input is empty and `prebuild-deps: soldr-cook` is active, setup-soldr enables this required companion automatically so a fresh job rematerializes both compiled dependency artifacts and their registry/git sources. Set "false" explicitly to opt out. Deliberately NOT cached on this layer: ~/.cargo/.package-cache and ~/.cargo/.package-cache-mutate are cargo's "another build is running" mutex files — caching them causes false "another cargo is running" errors on the next job. ~/.cargo/credentials.toml is a secret and must not be persisted. The list is enforced by exclusion: we cache explicit basenames (registry, .global-cache, git) rather than the full $CARGO_HOME so accidentally-staged secrets never enter the archive. Empty (default) resolves to "true" when `prebuild-deps: soldr-cook` is active, otherwise "false"; cache presets may override it explicitly. (#251, #470) required: false default: "" ci-tests: description: > Prepare the prescribed CI-test domain without running a hidden test command. CARGO_BUILD_JOBS and SOLDR_JOBS remain unset unless the workflow sets them. Only NEXTEST_TEST_THREADS defaults to one unless the workflow sets it. Dylint remains an explicit separate-toolchain opt-in. Call the repository's explicit test command after this action. Cache contract (soldr#2931): linked test products — integration-test executables, benches, examples built for tests, doctest products, their debug sidecars, and test-specific incremental state — are never persisted by any cache layer. Because a ci-test lane's entire output is those products, setting this to "true" additionally refuses a bulk `target/` snapshot: if `build-cache-mode` resolves to "full" with target caching on, the mode is degraded to "thin" and a warning is emitted. Tier-1 cook dependency compilation and the tier-2 per-unit zccache store are unaffected. Omit `ci-tests` if a job genuinely needs the bulk snapshot. The resolved layers are reported by the `cache-policy-json` output. required: false default: "false" dylint: description: > Enable Dylint mode. Default "false": setup-soldr performs no nightly map request, toolchain restore/install, environment substitution, or Dylint-specific cache preparation. When "true", the action maps the resolved Rust major.minor version to the newest compatible dated nightly, runs `soldr dylint prepare` to materialize and verify the pinned tools/components/driver, exports the managed tool directories, and scopes that identity to Soldr's Dylint child processes. required: false default: "false" dylint-foundation-cache: description: > Cache the exact Dylint nightly, required components, tools, and driver. Defaults to "true" inside Dylint mode and is inert when dylint is false. required: false default: "true" dylint-output-cache: description: > Reserve Dylint's isolated plugin/workspace output cache policy. Defaults to "true" inside Dylint mode and is inert when dylint is false. required: false default: "true" dylint-cache: description: > Explicit opt-in cache for Dylint tooling. When "true", setup-soldr restores and saves a cache slot for cargo-dylint, dylint-link, Cargo install metadata, and the compatible Dylint driver directory. This is cache-only: cold runs still execute the workflow's normal install/build steps, while warm runs can skip them by checking the dylint-cache-hit output or SETUP_SOLDR_DYLINT_CACHE_HIT environment variable. Default "false" keeps normal Rust setup unchanged. required: false default: "false" dylint-toolchain: description: > Nightly Rust toolchain used by the Dylint driver, e.g. nightly-2026-03-26. Empty defaults to the action's resolved toolchain. Included in the Dylint cache key. required: false default: "" dylint-targets: description: > Comma- or whitespace-separated canonical Rust target triples (for example x86_64-pc-windows-msvc, aarch64-apple-darwin) for cross-platform Dylint check-only passes, in addition to the host. When set, setup-soldr prepares rust-std for every listed target alongside the host and folds the full target set into the Dylint foundation/output cache identity, so each declared target set gets its own warm cache generation (ci.yml#9). Empty runs Dylint on the host target only. Aliases are rejected the same way cross-targets rejects them. required: false default: "" dylint-driver-rev: description: > Git revision or version identity for the compatible Dylint driver source. Included in the Dylint cache key. Use the same revision your driver build script checks out. required: false default: "" cargo-dylint-version: description: cargo-dylint version materialized by Soldr in Dylint mode. Included in the Dylint cache key. required: false default: "6.0.3" dylint-link-version: description: dylint-link version materialized by Soldr in Dylint mode. Included in the Dylint cache key. required: false default: "6.0.3" dylint-cache-paths: description: > Optional newline- or comma-separated paths to restore/save for dylint-cache. Relative paths are resolved from the workspace. Empty uses $CARGO_HOME/bin/cargo-dylint*, $CARGO_HOME/bin/dylint-link*, $CARGO_HOME/.crates.toml, $CARGO_HOME/.crates2.json, and $RUNNER_TEMP/dylint-drivers. required: false default: "" shims: description: > When "true", setup-soldr writes PATH-shadowing shims for cargo, rustfmt, clippy-driver, rustc, and rustdoc into ${cache-dir}/shims/ and prepends that directory to $PATH. Each shim routes its invocation through the installed soldr binary. Default "false". required: false default: "false" compile-cache-stats: description: > Controls compile-cache (zccache) diagnostic output. "none" suppresses all compile-cache info. "summarize" (default) renders a per-session totals table into $GITHUB_STEP_SUMMARY and emits scalar action outputs (hit rate, hits, misses, etc.). "detailed" adds per-extension and per-tool rollup tables and sets compile-cache-rollups-json. "insights" extends summarize with per-diagnosis
blocks rendered from `soldr cache report --json`'s `diagnoses[]` array, emits GitHub annotations (::warning::/::notice::) pinned to the relevant source files, and best-effort uploads a chrome-trace artifact (`setup-soldr-trace-.json`) when the installed soldr supports `cache report --chrome-trace`. required: false default: "summarize" verify-compile-cache: description: > Guard against silently-bypassed compile caching. When a job is expected to exercise zccache but the session reports hits + misses == 0, the build was not routed through the cache (bypass) or the measurement is invalid — reporting that as a successful warm cache is misleading. Values: "off" (default, no check), "warn" (emit a GitHub Actions warning with the likely bypass cause), "error"/"true" (fail the post step). Legitimate bypasses are always skipped, never failed: enable:false passthrough, build-cache:false, an unreadable compile-cache report, or unavailable hit/miss counters. The diagnostic names RUSTC_WRAPPER, SOLDR_CACHE_DIR, ZCCACHE_CACHE_DIR, the shims dir, and the session stats path so the bypass is actionable. Sets the compile-cache-verification output to ok / invalid-measurement / skipped. required: false default: "off" stats: description: > Controls diagnostic output for cache operations. "none" suppresses all stats output. "summarize" (default) prints a compact hit/miss table after setup. "detailed" adds full JSON stats to the log, writes $RUNNER_TEMP/setup-soldr-stats.json and $RUNNER_TEMP/setup-soldr-session.log (updated by the post phase with save operations), and sets the stats-json output. required: false default: "summarize" debug: description: > When "true", enables verbose per-operation diagnostics: archive magic bytes, compressed/inflated byte counts, file counts, compression ratios, and the exact decompression/compression commands run. required: false default: "false" journal-print-raw: description: > When "true", the post-phase diagnostic dump appends the verbatim per-rustc-invocation JSONL stream from `${ZCCACHE_CACHE_DIR}/logs/last-session.jsonl` to stdout. Default is empty, which mirrors `debug` (so users who set `debug: true` keep the pre-existing forensic dump). Set to "false" to suppress the raw stream even when debug is on — useful for workflows that already upload the JSONL as an artifact and don't want to pay the log-writer cost (the raw stream is often thousands of records / 20-30 MB and can add 30-50 s to the post step on hosted runners). Accepts "true"/"false"/"on"/"off"/"yes"/"no"/"1"/"0". required: false default: "" rust-backtrace: description: > Value to export as `RUST_BACKTRACE`. Default "1" so any unexpected panic in `soldr cargo …` (or anything else downstream of this action) emits a backtrace immediately — saving a re-run to capture context after the fact. Accepts "1"/"true"/"on"/"yes" (trimmed backtrace, default), "full" (full stack including std internals), or "0"/"false"/"off"/"no"/"" to skip the export and keep whatever the calling environment had. Has no effect on release builds with `panic = "abort"` (Rust doesn't print a backtrace in that case) and only fires on panic — there's no runtime cost for builds that don't panic. required: false default: "1" cache-shutdown-on-idle: description: > Configure the cache daemon (zccache / sccache) to self-exit after this much idle time. Accepts bare integers (seconds), "s", "m", or "h". The empty string and "0"/"off"/"false" disable the override and let the daemon use its built-in timeout. When set, setup-soldr exports both `ZCCACHE_IDLE_TIMEOUT` and `SCCACHE_IDLE_TIMEOUT` to the resolved seconds so the daemon dies between idle compile invocations and respawns on next use — a workaround for daemons that accumulate state or hold locks across a long build. The post step always calls `soldr cache shutdown` (falling back to `zccache stop` when needed) as a final best-effort sweep regardless of this setting. required: false default: "" logging: description: > When "true", emit a one-shot "DIAGNOSTIC DUMP" section after the main step (post-resolve) and again at the end of the post step. The dump includes every observed `INPUT_*` env var (so you can see what the runner actually passed in), the parsed RawInputs struct, every constructed cache key with its restore-key fallbacks, all restore/save outcomes, key SOLDR_/ZCCACHE_ env exports, and the compile-cache report. Token-shaped values are redacted. Use this when cache behavior surprises you — captures everything needed to file a bug without having to re-run with extra flags. Distinct from `debug`, which only adds a few targeted `[debug]` lines. required: false default: "false" preserve-source-mtimes: description: > Experimental. When "true", snapshot every tracked Rust source file's (mtime, size, content-hash) at cold-post time and replay the mtime onto matching files on warm — *only* when the current content is byte-identical to the snapshot. Solves the case where `actions/checkout` resets every source mtime on each run, which otherwise makes Cargo invalidate every fingerprint and bypass zccache's compile cache. The size+hash safety net means we cannot underbuild the way the abandoned `source-mtime-normalize` could: if a source file genuinely changed between cold and warm (e.g., a patch landed at the same SHA range), its current mtime is left alone and Cargo rebuilds correctly. Snapshot is a small JSON sidecar shipped inside the existing build-cache tar.zst. required: false default: "false" solo-toolchain-cache: description: > Maintain a long-lived, small, per-platform cache that holds only what setup-soldr added to `$RUSTUP_HOME/toolchains/` and `$CARGO_HOME/bin/` on top of the runner image. On warm runs, the toolchain is restored from cache (~3-5 s) instead of installed via rustup (~7-11 s). Save layer short-circuits when the install delta is empty (the common case on hosted runners that already ship rustup + stable). Default "true" (validated end-to-end on Linux/macOS/Windows; see #305/#316/#321/#324/#326/#328/#331/#335/#343). Pass "false" to opt out — useful when the workflow installs components AFTER setup-soldr (the snapshot won't include them) or when the warm-cycle win isn't worth the ~12 s first cold-save. If a restored entry fails validation, setup-soldr repairs the requested toolchain and targets, deletes the poisoned entry, and uploads the verified replacement. Automatic deletion requires `actions: write` on the workflow GITHUB_TOKEN; a missing permission is reported visibly. required: false default: "true" solo-toolchain-cache-level: description: > zstd compression level for the solo-toolchain-cache archive. Empty (the default) picks the runner profile: "9" on GitHub-hosted runners, "1" on a local runner (ACT=true, e.g. act/act2 under bosn). An explicit value always wins on both. GitHub "9" — measured save = ~12 s on a 140 MB delta vs "19" which measured at ~104 s (zccache CI v0.9.35, see #310). The archive grows ~25% at -9 (140 MB → 175 MB), restore stays bandwidth-bound at ~70 MB/s either way — the extra MB only adds ~0.5 s per restore. Saves the win only after ≥ ~180 restores at the same key, which is rare in practice (every rustc release / soldr version bump invalidates). Users with truly long-lived workflows can override to "19" or "22". required: false default: "" cache-eviction-policy: description: > Repo-level Actions Cache eviction policy run in the post-step (#347). When the repo's cache usage exceeds the trigger threshold, evict the OLDEST per-commit / per-lockfile entries (cook-delta, build-cache, etc.) until under the target, while NEVER touching foundation prefixes (solo-toolchain, cargo-registry, soldr-mini, setup-cache). Prevents LRU from pushing out the small long-lived caches that deliver the big warm-CI wins. Requires `actions: write` permission on the workflow's GITHUB_TOKEN; falls back to a no-op with a warning if permission is missing. Values: - "disabled" (default): no eviction. Current behavior. - "protect-foundations": trigger at 8 GB, target 7 GB. - "aggressive": trigger at 6 GB, target 5 GB. required: false default: "disabled" prebuild-deps: description: > Pre-build dependencies via `soldr cook` before the workflow's own cargo invocations. "soldr-cook" is the named long-enduring dependency cache mode; "cargo-chef" remains a compatibility alias for older workflows. When the cache hits on the Cargo.lock hash, target/deps/ is pre-warmed so the user's first build starts hot. Empty (default) resolves to "soldr-cook" — every preset (minimal/foundation/full) keeps cook on, so opt out explicitly with `prebuild-deps: none` if you want to skip. Other values reserved for future strategies. (#251 cache-preset) Cache key is content-addressable on (os, arch, libc, rustc_release, flags_hash, Cargo.lock hash, soldr_version) — same Cargo.lock hits across branches with zero parent-ladder logic. See CLAUDE.md "Cache-lifetime axis". Skipped when `cache: false` or no Cargo.lock is found. Failures are logged but never fail the action — the user's normal cargo build still runs and succeeds. required: false default: "soldr-cook" prebuild-deps-flags: description: > Additional flags forwarded to `soldr cook`. The profile MUST match what the job actually compiles or the cooked artifacts are never reused: pass empty ("") for dev/debug jobs (cargo check/clippy/doc/test), keep "--release" only for jobs that build a release artifact. Examples: "--release --target x86_64-unknown-linux-musl", "--profile release-lto", "--workspace". These flags are hashed into the cache key — different flags = different cache entry. See README "Match cook to what your job actually compiles". required: false default: "--release" prebuild-deps-delta-cache: description: > When "true" (default), setup-soldr uses soldr's protobuf-backed layered cook cache for compatible soldr releases. The base layer is long-lived and Cargo.lock-oriented; the delta layer is commit/build shape-oriented and should stay small for normal code-only changes. Set to "false" to fall back to the legacy single cook archive for rollback/debugging. Requires soldr 0.7.38 or newer; older releases automatically use the legacy cook cache path. required: false default: "true" cook-delta: description: > true | false (default "false"). Controls only the commit/build-shape delta layer (`cook-delta-v2-*`) that the layered cook cache stacks on top of the base archive. With "false" the base cook archive (`cook-base-v2-*`) is still restored, and saved per `save-cache`, but no delta is restored or saved. Set "true" to restore the pre-#528 behavior of restoring and saving a delta on top of the base. Has no effect when `prebuild-deps-delta-cache: false` selects the legacy single cook archive. required: false default: "false" cross-targets: description: > Optional one canonical Rust target triple for the `soldr prepare` lifecycle (for example, aarch64-apple-darwin). Exactly one target is accepted per job; use a matrix for multiple targets. Soldr owns compiler, linker, SDK, sysroot, environment, and capability selection. The action exports Soldr's target plan, capabilities, environment, cache identity, artifact directory, and operation hooks. Builds use soldr build --target. cache: false disables only prepared-state archive caching. The packaging target universal2-apple-darwin provisions both real Apple Rust targets; it is never requested as a Rust standard-library target. Default empty. When caching is enabled, prepared compiler/SDK archives are cached automatically with stable host + target + Soldr-repository restore prefixes. A new Soldr release reuses the prior toolchain archive, then downloads only genuinely changed assets and promotes the result to its own immutable exact key. This avoids repeatedly fetching large soldr-toolchain LFS payloads such as LLVM, GNU/Linux, MinGW, musl, xwin, and Apple SDK bundles. required: false default: "" soldr-mini-cache: description: > Cache the soldr binary in its own tiny long-lived layer, keyed only on (version, os, arch, libc). Avoids re-downloading from GitHub Releases when other cache layers (which mix in toolchain hash + cache-key-suffix) invalidate but the soldr binary itself is unchanged. Default "true". Set "false" to disable. Skipped automatically when `enable: false` or `ref` is set (rebuilding from source — binary content depends on commit not version). required: false default: "true" outputs: enabled: description: > "true" when the action installed the real soldr binary, "false" when the action installed the passthrough stub (input `enable: false`). soldr-path: description: Installed Soldr binary path added to PATH for later steps. soldr-version: description: > Installed Soldr version reported by `soldr version --json`. The literal string "passthrough" when `enable: false`. prepared-target: description: Canonical target prepared by Soldr, or empty. blessed-prepare-cache-key: description: Exact immutable cache key for the Soldr prepared-state archive, or empty. blessed-prepare-cache-hit: description: Whether the exact prepared-state archive was restored. target-plan-json: description: Stable JSON target lifecycle plan reported by Soldr after preparation. target-capabilities-json: description: Stable JSON canonical target, cache identity, toolchain, platform, and supported operations. target-env-json: description: JSON target-scoped environment exported by Soldr's target plan. target-cache-identity: description: Soldr-reported cache identity for the canonical target lane. target-artifact-dir: description: Target directory where target-specific build artifacts are emitted, or empty when build is not advertised. target-build-hook: description: Blessed target build command when advertised; otherwise empty. target-clippy-hook: description: Target clippy command when advertised; otherwise empty. target-test-hook: description: Target test-harness compilation command when advertised; otherwise empty. target-wheel-hook: description: PEP 517 frontend command for wheel production when advertised; otherwise empty. target-sdist-hook: description: PEP 517 frontend command for source distribution production when advertised; otherwise empty. cache-dir: description: Runner-local cache/state root used by the action. setup-duration-seconds: description: Total wall-clock time spent inside the setup-soldr action. setup-phase-summary: description: JSON timing summary for the main setup phases and cache restore statuses. cache-hit: description: Whether the action restored an exact cache hit for the selected cache/state root. cache-key: description: Primary key used for the action-managed cache/state root. cache-restore-status: description: Diagnostic restore status for the action-managed cache/state root. cache-preset-effective: description: > The resolved `cache-preset` value (one of "minimal", "foundation", "full") that filled unset cache-affecting inputs this run. Empty string when no preset was set. (#251) cache-policy-json: description: > JSON statement of the cache-ownership policy this lane resolved to (soldr#2931). Shape: `{"schema":1,"layers":[...],"target_tree_snapshot":bool, "test_products":"never","ci_tests":bool, "ci_tests_target_tree_refused":bool}`. `layers` is ordered by the stability gradient and drawn from "toolchain", "cargo-registry", "cook", "zccache-unit", "target-bundle" | "target-tree", "dylint-foundation", "dylint-output". `test_products` is the constant "never": linked test binaries, benches, examples built for tests, doctest products and their debug sidecars are not cacheable at any layer. `ci_tests_target_tree_refused` is true when `ci-tests: true` degraded `build-cache-mode` from "full" to "thin". Also exported as `SETUP_SOLDR_CACHE_POLICY_JSON`. cook-cache-hit: description: Whether the long-lived dependency base was restored and loaded for usable rematerialization; a compatible delta hit is reported separately. cook-cache-base-hit: description: Whether the long-lived Cargo.lock-oriented cook base archive was restored and loaded. cook-cache-delta-hit: description: Whether the compatible build-shape cook delta archive was restored and loaded on top of the base. cook-cache-status: description: Dependency-rematerialization transport status (disabled, miss, base-hit, hit, or covered-by-target-cache). cook-cache-load-report-json: description: JSON load diagnostics for the base and delta archives, including restored-file and mtime replay counters. cargo-registry-cache-hit: description: Whether the Cargo registry/git source half of the dependency-rematerialization closure restored an exact cache key. build-cache-hit: description: > Whether the action restored the Soldr-owned zccache compilation artifact cache. "true" for an exact key match, "false" for a restore-key fallback or no cache, empty string when `build-cache` is explicitly disabled. build-cache-key: description: Primary key used for the Soldr-owned zccache compilation cache. build-cache-matched-key: description: Actual usable build-cache entry restored, or empty on a miss. build-cache-ancestor-json: description: Opt-in ancestor selection telemetry (candidate ID/key, identity, distance, write key, scan/API time, request count and rate limit); empty for legacy selection. Candidate selection alone does not prove a usable restore. build-cache-path: description: Soldr-owned zccache compilation cache path. build-cache-mode: description: Effective setup-soldr Rust build cache mode. build-cache-restore-status: description: Diagnostic restore status for the Soldr-owned zccache compilation cache. target-cache-hit: description: > Whether the action restored the zccache-owned Rust artifact cache state. "true" for an exact key match, "false" for a restore-key fallback or no cache, empty string when `target-cache` or `build-cache` is disabled. target-cache-key: description: Primary key used for the zccache-owned Rust artifact cache state. target-cache-path: description: Cargo target directory used by soldr for Rust artifact planning. target-cache-paths: description: Path or newline-delimited path list passed to actions/cache for zccache-owned Rust artifact cache state. target-cache-mode: description: Effective setup-soldr Rust target artifact cache mode. target-cache-profile: description: Effective setup-soldr thin-slice pruning policy (thin-v1, thin-v2, or thin-v3). target-cache-compress: description: Effective target-cache compression codec (auto, zstd, or none). target-cache-compress-level: description: Effective target-cache compression level (1-22) applied when zstd is selected. target-cache-restore-status: description: Diagnostic restore status for the Rust target artifact cache state. target-cache-budget-bytes: description: Soft byte budget used to warn when the restored Rust artifact cache footprint is likely too large for fast CI reuse. target-cache-budget-files: description: Soft file-count budget used to warn when the restored Rust artifact cache footprint is likely too large for fast CI reuse. target-cache-footprint-bytes: description: Observed byte size of the restored Rust artifact cache footprint across the cache paths selected for the current mode. target-cache-footprint-files: description: Observed file count of the restored Rust artifact cache footprint across the cache paths selected for the current mode. target-cache-budget-status: description: Soft-budget diagnostic for the restored Rust artifact cache footprint. target-lockfile: description: Cargo.lock path used for Rust artifact cache keying. target-lockfile-hash: description: Short hash of the Cargo.lock used for Rust artifact cache keying, or no-lock. dylint-cache-hit: description: Whether the opt-in Dylint tool/driver cache restored an exact key hit. dylint-cache-key: description: Primary key used by the opt-in Dylint tool/driver cache. dylint-cache-restore-status: description: Diagnostic restore status for the opt-in Dylint tool/driver cache. dylint-driver-path: description: Dylint driver directory exported as DYLINT_DRIVER_PATH when dylint-cache is enabled. dylint-toolchain: description: Selected dated nightly scoped to Dylint mode. dylint-rustc-release: description: Mapped compiler release for the selected Dylint nightly. dylint-rustc-commit-hash: description: Full mapped compiler commit for the selected Dylint nightly. dylint-cache-identity: description: Nightly channel, compiler release, and full commit cache identity. dylint-targets: description: > Comma-separated resolved target set (host + declared dylint-targets, deduped and sorted) folded into the Dylint foundation/output cache identity. Compare across runs to confirm a target-set change produced a new cache generation instead of colliding with an unrelated one. dylint-output-cache-hit: description: Whether the isolated Dylint project-output cache restored an exact key. dylint-output-cache-key: description: Exact isolated Dylint project-output cache key. dylint-output-cache-paths: description: Newline-delimited Dylint plugin and workspace output paths. dylint-output-cache-restore-status: description: Diagnostic restore status for the isolated Dylint project-output cache. toolchain: description: Exact Rust toolchain channel configured by rustup for the action. stats-json: description: > JSON string containing full cache stats (restores + saves with byte counts, durations, and hit/miss status). Only set when stats is "detailed". shims-dir: description: Path to the directory containing the PATH shims written by setup-soldr. compile-cache-session-status: description: Compile-cache session status (ok / missing / unsupported / error). compile-cache-verification: description: > Result of the verify-compile-cache zero-count guard: "ok" (the cache observed cacheable work), "invalid-measurement" (hits + misses == 0 while compile caching was expected — bypassed or invalid), or "skipped" (the check did not run, e.g. verify-compile-cache: off or a legitimate bypass). compile-cache-hit-rate: description: Compile-cache hit rate (0.0–1.0) for the last session, or empty when unavailable. compile-cache-hits: description: Compile-cache hit count for the last session. compile-cache-misses: description: Compile-cache miss count for the last session. compile-cache-compilations: description: Total compilation count for the last session. compile-cache-time-saved-ms: description: Estimated compile time saved (ms) for the last session. compile-cache-bytes-read: description: Cache bytes read during the last session. compile-cache-bytes-written: description: Cache bytes written during the last session. compile-cache-rollups-json: description: > JSON-encoded rollups object (by_extension, by_tool_total_ms) from soldr cache report. Only set when compile-cache-stats is "detailed". compile-cache-summary-json: description: > Full soldr cache report JSON payload (one-shot consumer hook). Set whenever soldr cache report succeeds (status "ok"). compile-cache-sessions-total: description: > Total number of cargo invocations whose per-session stats were archived under `/logs/archive/` during the job. Only set when more than one session was observed (multi-step jobs); the empty value lets downstream steps gate on `steps.setup.outputs.compile-cache-sessions-total`. Added in setup-soldr#98 PR4. compile-cache-overall-hit-rate: description: > Compile-cache hit rate (0.0–1.0) computed across every per-invocation session archived during the job (weighted by compilations, NOT the unweighted mean of per-session rates). Only set alongside compile-cache-sessions-total when more than one session was observed. Added in setup-soldr#98 PR4. runs: using: node24 main: dist/main.js post: dist/post.js # always() so the post step (and its unconditional cache-daemon # shutdown) fires on job failure too. saveOne is already best-effort # — missing dirs and save errors are logged, not raised — so running # the full post pipeline on failure cannot brick the run. post-if: always()