Introduce save-only option for parity

This commit is contained in:
Jason T. Greene 2020-02-01 13:53:22 -06:00
parent e44e77f968
commit 42580c43b4
7 changed files with 83 additions and 10 deletions

View file

@ -401,3 +401,57 @@ test("restore with cache found for restore key", async () => {
); );
expect(failedMock).toHaveBeenCalledTimes(0); expect(failedMock).toHaveBeenCalledTimes(0);
}); });
test("restore skipped with save-only", async () => {
const key = "node-test";
const restoreKey = "node-";
testUtils.setInputs({
path: "node_modules",
key,
restoreKeys: [restoreKey],
saveOnly: "true"
});
const infoMock = jest.spyOn(core, "info");
const failedMock = jest.spyOn(core, "setFailed");
const stateMock = jest.spyOn(core, "saveState");
const cacheEntry: ArtifactCacheEntry = {
cacheKey: restoreKey,
scope: "refs/heads/master",
archiveLocation: "www.actionscache.test/download"
};
const getCacheMock = jest.spyOn(cacheHttpClient, "getCacheEntry");
getCacheMock.mockImplementation(() => {
return Promise.resolve(cacheEntry);
});
const tempPath = "/foo/bar";
const createTempDirectoryMock = jest.spyOn(
actionUtils,
"createTempDirectory"
);
createTempDirectoryMock.mockImplementation(() => {
return Promise.resolve(tempPath);
});
const setCacheStateMock = jest.spyOn(actionUtils, "setCacheState");
const downloadCacheMock = jest.spyOn(cacheHttpClient, "downloadCache");
const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
await run();
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(getCacheMock).toHaveBeenCalledWith([key, restoreKey]);
expect(setCacheStateMock).toHaveBeenCalledWith(cacheEntry);
expect(createTempDirectoryMock).toHaveBeenCalledTimes(0);
expect(downloadCacheMock).toHaveBeenCalledTimes(0);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
expect(infoMock).toHaveBeenCalledWith(
"Cache action configured for save-only, skipping restore step."
);
expect(failedMock).toHaveBeenCalledTimes(0);
});

View file

@ -414,7 +414,7 @@ test("save skipped with restore only", async () => {
await run(); await run();
expect(infoMock).toHaveBeenCalledWith( expect(infoMock).toHaveBeenCalledWith(
"Cache action configured for restore-only, skipping save step" "Cache action configured for restore-only, skipping save step."
); );
expect(reserveCacheMock).toHaveBeenCalledTimes(0); expect(reserveCacheMock).toHaveBeenCalledTimes(0);

View file

@ -14,6 +14,9 @@ inputs:
restore-only: restore-only:
description: 'Disables saving a new cache entry when true' description: 'Disables saving a new cache entry when true'
required: false required: false
save-only:
description: 'Disables downloading and restoring a new cache entry when true'
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'

View file

@ -2,7 +2,8 @@ export enum Inputs {
Key = "key", Key = "key",
Path = "path", Path = "path",
RestoreKeys = "restore-keys", RestoreKeys = "restore-keys",
RestoreOnly = "restore-only" RestoreOnly = "restore-only",
SaveOnly = "save-only"
} }
export enum Outputs { export enum Outputs {

View file

@ -67,15 +67,28 @@ async function run(): Promise<void> {
return; return;
} }
const isExactKeyMatch = utils.isExactKeyMatch(
primaryKey,
cacheEntry
);
// Store the cache result
utils.setCacheState(cacheEntry);
if (core.getInput(Inputs.SaveOnly) === "true") {
core.info(
"Cache action configured for save-only, skipping restore step."
);
utils.setCacheHitOutput(isExactKeyMatch);
return;
}
const archivePath = path.join( const archivePath = path.join(
await utils.createTempDirectory(), await utils.createTempDirectory(),
"cache.tgz" "cache.tgz"
); );
core.debug(`Archive Path: ${archivePath}`); core.debug(`Archive Path: ${archivePath}`);
// Store the cache result
utils.setCacheState(cacheEntry);
// Download the cache from the cache entry // Download the cache from the cache entry
await cacheHttpClient.downloadCache( await cacheHttpClient.downloadCache(
cacheEntry.archiveLocation, cacheEntry.archiveLocation,
@ -91,10 +104,6 @@ async function run(): Promise<void> {
await extractTar(archivePath, cachePath); await extractTar(archivePath, cachePath);
const isExactKeyMatch = utils.isExactKeyMatch(
primaryKey,
cacheEntry
);
utils.setCacheHitOutput(isExactKeyMatch); utils.setCacheHitOutput(isExactKeyMatch);
core.info( core.info(

View file

@ -20,7 +20,7 @@ async function run(): Promise<void> {
if (core.getInput(Inputs.RestoreOnly) === "true") { if (core.getInput(Inputs.RestoreOnly) === "true") {
core.info( core.info(
"Cache action configured for restore-only, skipping save step" "Cache action configured for restore-only, skipping save step."
); );
return; return;
} }

View file

@ -13,6 +13,8 @@ interface CacheInput {
path: string; path: string;
key: string; key: string;
restoreKeys?: string[]; restoreKeys?: string[];
restoreOnly?: string;
saveOnly?: string;
} }
export function setInputs(input: CacheInput): void { export function setInputs(input: CacheInput): void {
@ -20,10 +22,14 @@ 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"));
input.restoreOnly && setInput(Inputs.RestoreOnly, input.restoreOnly);
input.saveOnly && setInput(Inputs.SaveOnly, input.saveOnly);
} }
export function clearInputs(): void { export function clearInputs(): void {
delete process.env[getInputName(Inputs.Path)]; delete process.env[getInputName(Inputs.Path)];
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.RestoreOnly)];
delete process.env[getInputName(Inputs.SaveOnly)];
} }