From 6a898d25f06f5e404274fc04835f03f1056b28f8 Mon Sep 17 00:00:00 2001 From: MOREL Matthieu Date: Thu, 26 Aug 2021 15:04:57 +0200 Subject: [PATCH 1/3] feat(cache): change key to match actions/cache documentation Signed-off-by: Matthieu MOREL --- __tests__/cache-restore.test.ts | 6 +++--- dist/setup/index.js | 8 +++++--- src/cache-restore.ts | 10 +++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/__tests__/cache-restore.test.ts b/__tests__/cache-restore.test.ts index 27f6fa27..cd9cde55 100644 --- a/__tests__/cache-restore.test.ts +++ b/__tests__/cache-restore.test.ts @@ -135,10 +135,10 @@ describe('cache-restore', () => { await restoreCache(packageManager); expect(hashFilesSpy).toHaveBeenCalled(); expect(infoSpy).toHaveBeenCalledWith( - `Cache restored from key: node-cache-${platform}-${packageManager}-${fileHash}` + `Cache restored from key: ${platform}-setup-node-${packageManager}-${fileHash}` ); expect(infoSpy).not.toHaveBeenCalledWith( - `${packageManager} cache is not found` + `Cache not found for input keys: ${platform}-setup-node-${packageManager}-${fileHash}, ${platform}-setup-node-${packageManager}-, ${platform}-setup-node-` ); expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true); } @@ -166,7 +166,7 @@ describe('cache-restore', () => { await restoreCache(packageManager); expect(hashFilesSpy).toHaveBeenCalled(); expect(infoSpy).toHaveBeenCalledWith( - `${packageManager} cache is not found` + `Cache not found for input keys: ${platform}-setup-node-${packageManager}-${fileHash}, ${platform}-setup-node-${packageManager}-, ${platform}-setup-node-` ); expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', false); } diff --git a/dist/setup/index.js b/dist/setup/index.js index ff4bec26..4945fcfc 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73044,13 +73044,15 @@ const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, if (!fileHash) { throw new Error('Some specified paths were not resolved, unable to cache dependencies.'); } - const primaryKey = `node-cache-${platform}-${packageManager}-${fileHash}`; + const keyPrefix = `${platform}-setup-node-`; + const primaryKey = `${keyPrefix}${packageManager}-${fileHash}`; + const restoreKeys = [`${keyPrefix}${packageManager}-`, keyPrefix]; core.debug(`primary key is ${primaryKey}`); core.saveState(constants_1.State.CachePrimaryKey, primaryKey); - const cacheKey = yield cache.restoreCache([cachePath], primaryKey); + const cacheKey = yield cache.restoreCache([cachePath], primaryKey, restoreKeys); core.setOutput('cache-hit', Boolean(cacheKey)); if (!cacheKey) { - core.info(`${packageManager} cache is not found`); + core.info(`Cache not found for input keys: ${[primaryKey, ...restoreKeys].join(', ')}`); return; } core.saveState(constants_1.State.CacheMatchedKey, cacheKey); diff --git a/src/cache-restore.ts b/src/cache-restore.ts index 7f761da4..cb81844c 100644 --- a/src/cache-restore.ts +++ b/src/cache-restore.ts @@ -35,17 +35,17 @@ export const restoreCache = async ( 'Some specified paths were not resolved, unable to cache dependencies.' ); } - - const primaryKey = `node-cache-${platform}-${packageManager}-${fileHash}`; + const keyPrefix = `${platform}-setup-node-`; + const primaryKey = `${keyPrefix}${packageManager}-${fileHash}`; + const restoreKeys = [`${keyPrefix}${packageManager}-`, keyPrefix]; core.debug(`primary key is ${primaryKey}`); - core.saveState(State.CachePrimaryKey, primaryKey); - const cacheKey = await cache.restoreCache([cachePath], primaryKey); + const cacheKey = await cache.restoreCache([cachePath], primaryKey, restoreKeys); core.setOutput('cache-hit', Boolean(cacheKey)); if (!cacheKey) { - core.info(`${packageManager} cache is not found`); + core.info(`Cache not found for input keys: ${[primaryKey, ...restoreKeys].join(', ')}`); return; } From cbe3ec3ea18a8adf9ef339c33ff89b256471a9e3 Mon Sep 17 00:00:00 2001 From: Pelle Wessman Date: Mon, 27 Feb 2023 19:27:47 +0100 Subject: [PATCH 2/3] Simplifies cache fallback + add timed invalidation --- README.md | 2 ++ __tests__/cache-restore.test.ts | 10 +++++----- action.yml | 2 ++ src/cache-restore.ts | 13 ++++++++++--- src/main.ts | 3 ++- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ba67317c..ba7dfbf1 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ The action defaults to search for the dependency file (`package-lock.json`, `npm **Note:** The action does not cache `node_modules` +Use `cache-invalidate-after-days` to change the default fallback cache invalidation of every 120 days. Set to 0 to deactivate. + See the examples of using cache for `yarn`/`pnpm` and `cache-dependency-path` input in the [Advanced usage](docs/advanced-usage.md#caching-packages-data) guide. **Caching npm dependencies:** diff --git a/__tests__/cache-restore.test.ts b/__tests__/cache-restore.test.ts index cd9cde55..68de2af6 100644 --- a/__tests__/cache-restore.test.ts +++ b/__tests__/cache-restore.test.ts @@ -132,13 +132,13 @@ describe('cache-restore', () => { } }); - await restoreCache(packageManager); + await restoreCache(packageManager, undefined, '0'); expect(hashFilesSpy).toHaveBeenCalled(); expect(infoSpy).toHaveBeenCalledWith( - `Cache restored from key: ${platform}-setup-node-${packageManager}-${fileHash}` + `Cache restored from key: ${platform}-0-setup-node-${packageManager}-${fileHash}` ); expect(infoSpy).not.toHaveBeenCalledWith( - `Cache not found for input keys: ${platform}-setup-node-${packageManager}-${fileHash}, ${platform}-setup-node-${packageManager}-, ${platform}-setup-node-` + `Cache not found for input keys: ${platform}-0-setup-node-${packageManager}-${fileHash}, ${platform}-0-setup-node-${packageManager}-` ); expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true); } @@ -163,10 +163,10 @@ describe('cache-restore', () => { }); restoreCacheSpy.mockImplementationOnce(() => undefined); - await restoreCache(packageManager); + await restoreCache(packageManager, undefined, '0'); expect(hashFilesSpy).toHaveBeenCalled(); expect(infoSpy).toHaveBeenCalledWith( - `Cache not found for input keys: ${platform}-setup-node-${packageManager}-${fileHash}, ${platform}-setup-node-${packageManager}-, ${platform}-setup-node-` + `Cache not found for input keys: ${platform}-0-setup-node-${packageManager}-${fileHash}, ${platform}-0-setup-node-${packageManager}-` ); expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', false); } diff --git a/action.yml b/action.yml index b22de1ef..13473abf 100644 --- a/action.yml +++ b/action.yml @@ -25,6 +25,8 @@ inputs: description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm.' cache-dependency-path: description: 'Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies.' + cache-invalidate-after-days: + description: 'Used to control how often the fallback cache is invalidated automatically.' # TODO: add input to control forcing to pull from cloud or dist. # escape valve for someone having issues or needing the absolute latest which isn't cached yet outputs: diff --git a/src/cache-restore.ts b/src/cache-restore.ts index cb81844c..d72da4ed 100644 --- a/src/cache-restore.ts +++ b/src/cache-restore.ts @@ -13,7 +13,8 @@ import { export const restoreCache = async ( packageManager: string, - cacheDependencyPath?: string + cacheDependencyPath?: string, + cacheInvalidateAfterDays?: string ) => { const packageManagerInfo = await getPackageManagerInfo(packageManager); if (!packageManagerInfo) { @@ -35,9 +36,15 @@ export const restoreCache = async ( 'Some specified paths were not resolved, unable to cache dependencies.' ); } - const keyPrefix = `${platform}-setup-node-`; + const numericCacheInvalidateAfterDays = cacheInvalidateAfterDays && cacheInvalidateAfterDays === '0' + ? 0 + : (parseInt(cacheInvalidateAfterDays || '', 10) || 120) + const timedInvalidationPrefix = numericCacheInvalidateAfterDays + ? Math.floor(Date.now() / (1000 * 60 * 60 * 24 * numericCacheInvalidateAfterDays)) % 1000 // % 1000 to get a rolling prefix between 0 and 999 rather than a possibly infinitely large + : 0; + const keyPrefix = `${platform}-${timedInvalidationPrefix}-setup-node-`; const primaryKey = `${keyPrefix}${packageManager}-${fileHash}`; - const restoreKeys = [`${keyPrefix}${packageManager}-`, keyPrefix]; + const restoreKeys = [`${keyPrefix}${packageManager}-`]; core.debug(`primary key is ${primaryKey}`); core.saveState(State.CachePrimaryKey, primaryKey); diff --git a/src/main.ts b/src/main.ts index 90cd1d9d..7708a606 100644 --- a/src/main.ts +++ b/src/main.ts @@ -61,7 +61,8 @@ export async function run() { if (cache && isCacheFeatureAvailable()) { const cacheDependencyPath = core.getInput('cache-dependency-path'); - await restoreCache(cache, cacheDependencyPath); + const cacheInvalidateAfterDays = core.getInput('cache-invalidate-after-days'); + await restoreCache(cache, cacheDependencyPath, cacheInvalidateAfterDays); } const matchersPath = path.join(__dirname, '../..', '.github'); From 6ef1113e78db8dfa5e72d35d5b0b4dc2e78ac931 Mon Sep 17 00:00:00 2001 From: Pelle Wessman Date: Fri, 28 Apr 2023 12:04:14 +0200 Subject: [PATCH 3/3] Run `npm run build` as suggested --- dist/setup/index.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 4945fcfc..36583dd8 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73030,7 +73030,7 @@ const path_1 = __importDefault(__nccwpck_require__(1017)); const fs_1 = __importDefault(__nccwpck_require__(7147)); const constants_1 = __nccwpck_require__(9042); const cache_utils_1 = __nccwpck_require__(1678); -const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { +const restoreCache = (packageManager, cacheDependencyPath, cacheInvalidateAfterDays) => __awaiter(void 0, void 0, void 0, function* () { const packageManagerInfo = yield cache_utils_1.getPackageManagerInfo(packageManager); if (!packageManagerInfo) { throw new Error(`Caching for '${packageManager}' is not supported`); @@ -73044,9 +73044,15 @@ const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, if (!fileHash) { throw new Error('Some specified paths were not resolved, unable to cache dependencies.'); } - const keyPrefix = `${platform}-setup-node-`; + const numericCacheInvalidateAfterDays = cacheInvalidateAfterDays && cacheInvalidateAfterDays === '0' + ? 0 + : (parseInt(cacheInvalidateAfterDays || '', 10) || 120); + const timedInvalidationPrefix = numericCacheInvalidateAfterDays + ? Math.floor(Date.now() / (1000 * 60 * 60 * 24 * numericCacheInvalidateAfterDays)) % 1000 // % 1000 to get a rolling prefix between 0 and 999 rather than a possibly infinitely large + : 0; + const keyPrefix = `${platform}-${timedInvalidationPrefix}-setup-node-`; const primaryKey = `${keyPrefix}${packageManager}-${fileHash}`; - const restoreKeys = [`${keyPrefix}${packageManager}-`, keyPrefix]; + const restoreKeys = [`${keyPrefix}${packageManager}-`]; core.debug(`primary key is ${primaryKey}`); core.saveState(constants_1.State.CachePrimaryKey, primaryKey); const cacheKey = yield cache.restoreCache([cachePath], primaryKey, restoreKeys); @@ -73981,7 +73987,8 @@ function run() { } if (cache && cache_utils_1.isCacheFeatureAvailable()) { const cacheDependencyPath = core.getInput('cache-dependency-path'); - yield cache_restore_1.restoreCache(cache, cacheDependencyPath); + const cacheInvalidateAfterDays = core.getInput('cache-invalidate-after-days'); + yield cache_restore_1.restoreCache(cache, cacheDependencyPath, cacheInvalidateAfterDays); } const matchersPath = path.join(__dirname, '../..', '.github'); core.info(`##[add-matcher]${path.join(matchersPath, 'tsc.json')}`);