Bump @actions/cache to 5.1.0, handle cache write denied (#1026)

This commit is contained in:
Jason Ginchereau
2026-06-21 22:16:01 -10:00
committed by GitHub
parent baa1691374
commit 6e9017e125
7 changed files with 126 additions and 22 deletions
+52 -5
View File
@@ -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"}}');
/***/ })