cli

GitHub Actions

The preferred path is:

  1. install the CLI locally
  2. run boringcache onboard
  3. commit .boringcache.toml when it helps
  4. use the verified, immutable boringcache/one release commit in GitHub Actions

That keeps CI and local runs on the same workspace, entries, and cache profiles.

Example:

- uses: boringcache/one@b55458ec8a4165e3fd70b1a1645f518a2095ed02 # v1.13.99
  with:
    workspace: my-org/my-project
    cache-profiles: bundle-install
  env:
    BORINGCACHE_RESTORE_TOKEN: $
    BORINGCACHE_SAVE_TOKEN: $

For proxy-backed modes, boringcache/one also accepts first-class metadata-hints so sessions and misses stay grouped by stable labels instead of per-run noise:

- uses: boringcache/one@b55458ec8a4165e3fd70b1a1645f518a2095ed02 # v1.13.99
  with:
    mode: bazel
    workspace: my-org/my-project
    metadata-hints: |
      project=web
      tool=bazel
      lane=ci
  env:
    BORINGCACHE_RESTORE_TOKEN: $
    BORINGCACHE_SAVE_TOKEN: $

Keep those hints low-cardinality. Good values are project=web, benchmark=grpc-bazel, tool=gradle, lane=ci, or workflow=build. Avoid commit SHAs, run ids, timestamps, and cold/warm labels for normal sessions; BoringCache classifies new and recurring misses from cache target and lifecycle data.

If the repo already defines [proxy] or adapter metadata-hints in .boringcache.toml, boringcache/one inherits them through the CLI dry-run plan. Prefer repo config for durable defaults and use the action input only when the workflow needs an explicit override. The canonical repo-config starting points in Tool guides are meant to be shared between local CLI runs and GitHub Actions for exactly this reason.

If you are migrating an existing workflow and do not have repo config yet, raw entries and actions/cache-compatible path / key / restore-keys inputs still work.

If you already manage the tool-specific setup yourself and only want proxy lifecycle plus adapter env injection, the CLI now also supports direct adapter commands:

- run: |
    cat > .boringcache.toml <<'EOF'
    workspace = "my-org/my-project"

    [proxy]
    metadata-hints = ["project=web"]

    [adapters.turbo]
    tag = "turbo-main"
    command = ["pnpm", "turbo", "run", "build"]
    metadata-hints = ["tool=turborepo", "lane=ci"]
    EOF

- run: boringcache turbo
  env:
    BORINGCACHE_RESTORE_TOKEN: $
    BORINGCACHE_SAVE_TOKEN: $

You can still override a configured adapter from the workflow when needed:

- run: |
    boringcache turbo \
      --workspace my-org/my-project \
      --tag turbo-main \
      -- pnpm turbo run build
  env:
    BORINGCACHE_RESTORE_TOKEN: $
    BORINGCACHE_SAVE_TOKEN: $

Use boringcache/one when you want the action to keep owning tool setup such as Bazel rc files, Maven or Gradle cache config, buildx setup, or container networking. Keep the full commit pin and update it deliberately after verifying a newer public release. When you run boringcache docker directly in GitHub Actions, the CLI derives the same branch/default/PR human tags from GitHub metadata that archive and proxy flows use. The action path passes provider-neutral metadata so Docker cache artifacts report the resolved human import/export tags and CI context.

For Docker and BuildKit registry caches on pull requests, restore-only is the default. A PR-scoped human tag may be absent and return 404, so restore-only PRs import the CLI-planned base/default tags without gaining write access. If a workflow intentionally wants PR-scoped Docker writes, give the job a save-capable token and set save-on-pull-request: true; do that only when the PR write scope is isolated, not merely to make the PR tag exist. In PR context, the derived write target is the PR human tag.

Keep the proxy story simple in CI too:

Keep the trust model simple:

Read from pull requests. Write from trusted branches, tags, or manual jobs.