mirror of https://github.com/actions/cache.git
Allow updating cache with 'update' key
This commit is contained in:
parent
eed9cfe64d
commit
2d697b4d9c
|
@ -194,3 +194,13 @@ test("getInputAsArray handles empty lines correctly", () => {
|
||||||
testUtils.setInput("foo", "\n\nbar\n\nbaz\n\n");
|
testUtils.setInput("foo", "\n\nbar\n\nbaz\n\n");
|
||||||
expect(actionUtils.getInputAsArray("foo")).toEqual(["bar", "baz"]);
|
expect(actionUtils.getInputAsArray("foo")).toEqual(["bar", "baz"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("getInputAsBoolean returns true if the value is set to 'true'", () => {
|
||||||
|
testUtils.setInput("foo", "true");
|
||||||
|
expect(actionUtils.getInputAsBoolean("foo")).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("getInputAsBoolean returns false if the value is set to anything else", () => {
|
||||||
|
testUtils.setInput("foo", "false");
|
||||||
|
expect(actionUtils.getInputAsBoolean("foo")).toEqual(false);
|
||||||
|
});
|
||||||
|
|
|
@ -118,6 +118,41 @@ test("save with exact match returns early", async () => {
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("save with exact match updates when configured", async () => {
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
|
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||||
|
const savedCacheKey = primaryKey;
|
||||||
|
|
||||||
|
jest.spyOn(core, "getState")
|
||||||
|
// Cache Entry State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return savedCacheKey;
|
||||||
|
})
|
||||||
|
// Cache Key State
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return primaryKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputPath = "node_modules";
|
||||||
|
testUtils.setInput(Inputs.Path, inputPath);
|
||||||
|
testUtils.setInput(Inputs.Update, "true");
|
||||||
|
|
||||||
|
const cacheId = 4;
|
||||||
|
const saveCacheMock = jest
|
||||||
|
.spyOn(cache, "saveCache")
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
return Promise.resolve(cacheId);
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey);
|
||||||
|
|
||||||
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
test("save with missing input outputs warning", async () => {
|
test("save with missing input outputs warning", async () => {
|
||||||
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
|
@ -11,6 +11,9 @@ inputs:
|
||||||
restore-keys:
|
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 the cache if no cache hit occurred for key'
|
||||||
required: false
|
required: false
|
||||||
|
update:
|
||||||
|
description: 'If true, the cache will be updated if the key already exists'
|
||||||
|
required: false
|
||||||
outputs:
|
outputs:
|
||||||
cache-hit:
|
cache-hit:
|
||||||
description: 'A boolean value to indicate an exact match was found for the primary key'
|
description: 'A boolean value to indicate an exact match was found for the primary key'
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
export enum Inputs {
|
export enum Inputs {
|
||||||
Key = "key",
|
Key = "key",
|
||||||
Path = "path",
|
Path = "path",
|
||||||
RestoreKeys = "restore-keys"
|
RestoreKeys = "restore-keys",
|
||||||
|
Update = "update"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Outputs {
|
export enum Outputs {
|
||||||
|
|
|
@ -16,15 +16,17 @@ async function run(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = utils.getCacheState();
|
const state = utils.getCacheState();
|
||||||
|
// Inputs are re-evaluated before the post action, so we want the original key used for restore
|
||||||
// Inputs are re-evaluted before the post action, so we want the original key used for restore
|
|
||||||
const primaryKey = core.getState(State.CachePrimaryKey);
|
const primaryKey = core.getState(State.CachePrimaryKey);
|
||||||
if (!primaryKey) {
|
if (!primaryKey) {
|
||||||
utils.logWarning(`Error retrieving key from state.`);
|
utils.logWarning(`Error retrieving key from state.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.isExactKeyMatch(primaryKey, state)) {
|
if (
|
||||||
|
utils.isExactKeyMatch(primaryKey, state) &&
|
||||||
|
!utils.getInputAsBoolean(Inputs.Update)
|
||||||
|
) {
|
||||||
core.info(
|
core.info(
|
||||||
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
|
||||||
);
|
);
|
||||||
|
|
|
@ -56,3 +56,10 @@ export function getInputAsArray(
|
||||||
.map(s => s.trim())
|
.map(s => s.trim())
|
||||||
.filter(x => x !== "");
|
.filter(x => x !== "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getInputAsBoolean(
|
||||||
|
name: string,
|
||||||
|
options?: core.InputOptions
|
||||||
|
): boolean {
|
||||||
|
return core.getInput(name, options) === "true";
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue