Add read-only feature

When `read-only` is `true`, the cache is only restored and not saved. This allows for sharing the cache with multiple steps even if these steps may change them, and speeds them up regardless.
pull/474/head
Martijn Hols 5 years ago
parent 9c77c9dbfc
commit b917253c33

@ -308,3 +308,35 @@ test("restore with cache found for restore key", async () => {
); );
expect(failedMock).toHaveBeenCalledTimes(0); expect(failedMock).toHaveBeenCalledTimes(0);
}); });
test("restore with read-only with cache found for key", async () => {
const path = "node_modules";
const key = "node-test";
testUtils.setInputs({
path: path,
key,
readOnly: true
});
const infoMock = jest.spyOn(core, "info");
const failedMock = jest.spyOn(core, "setFailed");
const stateMock = jest.spyOn(core, "saveState");
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
const restoreCacheMock = jest
.spyOn(cache, "restoreCache")
.mockImplementationOnce(() => {
return Promise.resolve(key);
});
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
expect(setCacheHitOutputMock).toHaveBeenCalledWith(true);
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`);
expect(failedMock).toHaveBeenCalledTimes(0);
});

@ -35,6 +35,14 @@ beforeAll(() => {
} }
); );
jest.spyOn(actionUtils, "getInputAsBoolean").mockImplementation(
(name, options) => {
return jest
.requireActual("../src/utils/actionUtils")
.getInputAsBoolean(name, options);
}
);
jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation( jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation(
(key, cacheResult) => { (key, cacheResult) => {
return jest return jest
@ -338,3 +346,32 @@ test("save with valid inputs uploads a cache", async () => {
expect(failedMock).toHaveBeenCalledTimes(0); expect(failedMock).toHaveBeenCalledTimes(0);
}); });
test("save with read-only does not upload cache", async () => {
const infoMock = jest.spyOn(core, "info");
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 saveCacheMock = jest.spyOn(cache, "saveCache");
testUtils.setInput(Inputs.ReadOnly, "true");
await run();
expect(saveCacheMock).toHaveBeenCalledTimes(0);
expect(infoMock).toHaveBeenCalledWith(
"Cache running in read-only mode, not saving cache."
);
expect(failedMock).toHaveBeenCalledTimes(0);
});

@ -14,6 +14,9 @@ inputs:
upload-chunk-size: upload-chunk-size:
description: 'The chunk size used to split up large files during upload, in bytes' description: 'The chunk size used to split up large files during upload, in bytes'
required: false required: false
read-only:
description: 'Set to true to never save the cache'
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'

2327
dist/restore/index.js vendored

File diff suppressed because it is too large Load Diff

2331
dist/save/index.js vendored

File diff suppressed because it is too large Load Diff

@ -2,7 +2,8 @@ export enum Inputs {
Key = "key", Key = "key",
Path = "path", Path = "path",
RestoreKeys = "restore-keys", RestoreKeys = "restore-keys",
UploadChunkSize = "upload-chunk-size" UploadChunkSize = "upload-chunk-size",
ReadOnly = "read-only"
} }
export enum Outputs { export enum Outputs {

@ -11,6 +11,11 @@ async function run(): Promise<void> {
return; return;
} }
if (utils.getInputAsBoolean(Inputs.ReadOnly)) {
core.info("Cache running in read-only mode, not saving cache.");
return;
}
if (!utils.isValidEvent()) { if (!utils.isValidEvent()) {
utils.logWarning( utils.logWarning(
`Event Validation Error: The event type ${ `Event Validation Error: The event type ${

@ -74,3 +74,10 @@ export function getInputAsInt(
} }
return value; return value;
} }
export function getInputAsBoolean(
name: string,
options?: core.InputOptions
): boolean {
return core.getInput(name, options) === "true";
}

@ -13,6 +13,7 @@ interface CacheInput {
path: string; path: string;
key: string; key: string;
restoreKeys?: string[]; restoreKeys?: string[];
readOnly?: boolean;
} }
export function setInputs(input: CacheInput): void { export function setInputs(input: CacheInput): void {
@ -20,6 +21,7 @@ export function setInputs(input: CacheInput): void {
setInput(Inputs.Key, input.key); setInput(Inputs.Key, input.key);
input.restoreKeys && input.restoreKeys &&
setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n")); setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
setInput(Inputs.ReadOnly, input.readOnly ? "true" : "false");
} }
export function clearInputs(): void { export function clearInputs(): void {
@ -27,4 +29,5 @@ export function clearInputs(): void {
delete process.env[getInputName(Inputs.Key)]; delete process.env[getInputName(Inputs.Key)];
delete process.env[getInputName(Inputs.RestoreKeys)]; delete process.env[getInputName(Inputs.RestoreKeys)];
delete process.env[getInputName(Inputs.UploadChunkSize)]; delete process.env[getInputName(Inputs.UploadChunkSize)];
delete process.env[getInputName(Inputs.ReadOnly)];
} }

Loading…
Cancel
Save