diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts index 250f7ef..ff09552 100644 --- a/__tests__/restore.test.ts +++ b/__tests__/restore.test.ts @@ -173,8 +173,12 @@ test("restore with cache found for key", async () => { expect(stateMock).toHaveBeenCalledWith("CACHE_RESULT", key); expect(stateMock).toHaveBeenCalledTimes(2); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); expect(failedMock).toHaveBeenCalledTimes(0); @@ -218,8 +222,12 @@ test("restore with cache found for restore key", async () => { expect(stateMock).toHaveBeenCalledWith("CACHE_RESULT", restoreKey); expect(stateMock).toHaveBeenCalledTimes(2); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(infoMock).toHaveBeenCalledWith( `Cache restored from key: ${restoreKey}` ); @@ -260,7 +268,11 @@ test("Fail restore when fail on cache miss is enabled and primary + restore keys ); expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(0); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(failedMock).toHaveBeenCalledWith( `Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${key}` @@ -306,8 +318,12 @@ test("restore when fail on cache miss is enabled and primary key doesn't match r expect(stateMock).toHaveBeenCalledWith("CACHE_RESULT", restoreKey); expect(stateMock).toHaveBeenCalledTimes(2); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(infoMock).toHaveBeenCalledWith( `Cache restored from key: ${restoreKey}` diff --git a/__tests__/restoreImpl.test.ts b/__tests__/restoreImpl.test.ts index 16f5f72..6d414c6 100644 --- a/__tests__/restoreImpl.test.ts +++ b/__tests__/restoreImpl.test.ts @@ -79,8 +79,12 @@ test("restore without AC available should no-op", async () => { await restoreImpl(new StateProvider()); expect(restoreCacheMock).toHaveBeenCalledTimes(0); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); }); test("restore on GHES without AC available should no-op", async () => { @@ -95,8 +99,12 @@ test("restore on GHES without AC available should no-op", async () => { await restoreImpl(new StateProvider()); expect(restoreCacheMock).toHaveBeenCalledTimes(0); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); }); test("restore on GHES with AC available ", async () => { @@ -133,8 +141,12 @@ test("restore on GHES with AC available ", async () => { ); expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); expect(failedMock).toHaveBeenCalledTimes(0); @@ -355,8 +367,12 @@ test("restore with cache found for key", async () => { ); expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); expect(failedMock).toHaveBeenCalledTimes(0); @@ -397,8 +413,12 @@ test("restore with cache found for restore key", async () => { ); expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(infoMock).toHaveBeenCalledWith( `Cache restored from key: ${restoreKey}` ); @@ -441,8 +461,12 @@ test("restore with lookup-only set", async () => { expect(stateMock).toHaveBeenCalledWith("CACHE_RESULT", key); expect(stateMock).toHaveBeenCalledTimes(2); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(2); expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "" + ); expect(infoMock).toHaveBeenCalledWith( `Cache found and can be restored from key: ${key}` diff --git a/__tests__/restoreOnly.test.ts b/__tests__/restoreOnly.test.ts index 81e5bca..40875ec 100644 --- a/__tests__/restoreOnly.test.ts +++ b/__tests__/restoreOnly.test.ts @@ -86,7 +86,8 @@ test("restore with no cache found", async () => { ); expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key); - expect(outputMock).toHaveBeenCalledTimes(1); + expect(outputMock).toHaveBeenCalledWith("save-always-d18d746b9", ""); + expect(outputMock).toHaveBeenCalledTimes(2); expect(failedMock).toHaveBeenCalledTimes(0); expect(infoMock).toHaveBeenCalledWith( @@ -169,8 +170,9 @@ test("restore with cache found for key", async () => { expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key); expect(outputMock).toHaveBeenCalledWith("cache-hit", "true"); expect(outputMock).toHaveBeenCalledWith("cache-matched-key", key); + expect(outputMock).toHaveBeenCalledWith("save-always-d18d746b9", ""); - expect(outputMock).toHaveBeenCalledTimes(3); + expect(outputMock).toHaveBeenCalledTimes(4); expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); expect(failedMock).toHaveBeenCalledTimes(0); @@ -212,8 +214,9 @@ test("restore with cache found for restore key", async () => { expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key); expect(outputMock).toHaveBeenCalledWith("cache-hit", "false"); expect(outputMock).toHaveBeenCalledWith("cache-matched-key", restoreKey); + expect(outputMock).toHaveBeenCalledWith("save-always-d18d746b9", ""); - expect(outputMock).toHaveBeenCalledTimes(3); + expect(outputMock).toHaveBeenCalledTimes(4); expect(infoMock).toHaveBeenCalledWith( `Cache restored from key: ${restoreKey}` diff --git a/action.yml b/action.yml index 0125281..2b51484 100644 --- a/action.yml +++ b/action.yml @@ -33,11 +33,13 @@ inputs: outputs: cache-hit: description: 'A boolean value to indicate an exact match was found for the primary key' + save-always-d18d746b9: + description: "Run the post step to save the cache even if another step before fails" runs: using: 'node20' main: 'dist/restore/index.js' post: 'dist/save/index.js' - post-if: "success() || github.event.inputs.save-always" + post-if: "success() || (contains(steps.*.outputs.save-always-d18d746b9, 'true') && !contains(steps.*.outputs.save-always-d18d746b9, 'false'))" branding: icon: 'archive' color: 'gray-dark' diff --git a/src/constants.ts b/src/constants.ts index 0158ae0..d61d0cd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -5,13 +5,15 @@ export enum Inputs { UploadChunkSize = "upload-chunk-size", // Input for cache, save action EnableCrossOsArchive = "enableCrossOsArchive", // Input for cache, restore, save action FailOnCacheMiss = "fail-on-cache-miss", // Input for cache, restore action - LookupOnly = "lookup-only" // Input for cache, restore action + LookupOnly = "lookup-only", // Input for cache, restore action + SaveAlways = "save-always" // Input for cache action } export enum Outputs { CacheHit = "cache-hit", // Output from cache, restore action CachePrimaryKey = "cache-primary-key", // Output from restore action - CacheMatchedKey = "cache-matched-key" // Output from restore action + CacheMatchedKey = "cache-matched-key", // Output from restore action + SaveAlways = "save-always-d18d746b9" // Output from cache action, with unique suffix for detection in post-if } export enum State { diff --git a/src/restoreImpl.ts b/src/restoreImpl.ts index 74a366d..0907e00 100644 --- a/src/restoreImpl.ts +++ b/src/restoreImpl.ts @@ -13,6 +13,8 @@ export async function restoreImpl( stateProvider: IStateProvider, earlyExit?: boolean | undefined ): Promise { + core.setOutput(Outputs.SaveAlways, core.getInput(Inputs.SaveAlways)); + try { if (!utils.isCacheFeatureAvailable()) { core.setOutput(Outputs.CacheHit, "false");