Changelog
All notable changes to BoringCache CLI are documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
1.31.0 - 2026-09-18
Added
- Publish any single file at an immutable public path with
boringcache artifact publish. Publication works with managed or BYOC
storage and reuses Artifact workload identity, provider checksums, and signed
Artifact receipts. Static tokens require admin access. The command checks
public response headers after upload; --verify-download also downloads and
hashes the public object.
- Address Docker and BuildKit cache mounts under their own namespace with
--mount-namespace (repo plan mount-namespace), so two jobs that need
independent image graphs can still share cache mounts: give each job its own
--tag and both the same namespace. A bare value covers every mount and
MOUNT_ID=NAMESPACE addresses one --mount=type=cache id, so a shared
registry can sit beside separate target directories. Mounts you do not name
keep the tag’s identity. Requires --mount-cache.
- Publish a shared cache-mount namespace without losing another job’s files.
A job that finds the namespace published since its own restore merges the
published files it does not have, keeps its own copy of every shared path,
and commits against the snapshot it merged. A job that loses that race
merges again and retries instead of skipping its save. A publication the
server declines to promote fails the save rather than reporting success, and
the merge restore honors the same signed-cache-hit requirement as the job’s
own restore. Deleted files are not propagated between jobs.
boringcache cargo --phase restore and boringcache cargo --phase save run
one cache phase around a job’s own Cargo commands instead of wrapping a single
command. A phase runs no Cargo command and ignores [adapters.cargo].command,
so a job that runs several Cargo commands caches all of them. The restore
phase records whether the checkout was clean in a job-scoped document under
the system temporary directory, keyed by the target path, so the save phase
cannot publish a target restored into a dirty checkout that was later tidied
up. The record stays out of the target directory, so a restore miss leaves
the target empty for the retry. That record only withdraws publication; the
save phase still checks the checkout itself.
--phase is Cargo-only, rejects a command, and rejects
--skip-restore/--skip-save. A cache phase with no token reports the
missing token instead of trying to run an empty command.
--phase-evidence-json writes a cache_phase_evidence.v1 document for a
cache phase: its duration, transferred and logical bytes, snapshot and
transfer durations, entry count, and whether the publish moved any bytes.
A publish that transferred nothing is reported as unchanged.
Changed
- Download stable BoringCache release assets from
artifacts.boringcache.com first, with the exact GitHub release as a
same-version fallback. Installer downloads use bounded timeouts and retries.
gha takes its workspace from the approved workload binding when the broker
reports one, so a separately configured workspace cannot drift out of
agreement with the binding. An explicit --workspace remains valid for the
static token mode and as an override, and one that disagrees with the binding
refuses readiness instead of being attempted.
gha reports a backend refusal as a typed Twirp error naming the workspace
and the operation: 401 as unauthenticated, 403 as permission_denied, and
404 as not_found. Only transport failures and unexpected responses remain
internal. Cache actions previously saw a bare 500 with no cause.
gha makes one bounded workspace check at startup. A workspace the workload
capability cannot see now publishes a refusal to its ready file and exits,
so the supervisor can run the job without a cache instead of answering every
cache call with an error.
- Record whether managed BuildKit step timing was reported, still pending, or
unavailable after the build command. Cache-session reports can distinguish
interrupted builds from builds with complete vertex timing.
- Collect aggregate task outcomes for Turbo, Nx, and Gradle adapter commands
and attach them to cache-session summaries. Run reports separate remote or
build-cache hits, local hits, already-current tasks, skipped tasks, executed
tasks, and failures without storing task names or cache keys.
- Add runner OS and architecture, CLI version, and post-build publication drain
duration to structured cache-session summaries so run reports can separate
environment and save work from the remaining workflow span.
- Verify BoringCache-signed in-toto/DSSE publication receipts after Artifact
uploads and before Artifact restores. Older Artifacts without a receipt
remain usable with a warning, and JSON output reports the verification
result.
- Update the managed ccache HTTP storage helper to
0.10.
- Update mise in the runtime and build base images to
2026.9.7.
- Update the managed Docker builder to BuildKit
v0.33.0-bc.4. One
daemon-wide limit admits one to four cache-mount archive worker processes
from the BuildKit CPU budget and reports active, queued, peak, and wait
metrics.
- A live OCI stream that fails to reopen and keeps its original response no
longer reports the reopen attempt’s sleep and header wait as a peer pause,
so other proxy-session reads do not widen their slow-read windows for it.
- Size adaptive buffers and concurrency from cgroup v2 memory limits and live
usage on Linux. Ancestor limits are included, and
memory.high reduces new
allocation admission without being treated as the hard memory limit.
- Keep OCI and KV demand, prefetch, sequential, and ranged storage reads within
one proxy-session request budget. Slow-read recovery now considers concurrent
peer throughput and pauses. Archive and CAS restores retain their separate
command-wide adaptive budget. OCI range rescue fans out to its configured
stream count under that session budget and no longer runs a per-rescue
byte-shaped adaptive limiter.
- Download and unpack an archive cache in one phase instead of waiting for
every blob before extraction starts. Blobs are fetched in the order the tar
stream consumes them, each chunk is decoded as soon as its own blob lands,
and restore reports unpacked bytes with speed and ETA while the remaining
blobs arrive. Storage pressure produced by a restore’s own extraction no
longer reduces that restore’s download concurrency.
Fixed
- Retry a transient brokered workload capability refresh with bounded backoff
instead of failing the publication. A single gateway or server error during a
long build no longer discards the whole build’s cache export. A denied
capability is still reported immediately and is never retried.
- Bound the first automatic eager-startup burst for large small-object caches,
wait for a reduced limit to take effect before reducing it again, and carry
Bazel’s learned action-result limit into closure hydration.
- Recover a stalled
artifact pull by refreshing its signed download request
after repeated zero progress and restarting the verified representation from
byte zero when the refreshed range also stalls.
- Write tracing diagnostics to stderr so
RUST_LOG output does not corrupt
structured command output on stdout.
- Apply and verify valid ad hoc code signatures after assembling the universal
macOS CLI and Xcode adapter release assets.
1.30.4 - 2026-09-10
Fixed
- Reuse archive graph decoder threads and zstd contexts across chunks to reduce
large archive restore materialization time.
1.30.3 - 2026-09-10
Fixed
- Align BuildKit smoke and end-to-end test defaults with the managed
v0.33.0-bc.2 image.
1.30.2 - 2026-09-10
Changed
Fixed
-
Use retained byte progress to adapt shared download admission after a slow-body
probe retries. A probe no longer independently halves capacity for unrelated
objects; transport failures and native resource pressure retain their backoff.
-
Use the same download recovery for archive chunks and proxy files. Retry
stalled response headers within bounded budgets, honor bounded server retry
delays, and refresh rejected cached URLs without restarting the retry budget.
Keep startup prefetch within that budget and use actual retries to adapt its
concurrency. After recovery opens a fresh connection, subsequent downloads
use its replacement pool. Print terminal transport causes without signed
storage URLs.
- Retry slow archive and OCI chunk downloads even when the chunk or resumed
remainder is small. Check throughput within two seconds of collecting bytes,
keep completed downloads, and report recovered download retries accurately.
-
Recover slow live OCI reads and proxy file downloads, including slow resumed
tails and sequential fallback after range rescue fails. Use the shared
progress policy after every reopen and avoid repeating a failed range fan-out.
Preserve byte progress and let the final attempt finish while its idle
deadline and integrity checks remain active.
- Preserve changed source timestamps after successful Cargo commands so repeated
--skip-save builds can reuse their local artifacts.
- Compress and stage identical chunks only once within each archive save.
- Use Action 1.30.1 in generated GitHub Actions workflows and workflow diagnostics.
1.30.1 - 2026-09-09
Added
- Configure managed Docker and BuildKit workers with a native
buildkitd.toml.
The CLI discovers the nearest file within the project; --buildkitd-config
or an adapter’s buildkitd-config repo setting selects another file.
Workers are recreated when settings or referenced registry certificates change.
- Limit the managed BuildKit worker’s CPU quota and CPU affinity with
BORINGCACHE_MANAGED_BUILDKIT_CPUS and
BORINGCACHE_MANAGED_BUILDKIT_CPUSET_CPUS.
Fixed
- Use Action 1.30.0 in generated GitHub Actions workflows and workflow diagnostics.
1.30.0 - 2026-09-09
Changed
- Update the managed Docker builder to BuildKit 0.33.0 with the BoringCache
backend, retaining an immutable image digest and existing cache behavior.
Fixed
- Use Action 1.21.0 in generated GitHub Actions workflows.
1.21.0 - 2026-09-08
Added
- Configure archive exclusions with
exclude in .boringcache.toml entries,
or add patterns with --exclude-pattern when an adapter such as Cargo saves
archive entries.
Fixed
- Publish Artifacts from OIDC jobs using authenticated workload provenance,
including providers whose job identity differs from the job name.
- Report missing Docker cache references without implying the entire build has
no cache, and explain cache startup waits and retries in plain language.
- Refresh OIDC credentials inside Docker cache-mount workers throughout long
builds, preserving restore-only permissions and normal cache publication.
- Refresh product credentials on HTTP retries and use Registry-scoped OIDC
credentials for Docker image publication.
- Share compiler cache Git and platform scoping between Cargo and sccache while
keeping Cargo archive scoping independent.
- Bound captured-output draining after a command exits, so background processes
retaining its output pipes cannot leave the cache lifecycle waiting forever.
- Update the embedded zstd library to 0.14.0 while retaining the existing
archive format and canonical cache identity.
- Keep archive and CAS restore download concurrency steady across overlapping
transfers, while retaining immediate backoff when a transfer fails.
- Record archive save and restore phase timings and available resource counters
so slow local processing can be distinguished from network transfer time.
1.20.5 - 2026-09-07
Fixed
- Keep native CI cache startup reliable across normal control-plane and broker
response latency by clamping each workload capability to the remaining
parent session lifetime.
1.20.4 - 2026-09-06
Fixed
- Accept server-issued workload capabilities across normal request latency by
clamping their local lifetime to the remaining parent session lifetime.
- Start the Actions compatibility service in restore-only mode whenever the
brokered workload session is restore-only, so Workspace publication policy
narrows a job without failing runner readiness.
- Explain when a valid CI workload is restore-only and direct users to a
trusted job or the Machine connection publication policy instead of showing
only a local broker 403 response.
1.20.3 - 2026-09-04
Added
- Enroll native BoringBuild workload identity with
boringcache ci connect --oidc-provider boringbuild, using the job’s
controller-issued renewable assertion and browser-approved Workspace
selection without a stored BoringCache secret.
- Acquire renewable CircleCI OIDC assertions with
--oidc-provider circleci
through the in-job Environment CLI, BoringCache’s audience, and CircleCI’s
root issuer, without a CircleCI API token or stored BoringCache secret.
- Use GitLab.com’s job-scoped
BORINGCACHE_OIDC_TOKEN directly with
--oidc-provider gitlab, binding immutable job namespace/project identity
while keeping merge-request and fork source jobs restore-only.
Changed
- Keep native GitLab’s private broker session for the bounded lifetime of its
job assertion, up to one hour, while continuing to issue five-minute product
capabilities and recheck live publication policy on every issuance. This
lets ordinary GitLab jobs run without exposing or replaying their OIDC token
and keeps existing providers compatible with released clients.
1.20.2 - 2026-09-03
Changed
- Checkpoint cumulative proxy diagnostics every five minutes while continuing
to deliver completed cache-operation rollups every 30 seconds, bounding
retained session state and repeated reporting work in long builds.
Fixed
- Keep Windows archive monitor requests on bounded blocking connections so a
partially delivered local observation cannot prematurely stop unchanged-cache
reuse.
- Route archive monitor failures through the configured diagnostic output so a
fail-closed reuse decision retains its actionable cause.
- Preserve each cache-operation rollup’s idempotency identity across delivery
retries so a transient reporting failure cannot duplicate its counters.
1.20.1 - 2026-09-03
Added
- Let Docker and BuildKit repo plans own optional native tool-cache and
cache-mount composition used by local runs and the thin GitHub Action.
Fixed
- Preserve managed Docker Cargo target reuse when an unchanged source tree is
materialized with newer mtimes.
- Forward
SCCACHE_IDLE_TIMEOUT into Docker-native sccache builds so long link
phases do not let the compiler-cache daemon exit early.
1.20.0 - 2026-09-02
Added
- Publish customer-facing CLI release notes from this changelog as part of every release.
- Add
boringcache system requirements <adapter> --check so automation can
fail before cache setup when a required helper is missing or incompatible.
- Let an interactive administrator enroll an exact provider-neutral OIDC
issuer through
boringcache onboard without creating a fallback CI token.
- Add
boringcache ci run to acquire renewable provider OIDC assertions,
supervise one runner-local workload broker, and run Cache or Artifact
commands without exposing or falling back to static BoringCache credentials.
- Add
boringcache ci connect with browser-approved Workspace selection and
in-memory enrollment for native CI providers, plus explicit stdin enrollment
for registered issuers and automation. Neither path creates a reusable
BoringCache credential.
- Acquire renewable Buildkite OIDC assertions with
--oidc-provider buildkite
and no hand-written token command, forge connection, or BoringCache secret.
- Acquire renewable GitHub Actions OIDC assertions with
--oidc-provider github-actions and the job’s native id-token: write
permission, without a GitHub App or stored BoringCache secret.
Changed
- Resolve GHA cache workspace from the committed repo plan when
gha-cache
receives no explicit workspace, and include that resolved workspace in the
service ready document consumed by GitHub integrations.
- Name credentials created by the provider-neutral onboarding path for CI
instead of GitHub Actions.
- Update the managed ccache HTTP storage helper to 0.9.
- Tell users to install adapter prerequisites through their normal project or
workflow setup instead of claiming that BoringCache One installs them.
Fixed
- Accept exact version output from tools such as
ccache-storage-http that
return a nonzero status for their version probe.
1.19.7 - 2026-08-29
Added
- Allow a workflow job to download artifacts produced by another job in the same workflow run while keeping cross-run access denied.
Fixed
- Retry temporary cache publication conflicts without misreporting them as permanent tag conflicts.
1.19.6 - 2026-08-28
Changed
- Promote the exact tested CLI candidate bytes into the public release instead of rebuilding platform artifacts during publication.
Fixed
- Preserve project-selected Maven extension versions when enabling Maven cache support.