Skip to content

Commit d2c83d8

Browse files
committed
Simplifies cache fallback + add timed invalidation
1 parent 117e7f5 commit d2c83d8

File tree

5 files changed

+21
-9
lines changed

5 files changed

+21
-9
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ The action has a built-in functionality for caching and restoring dependencies.
4545

4646
The action defaults to search for the dependency file (`package-lock.json` or `yarn.lock`) in the repository root, and uses its hash as a part of the cache key. Use `cache-dependency-path` for cases when multiple dependency files are used, or they are located in different subdirectories.
4747

48+
Use `cache-invalidate-after-days` to change the default fallback cache invalidation of every 120 days. Set to 0 to deactivate.
49+
4850
See the examples of using cache for `yarn` / `pnpm` and `cache-dependency-path` input in the [Advanced usage](docs/advanced-usage.md#caching-packages-dependencies) guide.
4951

5052
**Caching npm dependencies:**

__tests__/cache-restore.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,13 @@ describe('cache-restore', () => {
132132
}
133133
});
134134

135-
await restoreCache(packageManager);
135+
await restoreCache(packageManager, undefined, '0');
136136
expect(hashFilesSpy).toHaveBeenCalled();
137137
expect(infoSpy).toHaveBeenCalledWith(
138-
`Cache restored from key: ${platform}-setup-node-${packageManager}-${fileHash}`
138+
`Cache restored from key: ${platform}-0-setup-node-${packageManager}-${fileHash}`
139139
);
140140
expect(infoSpy).not.toHaveBeenCalledWith(
141-
`Cache not found for input keys: ${platform}-setup-node-${packageManager}-${fileHash}, ${platform}-setup-node-${packageManager}-, ${platform}-setup-node-`
141+
`Cache not found for input keys: ${platform}-0-setup-node-${packageManager}-${fileHash}, ${platform}-0-setup-node-${packageManager}-`
142142
);
143143
}
144144
);
@@ -162,10 +162,10 @@ describe('cache-restore', () => {
162162
});
163163

164164
restoreCacheSpy.mockImplementationOnce(() => undefined);
165-
await restoreCache(packageManager);
165+
await restoreCache(packageManager, undefined, '0');
166166
expect(hashFilesSpy).toHaveBeenCalled();
167167
expect(infoSpy).toHaveBeenCalledWith(
168-
`Cache not found for input keys: ${platform}-setup-node-${packageManager}-${fileHash}, ${platform}-setup-node-${packageManager}-, ${platform}-setup-node-`
168+
`Cache not found for input keys: ${platform}-0-setup-node-${packageManager}-${fileHash}, ${platform}-0-setup-node-${packageManager}-`
169169
);
170170
}
171171
);

action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ inputs:
2323
description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm'
2424
cache-dependency-path:
2525
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.'
26+
cache-invalidate-after-days:
27+
description: 'Used to control how often the fallback cache is invalidated automatically.'
2628
# TODO: add input to control forcing to pull from cloud or dist.
2729
# escape valve for someone having issues or needing the absolute latest which isn't cached yet
2830
# Deprecated option, do not use. Will not be supported after October 1, 2019

src/cache-restore.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212

1313
export const restoreCache = async (
1414
packageManager: string,
15-
cacheDependencyPath?: string
15+
cacheDependencyPath?: string,
16+
cacheInvalidateAfterDays?: string
1617
) => {
1718
const packageManagerInfo = await getPackageManagerInfo(packageManager);
1819
if (!packageManagerInfo) {
@@ -35,9 +36,15 @@ export const restoreCache = async (
3536
'Some specified paths were not resolved, unable to cache dependencies.'
3637
);
3738
}
38-
const keyPrefix = `${platform}-setup-node-`;
39+
const numericCacheInvalidateAfterDays = cacheInvalidateAfterDays && cacheInvalidateAfterDays === '0'
40+
? 0
41+
: (parseInt(cacheInvalidateAfterDays || '', 10) || 120)
42+
const timedInvalidationPrefix = numericCacheInvalidateAfterDays
43+
? 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
44+
: 0;
45+
const keyPrefix = `${platform}-${timedInvalidationPrefix}-setup-node-`;
3946
const primaryKey = `${keyPrefix}${packageManager}-${fileHash}`;
40-
const restoreKeys = [`${keyPrefix}${packageManager}-`, keyPrefix];
47+
const restoreKeys = [`${keyPrefix}${packageManager}-`];
4148
core.debug(`primary key is ${primaryKey}`);
4249
core.saveState(State.CachePrimaryKey, primaryKey);
4350
const cacheKey = await cache.restoreCache(paths, primaryKey, restoreKeys);

src/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ export async function run() {
5252
throw new Error('Caching is not supported on GHES');
5353
}
5454
const cacheDependencyPath = core.getInput('cache-dependency-path');
55-
await restoreCache(cache, cacheDependencyPath);
55+
const cacheInvalidateAfterDays = core.getInput('cache-invalidate-after-days');
56+
await restoreCache(cache, cacheDependencyPath, cacheInvalidateAfterDays);
5657
}
5758

5859
const matchersPath = path.join(__dirname, '../..', '.github');

0 commit comments

Comments
 (0)