mirror of
https://github.com/actions/toolkit.git
synced 2026-08-10 00:00:12 +02:00
feat: backport cache read-denied + ACTIONS_CACHE_MODE handling (5.2.0)
Backport of the read-denied and ACTIONS_CACHE_MODE cache-mode gating from the ESM v6.2.0 line (#2447) to the CommonJS v5 line, released as 5.2.0. Mirrors the earlier write-denied backport (#2435, 5.1.0). - Detect the `cache read denied:` prefix on download failures (v2 twirp path and v1 `_apis/artifactcache` path) and surface it as a core.warning without failing the run. - Honor ACTIONS_CACHE_MODE: skip restore when the effective cache-mode does not permit reads (none, write-only) and skip save when it does not permit writes (none, read), logging a single non-fatal core.info line. Unset or unrecognized modes are unchanged. - Add read-denied and cache-mode tests; bump to 5.2.0 with RELEASES entry. Co-authored-by: Copilot App <[email protected]> Copilot-Session: e96deec1-716e-4e14-acdf-a230139420a2
This commit is contained in:
co-authored by
Copilot App
parent
c6ca5e729f
commit
3b3db3879e
+34
-1
@@ -1,8 +1,10 @@
|
||||
import {downloadCache} from '../src/internal/cacheHttpClient'
|
||||
import {downloadCache, getCacheEntry} from '../src/internal/cacheHttpClient'
|
||||
import {getCacheVersion} from '../src/internal/cacheUtils'
|
||||
import {CompressionMethod} from '../src/internal/constants'
|
||||
import * as downloadUtils from '../src/internal/downloadUtils'
|
||||
import * as requestUtils from '../src/internal/requestUtils'
|
||||
import {DownloadOptions, getDownloadOptions} from '../src/options'
|
||||
import {HttpClientError} from '@actions/http-client'
|
||||
|
||||
jest.mock('../src/internal/downloadUtils')
|
||||
|
||||
@@ -57,6 +59,37 @@ test('getCacheVersion with enableCrossOsArchive as false returns version on wind
|
||||
}
|
||||
})
|
||||
|
||||
test('getCacheEntry throws a generic status-code error for non-read-denied failures', async () => {
|
||||
// Regression: a non read-denied failure must NOT leak the server's body
|
||||
// message; it should surface the generic status-code error.
|
||||
jest.spyOn(requestUtils, 'retryTypedResponse').mockResolvedValue({
|
||||
statusCode: 403,
|
||||
result: null,
|
||||
headers: {},
|
||||
error: new HttpClientError('some other server detail', 403)
|
||||
})
|
||||
|
||||
await expect(getCacheEntry(['key'], ['node_modules'])).rejects.toThrow(
|
||||
'Cache service responded with 403'
|
||||
)
|
||||
})
|
||||
|
||||
test('getCacheEntry surfaces the body message for a cache read denial', async () => {
|
||||
jest.spyOn(requestUtils, 'retryTypedResponse').mockResolvedValue({
|
||||
statusCode: 403,
|
||||
result: null,
|
||||
headers: {},
|
||||
error: new HttpClientError(
|
||||
'cache read denied: token has no readable scopes',
|
||||
403
|
||||
)
|
||||
})
|
||||
|
||||
await expect(getCacheEntry(['key'], ['node_modules'])).rejects.toThrow(
|
||||
'cache read denied: token has no readable scopes'
|
||||
)
|
||||
})
|
||||
|
||||
test('downloadCache uses http-client for non-Azure URLs', async () => {
|
||||
const downloadCacheHttpClientMock = jest.spyOn(
|
||||
downloadUtils,
|
||||
|
||||
Reference in New Issue
Block a user