From c9b6aee07e98596593e5709d3687092feeabe808 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Wed, 17 Jun 2026 10:52:02 -0400 Subject: [PATCH 1/4] Fix codeql workflow permissions (#993) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7a826123..1964b62f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -10,5 +10,8 @@ on: jobs: call-codeQL-analysis: + permissions: + actions: read + security-events: write name: CodeQL analysis uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main From bc52a13212ed712059892c2a00fd554f25c78125 Mon Sep 17 00:00:00 2001 From: George Adams Date: Wed, 17 Jun 2026 07:58:23 -0700 Subject: [PATCH 2/4] fix CodeQL permissions (#1025) --- .github/workflows/codeql-analysis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1964b62f..1816c150 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -12,6 +12,7 @@ jobs: call-codeQL-analysis: permissions: actions: read + contents: read security-events: write name: CodeQL analysis uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main From baa1691374336073bf9d31ab4c3ee6399dc3dcf3 Mon Sep 17 00:00:00 2001 From: Sean Proctor Date: Thu, 18 Jun 2026 05:47:02 +0200 Subject: [PATCH 3/4] fix: reject non-semver candidate versions in isVersionSatisfies (#1009) Distributions like JetBrains Runtime publish 4-segment versions such as '17.0.8.1+1080.1' that the semver package rejects. Both compareBuild and satisfies throw on these, which surfaced to users as "Error: Invalid Version: 17.0.8.1+1080.1" and aborted the whole install when any available version was non-semver. Guard with an early semver.valid check so unparseable versions are treated as a non-match. Co-authored-by: Claude Opus 4.7 (1M context) --- __tests__/util.test.ts | 6 +++++- dist/cleanup/index.js | 7 +++++++ dist/setup/index.js | 7 +++++++ src/util.ts | 8 ++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/__tests__/util.test.ts b/__tests__/util.test.ts index f41d2c91..310a180a 100644 --- a/__tests__/util.test.ts +++ b/__tests__/util.test.ts @@ -29,7 +29,11 @@ describe('isVersionSatisfies', () => { ['2.5.1+3', '2.5.1+3', true], ['2.5.1+3', '2.5.1+2', false], ['15.0.0+14', '15.0.0+14.1.202003190635', false], - ['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true] + ['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true], + // 4-segment versions (e.g. JetBrains Runtime '17.0.8.1+1080.1') are not + // valid semver — they should be rejected, not throw. + ['25.0.3+480.61', '17.0.8.1+1080.1', false], + ['17', '17.0.8.1+1080.1', false] ])( '%s, %s -> %s', (inputRange: string, inputVersion: string, expected: boolean) => { diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 4f3f4f1a..5b445475 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -52208,6 +52208,13 @@ function getDownloadArchiveExtension() { exports.getDownloadArchiveExtension = getDownloadArchiveExtension; function isVersionSatisfies(range, version) { var _a; + // Some distributions (e.g. JetBrains Runtime) publish 4-segment versions + // like '17.0.8.1+1080.1' that semver rejects. If the candidate version + // isn't valid semver, it can't match — bail out rather than letting + // compareBuild / satisfies throw. + if (!semver.valid(version)) { + return false; + } if (semver.valid(range)) { // if full version with build digit is provided as a range (such as '1.2.3+4') // we should check for exact equal via compareBuild diff --git a/dist/setup/index.js b/dist/setup/index.js index f393386b..8e259576 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -81039,6 +81039,13 @@ function getDownloadArchiveExtension() { exports.getDownloadArchiveExtension = getDownloadArchiveExtension; function isVersionSatisfies(range, version) { var _a; + // Some distributions (e.g. JetBrains Runtime) publish 4-segment versions + // like '17.0.8.1+1080.1' that semver rejects. If the candidate version + // isn't valid semver, it can't match — bail out rather than letting + // compareBuild / satisfies throw. + if (!semver.valid(version)) { + return false; + } if (semver.valid(range)) { // if full version with build digit is provided as a range (such as '1.2.3+4') // we should check for exact equal via compareBuild diff --git a/src/util.ts b/src/util.ts index 5fe84c52..679c9fe3 100644 --- a/src/util.ts +++ b/src/util.ts @@ -55,6 +55,14 @@ export function getDownloadArchiveExtension() { } export function isVersionSatisfies(range: string, version: string): boolean { + // Some distributions (e.g. JetBrains Runtime) publish 4-segment versions + // like '17.0.8.1+1080.1' that semver rejects. If the candidate version + // isn't valid semver, it can't match — bail out rather than letting + // compareBuild / satisfies throw. + if (!semver.valid(version)) { + return false; + } + if (semver.valid(range)) { // if full version with build digit is provided as a range (such as '1.2.3+4') // we should check for exact equal via compareBuild From 6e9017e1258fe913cf5ad9d78c874b028aa55235 Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Sun, 21 Jun 2026 22:16:01 -1000 Subject: [PATCH 4/4] Bump @actions/cache to 5.1.0, handle cache write denied (#1026) --- .licenses/npm/@actions/cache.dep.yml | 2 +- __tests__/cache.test.ts | 6 ++- dist/cleanup/index.js | 57 +++++++++++++++++++++++++--- dist/setup/index.js | 57 +++++++++++++++++++++++++--- package-lock.json | 12 +++--- package.json | 4 +- src/cache.ts | 10 ++++- 7 files changed, 126 insertions(+), 22 deletions(-) diff --git a/.licenses/npm/@actions/cache.dep.yml b/.licenses/npm/@actions/cache.dep.yml index 25b3a5b1..97906801 100644 --- a/.licenses/npm/@actions/cache.dep.yml +++ b/.licenses/npm/@actions/cache.dep.yml @@ -1,6 +1,6 @@ --- name: "@actions/cache" -version: 5.0.5 +version: 5.1.0 type: npm summary: Actions cache lib homepage: https://github.com/actions/toolkit/tree/main/packages/cache diff --git a/__tests__/cache.test.ts b/__tests__/cache.test.ts index df7a59bd..0fdc6344 100644 --- a/__tests__/cache.test.ts +++ b/__tests__/cache.test.ts @@ -291,10 +291,12 @@ describe('dependency cache', () => { await save('maven'); expect(spyCacheSave).toHaveBeenCalled(); expect(spyWarning).not.toHaveBeenCalled(); - expect(spyInfo).toHaveBeenCalled(); - expect(spyInfo).toHaveBeenCalledWith( + expect(spyInfo).not.toHaveBeenCalledWith( expect.stringMatching(/^Cache saved with the key:.*/) ); + expect(spyDebug).toHaveBeenCalledWith( + expect.stringMatching(/^Cache was not saved for the key:.*/) + ); }); it('saves with error from toolkit, should fail workflow', async () => { diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 5b445475..327c9470 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -49,7 +49,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.FinalizeCacheError = exports.ReserveCacheError = exports.ValidationError = void 0; +exports.FinalizeCacheError = exports.CacheWriteDeniedError = exports.CACHE_WRITE_DENIED_PREFIX = exports.ReserveCacheError = exports.ValidationError = void 0; exports.isFeatureAvailable = isFeatureAvailable; exports.restoreCache = restoreCache; exports.saveCache = saveCache; @@ -77,6 +77,26 @@ class ReserveCacheError extends Error { } } exports.ReserveCacheError = ReserveCacheError; +/** + * Stable prefix used by the cache receiver to signal that the token has + * no writable scopes (read-only cache policy). Consumers can match on + * this prefix to distinguish policy denials from ordinary contention. + */ +exports.CACHE_WRITE_DENIED_PREFIX = 'cache write denied:'; +/** + * Extends ReserveCacheError for source-compatibility: existing + * `instanceof ReserveCacheError` checks and `typedError.name === + * ReserveCacheError.name` paths keep working, while consumers that want to + * distinguish a policy denial can check for CacheWriteDeniedError.name. + */ +class CacheWriteDeniedError extends ReserveCacheError { + constructor(message) { + super(message); + this.name = 'CacheWriteDeniedError'; + Object.setPrototypeOf(this, CacheWriteDeniedError.prototype); + } +} +exports.CacheWriteDeniedError = CacheWriteDeniedError; class FinalizeCacheError extends Error { constructor(message) { super(message); @@ -387,7 +407,11 @@ function saveCacheV1(paths_1, key_1, options_1) { throw new Error((_d = (_c = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : `Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the data cap limit, not saving cache.`); } else { - throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${(_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message}`); + const detailMessage = (_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message; + if (detailMessage === null || detailMessage === void 0 ? void 0 : detailMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) { + throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${detailMessage}`); + } + throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${detailMessage}`); } core.debug(`Saving Cache (ID: ${cacheId})`); yield cacheHttpClient.saveCache(cacheId, archivePath, '', options); @@ -397,6 +421,9 @@ function saveCacheV1(paths_1, key_1, options_1) { if (typedError.name === ValidationError.name) { throw error; } + else if (typedError.name === CacheWriteDeniedError.name) { + core.warning(`Failed to save: ${typedError.message}`); + } else if (typedError.name === ReserveCacheError.name) { core.info(`Failed to save: ${typedError.message}`); } @@ -435,6 +462,7 @@ function saveCacheV1(paths_1, key_1, options_1) { */ function saveCacheV2(paths_1, key_1, options_1) { return __awaiter(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { + var _a; // Override UploadOptions to force the use of Azure // ...options goes first because we want to override the default values // set in UploadOptions with these specific figures @@ -470,7 +498,11 @@ function saveCacheV2(paths_1, key_1, options_1) { try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - if (response.message) { + // Skip the redundant inner warning when the receiver signalled a + // policy denial: the outer catch arm below will log a single + // customer-facing warning. + if (response.message && + !response.message.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) { core.warning(`Cache reservation failed: ${response.message}`); } throw new Error(response.message || 'Response was not ok'); @@ -479,6 +511,10 @@ function saveCacheV2(paths_1, key_1, options_1) { } catch (error) { core.debug(`Failed to reserve cache: ${error}`); + const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : ''; + if (errorMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) { + throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${errorMessage}`); + } throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache.`); } core.debug(`Attempting to upload cache located at: ${archivePath}`); @@ -503,6 +539,9 @@ function saveCacheV2(paths_1, key_1, options_1) { if (typedError.name === ValidationError.name) { throw error; } + else if (typedError.name === CacheWriteDeniedError.name) { + core.warning(`Failed to save: ${typedError.message}`); + } else if (typedError.name === ReserveCacheError.name) { core.info(`Failed to save: ${typedError.message}`); } @@ -51849,7 +51888,15 @@ function save(id) { return; } try { - yield cache.saveCache(packageManager.path, primaryKey); + const cacheId = yield cache.saveCache(packageManager.path, primaryKey); + if (cacheId === -1) { + // saveCache returns -1 without throwing when the cache was not saved, + // e.g. a reserve collision or a read-only token (fork PR). @actions/cache + // has already logged the reason at the appropriate severity, so just + // trace it instead of misreporting that the cache was saved. + core.debug(`Cache was not saved for the key: ${primaryKey}`); + return; + } core.info(`Cache saved with the key: ${primaryKey}`); } catch (error) { @@ -93808,7 +93855,7 @@ function randomUUID() { /***/ ((module) => { "use strict"; -module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.0.5","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}'); +module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.1.0","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}'); /***/ }) diff --git a/dist/setup/index.js b/dist/setup/index.js index 8e259576..f48cde26 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -49,7 +49,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.FinalizeCacheError = exports.ReserveCacheError = exports.ValidationError = void 0; +exports.FinalizeCacheError = exports.CacheWriteDeniedError = exports.CACHE_WRITE_DENIED_PREFIX = exports.ReserveCacheError = exports.ValidationError = void 0; exports.isFeatureAvailable = isFeatureAvailable; exports.restoreCache = restoreCache; exports.saveCache = saveCache; @@ -77,6 +77,26 @@ class ReserveCacheError extends Error { } } exports.ReserveCacheError = ReserveCacheError; +/** + * Stable prefix used by the cache receiver to signal that the token has + * no writable scopes (read-only cache policy). Consumers can match on + * this prefix to distinguish policy denials from ordinary contention. + */ +exports.CACHE_WRITE_DENIED_PREFIX = 'cache write denied:'; +/** + * Extends ReserveCacheError for source-compatibility: existing + * `instanceof ReserveCacheError` checks and `typedError.name === + * ReserveCacheError.name` paths keep working, while consumers that want to + * distinguish a policy denial can check for CacheWriteDeniedError.name. + */ +class CacheWriteDeniedError extends ReserveCacheError { + constructor(message) { + super(message); + this.name = 'CacheWriteDeniedError'; + Object.setPrototypeOf(this, CacheWriteDeniedError.prototype); + } +} +exports.CacheWriteDeniedError = CacheWriteDeniedError; class FinalizeCacheError extends Error { constructor(message) { super(message); @@ -387,7 +407,11 @@ function saveCacheV1(paths_1, key_1, options_1) { throw new Error((_d = (_c = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : `Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the data cap limit, not saving cache.`); } else { - throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${(_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message}`); + const detailMessage = (_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message; + if (detailMessage === null || detailMessage === void 0 ? void 0 : detailMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) { + throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${detailMessage}`); + } + throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${detailMessage}`); } core.debug(`Saving Cache (ID: ${cacheId})`); yield cacheHttpClient.saveCache(cacheId, archivePath, '', options); @@ -397,6 +421,9 @@ function saveCacheV1(paths_1, key_1, options_1) { if (typedError.name === ValidationError.name) { throw error; } + else if (typedError.name === CacheWriteDeniedError.name) { + core.warning(`Failed to save: ${typedError.message}`); + } else if (typedError.name === ReserveCacheError.name) { core.info(`Failed to save: ${typedError.message}`); } @@ -435,6 +462,7 @@ function saveCacheV1(paths_1, key_1, options_1) { */ function saveCacheV2(paths_1, key_1, options_1) { return __awaiter(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { + var _a; // Override UploadOptions to force the use of Azure // ...options goes first because we want to override the default values // set in UploadOptions with these specific figures @@ -470,7 +498,11 @@ function saveCacheV2(paths_1, key_1, options_1) { try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - if (response.message) { + // Skip the redundant inner warning when the receiver signalled a + // policy denial: the outer catch arm below will log a single + // customer-facing warning. + if (response.message && + !response.message.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) { core.warning(`Cache reservation failed: ${response.message}`); } throw new Error(response.message || 'Response was not ok'); @@ -479,6 +511,10 @@ function saveCacheV2(paths_1, key_1, options_1) { } catch (error) { core.debug(`Failed to reserve cache: ${error}`); + const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : ''; + if (errorMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) { + throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${errorMessage}`); + } throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache.`); } core.debug(`Attempting to upload cache located at: ${archivePath}`); @@ -503,6 +539,9 @@ function saveCacheV2(paths_1, key_1, options_1) { if (typedError.name === ValidationError.name) { throw error; } + else if (typedError.name === CacheWriteDeniedError.name) { + core.warning(`Failed to save: ${typedError.message}`); + } else if (typedError.name === ReserveCacheError.name) { core.info(`Failed to save: ${typedError.message}`); } @@ -77713,7 +77752,15 @@ function save(id) { return; } try { - yield cache.saveCache(packageManager.path, primaryKey); + const cacheId = yield cache.saveCache(packageManager.path, primaryKey); + if (cacheId === -1) { + // saveCache returns -1 without throwing when the cache was not saved, + // e.g. a reserve collision or a read-only token (fork PR). @actions/cache + // has already logged the reason at the appropriate severity, so just + // trace it instead of misreporting that the cache was saved. + core.debug(`Cache was not saved for the key: ${primaryKey}`); + return; + } core.info(`Cache saved with the key: ${primaryKey}`); } catch (error) { @@ -128099,7 +128146,7 @@ Object.defineProperty(exports, "YAMLWriter", ({ enumerable: true, get: function /***/ ((module) => { "use strict"; -module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.0.5","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}'); +module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.1.0","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}'); /***/ }) diff --git a/package-lock.json b/package-lock.json index 491644e0..7bc4b8e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "setup-java", - "version": "5.2.0", + "version": "5.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "setup-java", - "version": "5.2.0", + "version": "5.3.0", "license": "MIT", "dependencies": { - "@actions/cache": "^5.0.5", + "@actions/cache": "^5.1.0", "@actions/core": "^2.0.3", "@actions/exec": "^2.0.0", "@actions/glob": "^0.5.1", @@ -50,9 +50,9 @@ } }, "node_modules/@actions/cache": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.0.5.tgz", - "integrity": "sha512-jiQSg0gfd+C2KPgcmdCOq7dCuCIQQWQ4b1YfGIRaaA9w7PJbRwTOcCz4LiFEUnqZGf0ha/8OKL3BeNwetHzYsQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.1.0.tgz", + "integrity": "sha512-kTIj4YPrjjRPKSGlj7f8eq+Pijoy/SKBEbJcAwNsQTFGEF29NGqj1mqD02/PmhV6r4bRAixycexAWpmUJ2aCwg==", "license": "MIT", "dependencies": { "@actions/core": "^2.0.0", diff --git a/package.json b/package.json index 66e0e0f7..2ff28b9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "setup-java", - "version": "5.2.0", + "version": "5.3.0", "private": true, "description": "setup java action", "main": "dist/setup/index.js", @@ -29,7 +29,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@actions/cache": "^5.0.5", + "@actions/cache": "^5.1.0", "@actions/core": "^2.0.3", "@actions/exec": "^2.0.0", "@actions/glob": "^0.5.1", diff --git a/src/cache.ts b/src/cache.ts index 7d13839e..bb694140 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -146,7 +146,15 @@ export async function save(id: string) { return; } try { - await cache.saveCache(packageManager.path, primaryKey); + const cacheId = await cache.saveCache(packageManager.path, primaryKey); + if (cacheId === -1) { + // saveCache returns -1 without throwing when the cache was not saved, + // e.g. a reserve collision or a read-only token (fork PR). @actions/cache + // has already logged the reason at the appropriate severity, so just + // trace it instead of misreporting that the cache was saved. + core.debug(`Cache was not saved for the key: ${primaryKey}`); + return; + } core.info(`Cache saved with the key: ${primaryKey}`); } catch (error) { const err = error as Error;