Add outputs.cache-key

This commit is contained in:
Josh Soref 2022-01-23 13:46:47 -05:00
parent dbb732b211
commit dde36b38ea
8 changed files with 58 additions and 12 deletions

View file

@ -46,6 +46,8 @@ Create a workflow `.yml` file in your repositories `.github/workflows` directory
> See [Skipping steps based on cache-hit](#Skipping-steps-based-on-cache-hit) for info on using this output > See [Skipping steps based on cache-hit](#Skipping-steps-based-on-cache-hit) for info on using this output
* `cache-key` - A string indicating the matching cache key (if any).
### Cache scopes ### Cache scopes
The cache is scoped to the key and branch. The default branch cache is available to other branches. The cache is scoped to the key and branch. The default branch cache is available to other branches.

View file

@ -102,7 +102,8 @@ test("setOutputAndState with exact match to set cache-hit output and state", ()
actionUtils.setOutputAndState(key, cacheKey); actionUtils.setOutputAndState(key, cacheKey);
expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "true"); expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "true");
expect(setOutputMock).toHaveBeenCalledTimes(1); expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheKey, key);
expect(setOutputMock).toHaveBeenCalledTimes(2);
expect(saveStateMock).toHaveBeenCalledWith(State.CacheMatchedKey, cacheKey); expect(saveStateMock).toHaveBeenCalledWith(State.CacheMatchedKey, cacheKey);
expect(saveStateMock).toHaveBeenCalledTimes(1); expect(saveStateMock).toHaveBeenCalledTimes(1);
@ -118,7 +119,8 @@ test("setOutputAndState with no exact match to set cache-hit output and state",
actionUtils.setOutputAndState(key, cacheKey); actionUtils.setOutputAndState(key, cacheKey);
expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "false"); expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "false");
expect(setOutputMock).toHaveBeenCalledTimes(1); expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheKey, key);
expect(setOutputMock).toHaveBeenCalledTimes(2);
expect(saveStateMock).toHaveBeenCalledWith(State.CacheMatchedKey, cacheKey); expect(saveStateMock).toHaveBeenCalledWith(State.CacheMatchedKey, cacheKey);
expect(saveStateMock).toHaveBeenCalledTimes(1); expect(saveStateMock).toHaveBeenCalledTimes(1);

View file

