Run Windows BSD tar/zstd extraction and listing in private temporary
directories. Concurrent operations previously overwrote cache.tar in the
process working directory and could extract the wrong archive without
reporting an error. Debug listings during cache saves have the same race.
Resolve and quote archive and workspace paths before changing the child
working directory, and remove scratch files on success and failure.
Leave GNU tar, gzip, and the cache archive format unchanged.
Add deterministic regression tests for concurrent reads, relative paths
with spaces, and cleanup after failures in either subprocess.
* feat(cache): surface cache read-denied as a distinct restore warning
Mirror the existing cache write-denied handling on the restore path. When
the receiver refuses a download URL because the run's token has no readable
cache scopes, it returns a twirp PermissionDenied (HTTP 403). The twirp
client wraps that 403 in a generic Error, so the stable 'cache read denied:'
prefix is embedded in the message rather than at the start.
- Add CACHE_READ_DENIED_PREFIX and CacheReadDeniedError
- Dispatch on the prefix in the restoreCacheV2 catch block (V2 only), log a
policy-specific warning, and report a cache miss so the run continues
- Add a test mirroring the write-denied coverage
* chore(cache): trim comments, bump to 6.2.0, add RELEASES entry
* refactor(cache): dispatch read-denied by error name to mirror write path
Re-throw CacheReadDeniedError from an inner try/catch around
GetCacheEntryDownloadURL and dispatch on typedError.name in the outer catch,
matching how saveCacheV2 handles CacheWriteDeniedError.
* feat(cache): handle read-denied on the v1 restore path
Extend the read-denied handling to Cache Service v1 so GHES (which forces v1
via _apis/artifactcache) is covered when read-scope enforcement ships there.
- Surface the receiver's error body message from getCacheEntry instead of a
generic status-code error, so the cache read denied: prefix reaches callers
- Re-throw CacheReadDeniedError from restoreCacheV1 and dispatch on it in the
outer catch, mirroring restoreCacheV2 and the write-denied v1 handling
- Add a v1 read-denied test
* refactor(cache): only surface receiver body for read-denied on v1
* test(cache): assert getCacheEntry only surfaces body for read-denied
* test(cache): cover non-read-denied getCacheEntry passthrough on v1
* refactor(cache): share read-denied prefix via constants to avoid drift
* feat(cache): skip restore/save per ACTIONS_CACHE_MODE
* test(cache): expand ACTIONS_CACHE_MODE skip coverage across v1/v2 and unknown modes
* fix copilot pr feedback
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* docs(cache): remove internal reference from cache-mode comment
* test(cache): merge redundant cache-mode skip tests and simplify read-denied handling
Address PR review feedback:
- Merge the duplicate restore/save skip test.each blocks into single blocks parametrized over ACTIONS_CACHE_SERVICE_V2.
- Drop the redundant CacheReadDeniedError catch arms; the typed error is not an HttpClientError so it already falls through to a non-fatal warning.
- Clarify why read-denied classification happens both in getCacheEntry and cache.ts (dependency-free internal module cannot import the typed error).
* refactor(cache): drop redundant CacheWriteDeniedError catch arms
Mirror the read-denied simplification on the save path. CacheWriteDeniedError
is not an HttpClientError and its name does not match the ReserveCacheError
arm, so it falls through to the same non-fatal warning. Logging behavior is
unchanged (warns, never fails the run) and the exported type is still thrown
internally for consumers and tests. Also refresh stale doc wording.
* test(cache): collapse redundant restore getCacheEntry-failure tests
The two restoreCache tests exercised the identical warning + cache-miss path
now that read-denied is no longer reclassified in the catch, so merge them into
one. The read-denied prefix detection that actually branches on the message is
covered by getCacheEntry tests in cacheHttpClient.test.ts.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* `@actions/cache`: convert to an ESM module
* Update the fixture to ESM syntax
* Update the cache workflows
* Bump `@actions/glob` to `0.6.1`
* Fix awaiting in the cache unit tests
* Fix a type issues in contracts
* Export the `DownloadOptions`/`UploadOptions` like before
* More cache test fixes
* Make the cache units tests better
* Add some more logging
* Add retries to restore-cache.mjs
Remove abandoned @azure/ms-rest-js dependency which pulls in node-fetch@v2, causing punycode deprecation warnings on Node.js 24+.
The TransferProgressEvent type is now imported from @azure/core-rest-pipeline instead.
- Update restoreCacheV2.test.ts, restoreCache.test.ts, saveCacheV2.test.ts, and saveCache.test.ts
- Change test expectations from core.warning to core.error for cache operation failures
- All tests now pass successfully
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
- Update isFeatureAvailable() to leverage ACTIONS_CACHE_SERVICE_V2 feature flag
- For v2: check ACTIONS_RESULTS_URL availability
- For v1: check either ACTIONS_CACHE_URL or ACTIONS_RESULTS_URL availability
- Change warning logs to error logs for cache failures
- Add comprehensive tests covering all scenarios
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>