CI Cache Configuration
The ci.cache section of atmos.yaml configures the CI build cache. The cache restores a
well-known cache directory (the toolchain install path and anything else under the Atmos
cache root) at the start of a step and saves it back at the end, using the active CI
provider's cache store — the same store that actions/cache uses.
Quick Start
With this configuration, Atmos automatically restores the cache when it starts and saves it
when it exits (including on SIGINT/SIGTERM). You can also drive the cache explicitly with
the atmos ci cache subcommands regardless of the auto setting.
How It Works
The cache operates on a single well-known directory — the Atmos XDG cache root
(~/.cache/atmos by default). The toolchain is installed as a sub-path of this root, so a
single cache captures it. The cache key defaults to a value derived from the toolchain
lockfile (toolchain.lock.yaml) plus the OS and architecture, with a prefix restore-key
fallback — mirroring actions/cache.
Cache entries are write-once. To keep automatic and manual usage from conflicting, Atmos
records how each key was restored and whether it was saved: a save is skipped when the exact
key was an exact hit at restore time (content unchanged) or has already been saved. This is
the same cache-hit ⇒ skip save behavior as actions/cache.
Saving and restoring content require running inside a supported CI provider (GitHub Actions
today), which provides the runtime cache credentials (ACTIONS_RUNTIME_TOKEN and
ACTIONS_RESULTS_URL). GitHub withholds these credentials from run: steps, so
atmos ci cache can't reach the cache API directly from a run: step — wiring it up inside a
job always takes one of the approaches below. Outside a
supported CI provider, the cache is a no-op.
Configuration Reference
ci.cache.enabledMaster switch for the CI cache. The automatic hooks and the
atmos ci cachesubcommands only run when this istrue.Default:
falseci.cache.autoAutomatic behavior. One of:
off— no automatic behavior; use the subcommands manually.restore— restore on startup only.save— save on exit only.both— restore on startup and save on exit.
Default:
offci.cache.rootOverride the well-known cache directory that is archived. Honors
ATMOS_XDG_CACHE_HOME/XDG_CACHE_HOMEwhen unset.Default: the Atmos XDG cache directory (e.g.
~/.cache/atmos)ci.cache.pathsRoot-relative subpaths to include in the cache. When empty, the entire cache root is cached.
Default: the entire cache root
ci.cache.keyThe cache key. Supports Go templates with
{{.OS}},{{.Arch}}, and ahashFilesfunction (e.g.{{ hashFiles ".tool-versions" }}).Default: a key derived from the
toolchain.lock.yamlhash plus OS/archci.cache.restore_keysPrefix fallback keys tried (in order) when the exact key is absent, mirroring
actions/cacherestore-keys. Each entry also supports template syntax.Default: the default key's prefix (without the lockfile hash)
ci.cache.compressionArchive compression. Currently only
gzipis supported.Default:
gzip
Full Example
GitHub Actions Integration
GitHub's Actions cache service needs runtime credentials (ACTIONS_RUNTIME_TOKEN and ACTIONS_RESULTS_URL) that GitHub withholds from run: steps, so atmos ci cache restore/save can't reach the cache API directly from a run: step. Every approach below is a workaround for that, and they split on a single decision: do you let a native action store the cache, or use one of our actions to surface the credentials so Atmos's backend stores it?
- Native
actions/cache(the composite and explicit tabs) — Atmos only computes what to cache (the key and paths fromci.cache);actions/cachealready holds the credentials internally and does the storage. This exposes no runtime token to your job. - Atmos-managed (the scoped-token and ambient-token tabs) — Atmos's own backend (
atmos ci cache restore/save) does the storage via the GitHub Actions cache service. Thegithub-runtimeaction surfaces the withheld credentials so thoserun:steps can reach it.
Prefer the actions/cache composite (or the explicit form) — both expose no runtime token. Security ranking: no token (composite/explicit) > scoped token > ambient token. If you need Atmos to own restore/save, prefer mode: output (scoped) over mode: env (ambient).
- actions/cache · composite (recommended)
- actions/cache · explicit
- Atmos backend · scoped token
- Atmos backend · ambient token
One uses: — Atmos derives the key/paths, native actions/cache stores them, no runtime token.
- uses: cloudposse/atmos/actions/cache@v1 # pin to a release or SHA
- run: |
atmos toolchain install --default helm/helm@${{ env.HELM_VERSION }}
atmos toolchain env --format=github
Pros: no token; native isolation/eviction/cross-OS; least boilerplate.
Cons: one more Atmos action in the chain (it pins actions/cache internally).
The same as the composite, written out — useful when you want explicit control.
- name: Resolve Atmos cache key & paths
id: atmos-cache
run: atmos ci cache paths --format=github
- name: Cache Atmos toolchain
uses: actions/cache@v4
with:
key: ${{ steps.atmos-cache.outputs.key }}
path: ${{ steps.atmos-cache.outputs.path }}
restore-keys: ${{ steps.atmos-cache.outputs.restore-keys }}
- run: atmos toolchain install --default helm/helm@${{ env.HELM_VERSION }}
Pros: no token; full control over the actions/cache step.
Cons: three steps to wire by hand.
Atmos owns restore/save. github-runtime mode: output returns masked credentials as step outputs that you thread only into the cache steps.
- uses: cloudposse/atmos/actions/github-runtime@v1
id: ghr
- run: atmos ci cache restore
env:
ACTIONS_RUNTIME_TOKEN: ${{ steps.ghr.outputs.runtime-token }}
ACTIONS_RESULTS_URL: ${{ steps.ghr.outputs.results-url }}
- run: atmos toolchain install --default helm/helm@${{ env.HELM_VERSION }}
- if: always()
run: atmos ci cache save
env:
ACTIONS_RUNTIME_TOKEN: ${{ steps.ghr.outputs.runtime-token }}
ACTIONS_RESULTS_URL: ${{ steps.ghr.outputs.results-url }}
Pros: Atmos fully owns restore/save; token masked and scoped to the cache steps. Cons: the token still enters those steps; more YAML.
The simplest Atmos-managed form. github-runtime mode: env exports ACTIONS_* to $GITHUB_ENV for every later step.
- uses: cloudposse/atmos/actions/github-runtime@v1
with:
mode: env
- run: atmos ci cache restore
- run: atmos toolchain install --default helm/helm@${{ env.HELM_VERSION }}
- if: always()
run: atmos ci cache save
Pros: least YAML for the Atmos-managed path; works for any atmos ci cache subcommand.
Cons: the runtime token is ambient to every later run: step in the job (largest blast radius).
The actions ship inside the Atmos repository, so pin them to an Atmos release (@v1 moving major tag, @vX.Y.Z, or a commit SHA). Both actions' full sources are in actions/ — audit them before pinning.
Environment Variables
| Variable | Description |
|---|---|
ATMOS_CI_CACHE_ENABLED | Override ci.cache.enabled (true/false) |
ATMOS_CI_CACHE_AUTO | Override ci.cache.auto (off/restore/save/both) |
ATMOS_CI_CACHE_KEY | Override the cache key (--key) |
ATMOS_CI_CACHE_ROOT | Override the cache root (--root) |
ATMOS_CI_CACHE_PATHS | Override the cached paths (--path) |
ACTIONS_RUNTIME_TOKEN / ACTIONS_RESULTS_URL | Provided automatically inside a GitHub Actions runner; required for the GitHub Actions cache backend |
Related
atmos ci cache- Restore, save, list, and delete cache entries- CI Configuration - Configure CI integration
atmos toolchain- The toolchain that the cache warm-starts