@ -158,6 +158,7 @@ test("restore with no cache found", async () => {
const infoMock = jest.spyOn(core, "info"); const infoMock = jest.spyOn(core, "info");
const failedMock = jest.spyOn(core, "setFailed"); const failedMock = jest.spyOn(core, "setFailed");
const stateMock = jest.spyOn(core, "saveState"); const stateMock = jest.spyOn(core, "saveState");
const setOutputMock = jest.spyOn(core, "setOutput");
const restoreCacheMock = jest const restoreCacheMock = jest
.spyOn(cache, "restoreCache") .spyOn(cache, "restoreCache")
.mockImplementationOnce(() => { .mockImplementationOnce(() => {
@ -172,6 +173,8 @@ test("restore with no cache found", async () => {
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(failedMock).toHaveBeenCalledTimes(0); expect(failedMock).toHaveBeenCalledTimes(0);
expect(setOutputMock).toHaveBeenCalledTimes(0);
expect(infoMock).toHaveBeenCalledWith( expect(infoMock).toHaveBeenCalledWith(
`Cache not found for input keys: ${key}` `Cache not found for input keys: ${key}`
); );
@ -270,7 +273,7 @@ test("restore with cache found for key", async () => {
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
expect(setCacheHitOutputMock).toHaveBeenCalledWith(true); expect(setCacheHitOutputMock).toHaveBeenCalledWith(true);
expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); expect(infoMock).toHaveBeenCalledWith(`Cache restored for key: ${key}`);
expect(failedMock).toHaveBeenCalledTimes(0); expect(failedMock).toHaveBeenCalledTimes(0);
}); });

23
dist/restore/index.js vendored
View file

@ -4609,6 +4609,7 @@ var Inputs;
var Outputs; var Outputs;
(function (Outputs) { (function (Outputs) {
Outputs["CacheHit"] = "cache-hit"; Outputs["CacheHit"] = "cache-hit";
Outputs["CacheKey"] = "cache-key";
})(Outputs = exports.Outputs || (exports.Outputs = {})); })(Outputs = exports.Outputs || (exports.Outputs = {}));
var State; var State;
(function (State) { (function (State) {
@ -36343,8 +36344,9 @@ function isExactKeyMatch(key, cacheKey) {
}) === 0); }) === 0);
} }
exports.isExactKeyMatch = isExactKeyMatch; exports.isExactKeyMatch = isExactKeyMatch;
function setCacheState(state) { function setCacheState(state, key) {
core.saveState(constants_1.State.CacheMatchedKey, state); core.saveState(constants_1.State.CacheMatchedKey, state);
core.setOutput(constants_1.Outputs.CacheKey, key);
} }
exports.setCacheState = setCacheState; exports.setCacheState = setCacheState;
function setCacheHitOutput(isCacheHit) { function setCacheHitOutput(isCacheHit) {
@ -36354,7 +36356,7 @@ exports.setCacheHitOutput = setCacheHitOutput;
function setOutputAndState(key, cacheKey) { function setOutputAndState(key, cacheKey) {
setCacheHitOutput(isExactKeyMatch(key, cacheKey)); setCacheHitOutput(isExactKeyMatch(key, cacheKey));
// Store the matched cache key if it exists // Store the matched cache key if it exists
cacheKey && setCacheState(cacheKey); cacheKey && setCacheState(cacheKey, key);
} }
exports.setOutputAndState = setOutputAndState; exports.setOutputAndState = setOutputAndState;
function getCacheState() { function getCacheState() {
@ -46748,7 +46750,22 @@ function run() {
utils.setCacheState(cacheKey); utils.setCacheState(cacheKey);
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey); const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
utils.setCacheHitOutput(isExactKeyMatch); utils.setCacheHitOutput(isExactKeyMatch);
core.info(`Cache restored from key: ${cacheKey}`); let foundKey;
if (isExactKeyMatch) {
foundKey = primaryKey;
core.info(`Cache restored for key: ${foundKey}`);
}
else {
let i;
for (i = 0; i < restoreKeys.length - 1; i++) {
const fallbackCacheKey = yield cache.restoreCache(cachePaths, restoreKeys[i]);
if (cacheKey) {
break;
}
}
foundKey = restoreKeys[i];
core.info(`Cache restored from key: ${foundKey}`);
}
} }
catch (error) { catch (error) {
if (error.name === cache.ValidationError.name) { if (error.name === cache.ValidationError.name) {

6
dist/save/index.js vendored
View file

@ -4609,6 +4609,7 @@ var Inputs;
var Outputs; var Outputs;
(function (Outputs) { (function (Outputs) {
Outputs["CacheHit"] = "cache-hit"; Outputs["CacheHit"] = "cache-hit";
Outputs["CacheKey"] = "cache-key";
})(Outputs = exports.Outputs || (exports.Outputs = {})); })(Outputs = exports.Outputs || (exports.Outputs = {}));
var State; var State;
(function (State) { (function (State) {
@ -36343,8 +36344,9 @@ function isExactKeyMatch(key, cacheKey) {
}) === 0); }) === 0);
} }
exports.isExactKeyMatch = isExactKeyMatch; exports.isExactKeyMatch = isExactKeyMatch;
function setCacheState(state) { function setCacheState(state, key) {
core.saveState(constants_1.State.CacheMatchedKey, state); core.saveState(constants_1.State.CacheMatchedKey, state);
core.setOutput(constants_1.Outputs.CacheKey, key);
} }
exports.setCacheState = setCacheState; exports.setCacheState = setCacheState;
function setCacheHitOutput(isCacheHit) { function setCacheHitOutput(isCacheHit) {
@ -36354,7 +36356,7 @@ exports.setCacheHitOutput = setCacheHitOutput;
function setOutputAndState(key, cacheKey) { function setOutputAndState(key, cacheKey) {
setCacheHitOutput(isExactKeyMatch(key, cacheKey)); setCacheHitOutput(isExactKeyMatch(key, cacheKey));
// Store the matched cache key if it exists // Store the matched cache key if it exists
cacheKey && setCacheState(cacheKey); cacheKey && setCacheState(cacheKey, key);
} }
exports.setOutputAndState = setOutputAndState; exports.setOutputAndState = setOutputAndState;
function getCacheState() { function getCacheState() {

View file

@ -6,7 +6,8 @@ export enum Inputs {
} }
export enum Outputs { export enum Outputs {
CacheHit = "cache-hit" CacheHit = "cache-hit",
CacheKey = "cache-key"
} }
export enum State { export enum State {

View file

@ -54,7 +54,25 @@ async function run(): Promise<void> {
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey); const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
utils.setCacheHitOutput(isExactKeyMatch); utils.setCacheHitOutput(isExactKeyMatch);
core.info(`Cache restored from key: ${cacheKey}`); let foundKey: string;
if (isExactKeyMatch) {
foundKey = primaryKey;
core.info(`Cache restored for key: ${foundKey}`);
} else {
let i: number;
for (i = 0; i < restoreKeys.length - 1; i++) {
const fallbackCacheKey = await cache.restoreCache(
cachePaths,
restoreKeys[i]
);
if (cacheKey) {
break;
}
}
foundKey = restoreKeys[i];
core.info(`Cache restored from key: ${foundKey}`);
}
} catch (error) { } catch (error) {
if (error.name === cache.ValidationError.name) { if (error.name === cache.ValidationError.name) {
throw error; throw error;

View file

@ -18,8 +18,9 @@ export function isExactKeyMatch(key: string, cacheKey?: string): boolean {
); );
} }
export function setCacheState(state: string): void { export function setCacheState(state: string, key?: string): void {
core.saveState(State.CacheMatchedKey, state); core.saveState(State.CacheMatchedKey, state);
core.setOutput(Outputs.CacheKey, key);
} }
export function setCacheHitOutput(isCacheHit: boolean): void { export function setCacheHitOutput(isCacheHit: boolean): void {
@ -29,7 +30,7 @@ export function setCacheHitOutput(isCacheHit: boolean): void {
export function setOutputAndState(key: string, cacheKey?: string): void { export function setOutputAndState(key: string, cacheKey?: string): void {
setCacheHitOutput(isExactKeyMatch(key, cacheKey)); setCacheHitOutput(isExactKeyMatch(key, cacheKey));
// Store the matched cache key if it exists // Store the matched cache key if it exists
cacheKey && setCacheState(cacheKey); cacheKey && setCacheState(cacheKey, key);
} }
export function getCacheState(): string | undefined { export function getCacheState(): string | undefined {