v1.1.0 – actions/cache-Compatible Paths, Versioned Ref-Scoped Keys & Cross-OS CI
🚀 Cloud Cache Action v1.1.0
v1.1 is a correctness release. path now behaves like actions/cache, S3 keys carry the Git ref and a cache version, dual-cache strict mode actually fails the step, and CI covers Linux, macOS, Windows, cross-OS restores and three self-hosted S3 servers.
Important
Caches saved by v1.0 are not reused. The S3 object layout changed, so every cache misses once on the first v1.1 run and is rebuilt. The action never reads v1.0 objects again; let a bucket lifecycle rule expire them.
⚠️ Breaking changes
- New key layout:
${GITHUB_REPOSITORY}/${prefix}${ref}/${key}/${version}/${archive_filename}.${version}hashes thepathpatterns, the compression method and, on Windows,enableCrossOsArchive, so a cache is never restored into a job that caches different paths. - Branch isolation like actions/cache: restores search the current ref, then the pull request base branch, then the default branch.
mainnever restores a feature branch's cache. Set the newscoped-to-ref: falseinput to share caches across all refs. save-alwaysremoved: it never worked, becausepost-ifcan't read inputs. To save after failed steps, usecloud-cache-action/restoreandcloud-cache-action/savewithif: always().dual-cache-strategy: independentremoved: it now logs a warning and behaves asbackfill.dual-cache-strict: truefails the step: it now fails on tier errors during restore and save. Previously save errors only produced warnings.
🐛 Fixes
pathpatterns go through@actions/glob, so~/.npm,**/node_modulesand!exclusions work. Previously they reached tar unexpanded and failed withCannot stat.- Archives store paths relative to
GITHUB_WORKSPACE.
- Archives store paths relative to
- tar selection matches actions/cache:
- GNU tar on Linux;
gtaror BSD tar on macOS; Git's GNU tar or System32 tar on Windows. - Two-step zstd with BSD tar on Windows.
MSYS=winsymlinks:nativestrictfor symlinks.- File names starting with
-can no longer inject tar options.
- GNU tar on Linux;
- Restore-key matching:
- Listing now reads every page. It used to stop after 100 keys, which made the "newest" match arbitrary.
- The primary key is tried as a prefix before
restore-keys, as in actions/cache. - Keys containing
/or$survive the round trip.
- Failed downloads or extractions count as a cache miss with a warning instead of failing the job.
backfillchecks the other tier first: it only archives and uploads to a tier that doesn't already have the key.- Retries:
retry-countnow sets the SDK's standard retries.- Stream retries only cover network failures the SDK doesn't retry itself.
- 403s and other permanent errors are no longer retried.
retry-count: 0is honoured.
- Checksums: S3-compatible providers (R2, GCS, B2, Garage, MinIO, …) only receive request checksums when S3 requires them.
- Warnings: unknown providers, invalid booleans and enum values, and a lone access or secret key now log a warning instead of being ignored.
- Consistency: the post step reuses the restore step's settings and compression method, so both steps compute the same object key.
- Branding: the
restoreandsavesub-actions now use valid icons.
✅ Testing
- Test suites: unit tests on real temporary directories, real tar round trips (symlinks, file modes, unicode, option-like file names), and a contract test that keeps all three
action.ymlmanifests in sync with the code. - Integration tests run the real restore and save code against SeaweedFS, MinIO and Garage, and fail instead of skipping when no server is available.
- CI on every pull request:
- Jest on Linux, macOS and Windows
- per-OS round trips through
./saveand./restore - post-step saves by the main action
- Linux → macOS/Windows cross-OS restores
- dual-cache against the live GitHub Actions Cache
- a strict-mode failure check
- actionlint
- Nightly: live cross-OS restores on Cloudflare R2.
📦 Upgrading
- uses: xSAVIKx/cloud-cache-action@v1 # now v1.1.0
with:
bucket: my-ci-cache-bucket
access-key: ${{ secrets.S3_ACCESS_KEY }}
secret-key: ${{ secrets.S3_SECRET_KEY }}
path: |
~/.npm
packages/*/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-save-always: if you set it, remove it and use the restore/save split shown in the README.- Custom
s3-key-pattern: add${ref}and${version}to it. The action warns when they're missing. - Storage: ref scoping stores a separate cache per branch and per pull request, so configure a bucket lifecycle rule (for example, expire after 30–60 days).
- Security: read Branch isolation and trust model. Anyone holding the bucket's write credentials can write cache objects.
Full changelog: v1.0.0...v1.1.0