diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml index 0cbc269..4b62284 100644 --- a/.github/auto_assign.yml +++ b/.github/auto_assign.yml @@ -6,7 +6,7 @@ addAssignees: false # A list of reviewers to be added to pull requests (GitHub user name) reviewers: - - phantsure + - kotewar - aparna-ravindra - tiwarishub - vsvipul diff --git a/.github/workflows/auto-assign-issues.yml b/.github/workflows/auto-assign-issues.yml index 23ddc28..fe7fa42 100644 --- a/.github/workflows/auto-assign-issues.yml +++ b/.github/workflows/auto-assign-issues.yml @@ -11,5 +11,5 @@ jobs: - name: 'Auto-assign issue' uses: pozil/auto-assign-issue@v1.4.0 with: - assignees: phantsure,tiwarishub,aparna-ravindra,vsvipul,bishal-pdmsft + assignees: kotewar,tiwarishub,aparna-ravindra,vsvipul,bishal-pdmsft numOfAssignee: 1 diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml index 4dcc612..d7161b1 100644 --- a/.github/workflows/auto-assign.yml +++ b/.github/workflows/auto-assign.yml @@ -1,6 +1,6 @@ name: 'Auto Assign' on: - pull_request: + pull_request_target: types: [opened, ready_for_review] jobs: diff --git a/.licenses/npm/@actions/cache.dep.yml b/.licenses/npm/@actions/cache.dep.yml index f3f6ad9..cb0614a 100644 --- a/.licenses/npm/@actions/cache.dep.yml +++ b/.licenses/npm/@actions/cache.dep.yml @@ -1,6 +1,6 @@ --- name: "@actions/cache" -version: 2.0.5 +version: 3.0.0 type: npm summary: homepage: diff --git a/README.md b/README.md index fd4ba82..586af06 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ See ["Caching dependencies to speed up workflows"](https://help.github.com/githu * Fixed download issue for files > 2GB during restore. * Updated the minimum runner version support from node 12 -> node 16. * Fixed avoiding empty cache save when no files are available for caching. +* Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. Refer [here](https://github.com/actions/cache/blob/v2/README.md) for previous versions @@ -28,7 +29,8 @@ If you are using this inside a container, a POSIX-compliant `tar` needs to be in * `path` - A list of files, directories, and wildcard patterns to cache and restore. See [`@actions/glob`](https://github.com/actions/toolkit/tree/main/packages/glob) for supported patterns. * `key` - An explicit key for restoring and saving the cache -* `restore-keys` - An ordered list of keys to use for restoring the cache if no cache hit occurred for key +* `restore-keys` - An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note +`cache-hit` returns false in this case. ### Outputs @@ -70,6 +72,8 @@ jobs: run: /primes.sh -d prime-numbers ``` +> Note: You must use the `cache` action in your workflow before you need to use the files that might be restored from the cache. If the provided `key` doesn't match an existing cache, a new cache is automatically created if the job completes successfully. + ## Implementation Examples Every programming language and framework has its own way of caching. @@ -170,33 +174,33 @@ jobs: build-linux: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v3 - - name: Cache Primes - id: cache-primes - uses: actions/cache@v3 - with: - path: prime-numbers - key: primes + - name: Cache Primes + id: cache-primes + uses: actions/cache@v3 + with: + path: prime-numbers + key: primes - - name: Generate Prime Numbers - if: steps.cache-primes.outputs.cache-hit != 'true' - run: ./generate-primes.sh -d prime-numbers - - - name: Cache Numbers - id: cache-numbers - uses: actions/cache@v3 - with: - path: numbers - key: primes + - name: Generate Prime Numbers + if: steps.cache-primes.outputs.cache-hit != 'true' + run: ./generate-primes.sh -d prime-numbers - - name: Generate Numbers - if: steps.cache-numbers.outputs.cache-hit != 'true' - run: ./generate-primes.sh -d numbers - - build-windows: - runs-on: windows-latest - steps: + - name: Cache Numbers + id: cache-numbers + uses: actions/cache@v3 + with: + path: numbers + key: primes + + - name: Generate Numbers + if: steps.cache-numbers.outputs.cache-hit != 'true' + run: ./generate-primes.sh -d numbers + + build-windows: + runs-on: windows-latest + steps: - uses: actions/checkout@v3 - name: Cache Primes diff --git a/RELEASES.md b/RELEASES.md index 59bb4a6..a7a3a6c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -11,4 +11,7 @@ - Added support for dynamic cache size cap on GHES. ### 3.0.3 -- Fixed avoiding empty cache save when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624)) \ No newline at end of file +- Fixed avoiding empty cache save when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624)) + +### 3.0.4 +- Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. ([issue](https://github.com/actions/cache/issues/689)) \ No newline at end of file diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts index b4dbba9..e9a505b 100644 --- a/__tests__/restore.test.ts +++ b/__tests__/restore.test.ts @@ -227,40 +227,6 @@ test("restore with no cache found", async () => { ); }); -test("restore with server error should fail", async () => { - const path = "node_modules"; - const key = "node-test"; - testUtils.setInputs({ - path: path, - key - }); - - const logWarningMock = jest.spyOn(actionUtils, "logWarning"); - const failedMock = jest.spyOn(core, "setFailed"); - const stateMock = jest.spyOn(core, "saveState"); - const restoreCacheMock = jest - .spyOn(cache, "restoreCache") - .mockImplementationOnce(() => { - throw new Error("HTTP Error Occurred"); - }); - const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); - - await run(); - - expect(restoreCacheMock).toHaveBeenCalledTimes(1); - expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); - - expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); - - expect(logWarningMock).toHaveBeenCalledTimes(1); - expect(logWarningMock).toHaveBeenCalledWith("HTTP Error Occurred"); - - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); - expect(setCacheHitOutputMock).toHaveBeenCalledWith(false); - - expect(failedMock).toHaveBeenCalledTimes(0); -}); - test("restore with restore keys and no cache found", async () => { const path = "node_modules"; const key = "node-test"; diff --git a/__tests__/save.test.ts b/__tests__/save.test.ts index 7598e0c..4a3ae39 100644 --- a/__tests__/save.test.ts +++ b/__tests__/save.test.ts @@ -267,7 +267,6 @@ test("save with large cache outputs warning", async () => { }); test("save with reserve cache failure outputs warning", async () => { - const infoMock = jest.spyOn(core, "info"); const logWarningMock = jest.spyOn(actionUtils, "logWarning"); const failedMock = jest.spyOn(core, "setFailed"); @@ -306,10 +305,10 @@ test("save with reserve cache failure outputs warning", async () => { expect.anything() ); - expect(infoMock).toHaveBeenCalledWith( + expect(logWarningMock).toHaveBeenCalledWith( `Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.` ); - expect(logWarningMock).toHaveBeenCalledTimes(0); + expect(logWarningMock).toHaveBeenCalledTimes(1); expect(failedMock).toHaveBeenCalledTimes(0); }); diff --git a/action.yml b/action.yml index b5460b7..3e158e3 100644 --- a/action.yml +++ b/action.yml @@ -9,7 +9,7 @@ inputs: description: 'An explicit key for restoring and saving the cache' required: true restore-keys: - description: 'An ordered list of keys to use for restoring the cache if no cache hit occurred for key' + description: 'An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.' required: false upload-chunk-size: description: 'The chunk size used to split up large files during upload, in bytes' diff --git a/dist/restore/index.js b/dist/restore/index.js index 06e8122..cc1c684 100644 --- a/dist/restore/index.js +++ b/dist/restore/index.js @@ -37317,6 +37317,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) { ...getCompressionProgram(), '-cf', cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), + '--exclude', + cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), @@ -46848,17 +46850,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) { checkKey(key); } const compressionMethod = yield utils.getCompressionMethod(); - // path are needed to compute version - const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, { - compressionMethod - }); - if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) { - // Cache not found - return undefined; - } - const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core.debug(`Archive Path: ${archivePath}`); + let archivePath = ''; try { + // path are needed to compute version + const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, { + compressionMethod + }); + if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) { + // Cache not found + return undefined; + } + archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); + core.debug(`Archive Path: ${archivePath}`); // Download the cache from the cache entry yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); if (core.isDebug()) { @@ -46868,6 +46871,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) { core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); yield tar_1.extractTar(archivePath, compressionMethod); core.info('Cache restored successfully'); + return cacheEntry.cacheKey; + } + catch (error) { + const typedError = error; + if (typedError.name === ValidationError.name) { + throw error; + } + else { + // Supress all non-validation cache related errors because caching should be optional + core.warning(`Failed to restore: ${error.message}`); + } } finally { // Try to delete the archive to save space @@ -46878,7 +46892,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) { core.debug(`Failed to delete archive: ${error}`); } } - return cacheEntry.cacheKey; + return undefined; }); } exports.restoreCache = restoreCache; @@ -46896,7 +46910,7 @@ function saveCache(paths, key, options) { checkPaths(paths); checkKey(key); const compressionMethod = yield utils.getCompressionMethod(); - let cacheId = null; + let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); core.debug('Cache Paths:'); core.debug(`${JSON.stringify(cachePaths)}`); @@ -46935,6 +46949,18 @@ function saveCache(paths, key, options) { core.debug(`Saving Cache (ID: ${cacheId})`); yield cacheHttpClient.saveCache(cacheId, archivePath, options); } + catch (error) { + const typedError = error; + if (typedError.name === ValidationError.name) { + throw error; + } + else if (typedError.name === ReserveCacheError.name) { + core.info(`Failed to save: ${typedError.message}`); + } + else { + core.warning(`Failed to save: ${typedError.message}`); + } + } finally { // Try to delete the archive to save space try { @@ -48994,31 +49020,19 @@ function run() { const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { required: true }); - try { - const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys); - if (!cacheKey) { - core.info(`Cache not found for input keys: ${[ - primaryKey, - ...restoreKeys - ].join(", ")}`); - return; - } - // Store the matched cache key - utils.setCacheState(cacheKey); - const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey); - utils.setCacheHitOutput(isExactKeyMatch); - core.info(`Cache restored from key: ${cacheKey}`); - } - catch (error) { - const typedError = error; - if (typedError.name === cache.ValidationError.name) { - throw error; - } - else { - utils.logWarning(typedError.message); - utils.setCacheHitOutput(false); - } + const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys); + if (!cacheKey) { + core.info(`Cache not found for input keys: ${[ + primaryKey, + ...restoreKeys + ].join(", ")}`); + return; } + // Store the matched cache key + utils.setCacheState(cacheKey); + const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey); + utils.setCacheHitOutput(isExactKeyMatch); + core.info(`Cache restored from key: ${cacheKey}`); } catch (error) { core.setFailed(error.message); diff --git a/dist/save/index.js b/dist/save/index.js index ef4d318..b0f3e41 100644 --- a/dist/save/index.js +++ b/dist/save/index.js @@ -37317,6 +37317,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) { ...getCompressionProgram(), '-cf', cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), + '--exclude', + cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), @@ -46790,24 +46792,12 @@ function run() { const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { required: true }); - try { - yield cache.saveCache(cachePaths, primaryKey, { - uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize) - }); + const cacheId = yield cache.saveCache(cachePaths, primaryKey, { + uploadChunkSize: utils.getInputAsInt(constants_1.Inputs.UploadChunkSize) + }); + if (cacheId != -1) { core.info(`Cache saved with key: ${primaryKey}`); } - catch (error) { - const typedError = error; - if (typedError.name === cache.ValidationError.name) { - throw error; - } - else if (typedError.name === cache.ReserveCacheError.name) { - core.info(typedError.message); - } - else { - utils.logWarning(typedError.message); - } - } } catch (error) { utils.logWarning(error.message); @@ -46946,17 +46936,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) { checkKey(key); } const compressionMethod = yield utils.getCompressionMethod(); - // path are needed to compute version - const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, { - compressionMethod - }); - if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) { - // Cache not found - return undefined; - } - const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core.debug(`Archive Path: ${archivePath}`); + let archivePath = ''; try { + // path are needed to compute version + const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, { + compressionMethod + }); + if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) { + // Cache not found + return undefined; + } + archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); + core.debug(`Archive Path: ${archivePath}`); // Download the cache from the cache entry yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); if (core.isDebug()) { @@ -46966,6 +46957,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) { core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); yield tar_1.extractTar(archivePath, compressionMethod); core.info('Cache restored successfully'); + return cacheEntry.cacheKey; + } + catch (error) { + const typedError = error; + if (typedError.name === ValidationError.name) { + throw error; + } + else { + // Supress all non-validation cache related errors because caching should be optional + core.warning(`Failed to restore: ${error.message}`); + } } finally { // Try to delete the archive to save space @@ -46976,7 +46978,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) { core.debug(`Failed to delete archive: ${error}`); } } - return cacheEntry.cacheKey; + return undefined; }); } exports.restoreCache = restoreCache; @@ -46994,7 +46996,7 @@ function saveCache(paths, key, options) { checkPaths(paths); checkKey(key); const compressionMethod = yield utils.getCompressionMethod(); - let cacheId = null; + let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); core.debug('Cache Paths:'); core.debug(`${JSON.stringify(cachePaths)}`); @@ -47033,6 +47035,18 @@ function saveCache(paths, key, options) { core.debug(`Saving Cache (ID: ${cacheId})`); yield cacheHttpClient.saveCache(cacheId, archivePath, options); } + catch (error) { + const typedError = error; + if (typedError.name === ValidationError.name) { + throw error; + } + else if (typedError.name === ReserveCacheError.name) { + core.info(`Failed to save: ${typedError.message}`); + } + else { + core.warning(`Failed to save: ${typedError.message}`); + } + } finally { // Try to delete the archive to save space try { diff --git a/examples.md b/examples.md index 3a75eca..d9c4499 100644 --- a/examples.md +++ b/examples.md @@ -9,6 +9,7 @@ - [macOS](#macos) - [Windows](#windows-1) - [Elixir - Mix](#elixir---mix) +- [Erlang - Rebar3](#erlang--rebar3) - [Go - Modules](#go---modules) - [Linux](#linux-1) - [macOS](#macos-1) @@ -151,6 +152,18 @@ steps: ${{ runner.os }}-mix- ``` +## Erlang - Rebar3 +```yaml +- uses: actions/cache@v2 + with: + path: | + ~/.cache/rebar3 + _build + key: ${{ runner.os }}-erlang-${{ env.OTP_VERSION }}-${{ hashFiles('**/*rebar.lock') }} + restore-keys: | + ${{ runner.os }}-erlang-${{ env.OTP_VERSION }}- +``` + ## Go - Modules ### Linux @@ -210,6 +223,8 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba ## Haskell - Stack +### Linux or macOS + ```yaml - uses: actions/cache@v3 name: Cache ~/.stack @@ -227,6 +242,27 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba ${{ runner.os }}-stack-work- ``` +### Windows + +```yaml +- uses: actions/cache@v3 + name: Cache %APPDATA%\stack %LOCALAPPDATA%\Programs\stack + with: + path: | + ~\AppData\Roaming\stack + ~\AppData\Local\Programs\stack + key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }} + restore-keys: | + ${{ runner.os }}-stack-global- +- uses: actions/cache@v3 + name: Cache .stack-work + with: + path: .stack-work + key: ${{ runner.os }}-stack-work-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}-${{ hashFiles('**/*.hs') }} + restore-keys: | + ${{ runner.os }}-stack-work- +``` + ## Java - Gradle >Note: Ensure no Gradle daemons are running anymore when your workflow completes. Creating the cache package might fail due to locks being held by Gradle. Refer to the [Gradle Daemon documentation](https://docs.gradle.org/current/userguide/gradle_daemon.html) on how to disable or stop the Gradle Daemons. diff --git a/package-lock.json b/package-lock.json index 7368e95..67a8dd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "cache", - "version": "3.0.3", + "version": "3.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cache", - "version": "3.0.3", + "version": "3.0.4", "license": "MIT", "dependencies": { - "@actions/cache": "^2.0.6", "@actions/core": "^1.7.0", "@actions/exec": "^1.1.1", "@actions/io": "^1.1.2" + }, "devDependencies": { "@types/jest": "^27.5.0", @@ -36,9 +36,7 @@ } }, "node_modules/@actions/cache": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.6.tgz", - "integrity": "sha512-Z39ZrWaTRRPaV/AOQdY7hve+Iy/HloH5prpz+k+0lZgGQs/3SeO0UYSIakVuXOk2pdMZnl0Nv0PoK1rmh9YfGQ==", + "dependencies": { "@actions/core": "^1.2.6", "@actions/exec": "^1.0.1", @@ -9533,9 +9531,6 @@ }, "dependencies": { "@actions/cache": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.6.tgz", - "integrity": "sha512-Z39ZrWaTRRPaV/AOQdY7hve+Iy/HloH5prpz+k+0lZgGQs/3SeO0UYSIakVuXOk2pdMZnl0Nv0PoK1rmh9YfGQ==", "requires": { "@actions/core": "^1.2.6", "@actions/exec": "^1.0.1", diff --git a/package.json b/package.json index 64fb57c..5053731 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cache", - "version": "3.0.3", + "version": "3.0.4", "private": true, "description": "Cache dependencies and build outputs", "main": "dist/restore/index.js", @@ -23,7 +23,6 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@actions/cache": "^2.0.6", "@actions/core": "^1.7.0", "@actions/exec": "^1.1.1", "@actions/io": "^1.1.2" diff --git a/src/restore.ts b/src/restore.ts index 648e4cb..5bc17fa 100644 --- a/src/restore.ts +++ b/src/restore.ts @@ -29,38 +29,29 @@ async function run(): Promise { required: true }); - try { - const cacheKey = await cache.restoreCache( - cachePaths, - primaryKey, - restoreKeys + const cacheKey = await cache.restoreCache( + cachePaths, + primaryKey, + restoreKeys + ); + + if (!cacheKey) { + core.info( + `Cache not found for input keys: ${[ + primaryKey, + ...restoreKeys + ].join(", ")}` ); - if (!cacheKey) { - core.info( - `Cache not found for input keys: ${[ - primaryKey, - ...restoreKeys - ].join(", ")}` - ); - return; - } - // Store the matched cache key - utils.setCacheState(cacheKey); - - const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey); - utils.setCacheHitOutput(isExactKeyMatch); - - core.info(`Cache restored from key: ${cacheKey}`); - } catch (error: unknown) { - const typedError = error as Error; - if (typedError.name === cache.ValidationError.name) { - throw error; - } else { - utils.logWarning(typedError.message); - utils.setCacheHitOutput(false); - } + return; } + + // Store the matched cache key + utils.setCacheState(cacheKey); + + const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey); + utils.setCacheHitOutput(isExactKeyMatch); + core.info(`Cache restored from key: ${cacheKey}`); } catch (error: unknown) { core.setFailed((error as Error).message); } diff --git a/src/save.ts b/src/save.ts index 7b333fb..a0a21bf 100644 --- a/src/save.ts +++ b/src/save.ts @@ -44,20 +44,12 @@ async function run(): Promise { required: true }); - try { - await cache.saveCache(cachePaths, primaryKey, { - uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize) - }); + const cacheId = await cache.saveCache(cachePaths, primaryKey, { + uploadChunkSize: utils.getInputAsInt(Inputs.UploadChunkSize) + }); + + if (cacheId != -1) { core.info(`Cache saved with key: ${primaryKey}`); - } catch (error: unknown) { - const typedError = error as Error; - if (typedError.name === cache.ValidationError.name) { - throw error; - } else if (typedError.name === cache.ReserveCacheError.name) { - core.info(typedError.message); - } else { - utils.logWarning(typedError.message); - } } } catch (error: unknown) { utils.logWarning((error as Error).message);