From 7214f3c5466aaa3eb39e476f5b1e92720c9c3937 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Thu, 8 Feb 2024 20:07:45 -0500 Subject: [PATCH 01/14] Fix save-always/post-if with an output --- __tests__/restore.test.ts | 24 +++++++++++++++++++---- __tests__/restoreImpl.test.ts | 36 +++++++++++++++++++++++++++++------ __tests__/restoreOnly.test.ts | 9 ++++++--- action.yml | 4 +++- src/constants.ts | 6 ++++-- src/restoreImpl.ts | 2 ++ 6 files changed, 65 insertions(+), 16 deletions(-) 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"); From f04cc738d7337519800d4b973d8d90a1bff6b854 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Thu, 8 Feb 2024 20:20:05 -0500 Subject: [PATCH 02/14] Always output explicit "false" to prevent hijacking --- __tests__/restore.test.ts | 8 ++++---- __tests__/restoreImpl.test.ts | 12 ++++++------ __tests__/restoreOnly.test.ts | 6 +++--- src/restoreImpl.ts | 5 ++++- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts index ff09552..1cfb246 100644 --- a/__tests__/restore.test.ts +++ b/__tests__/restore.test.ts @@ -177,7 +177,7 @@ test("restore with cache found for key", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); @@ -226,7 +226,7 @@ test("restore with cache found for restore key", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(infoMock).toHaveBeenCalledWith( `Cache restored from key: ${restoreKey}` @@ -271,7 +271,7 @@ test("Fail restore when fail on cache miss is enabled and primary + restore keys expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(failedMock).toHaveBeenCalledWith( @@ -322,7 +322,7 @@ test("restore when fail on cache miss is enabled and primary key doesn't match r expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(infoMock).toHaveBeenCalledWith( diff --git a/__tests__/restoreImpl.test.ts b/__tests__/restoreImpl.test.ts index 6d414c6..130690c 100644 --- a/__tests__/restoreImpl.test.ts +++ b/__tests__/restoreImpl.test.ts @@ -83,7 +83,7 @@ test("restore without AC available should no-op", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); }); @@ -103,7 +103,7 @@ test("restore on GHES without AC available should no-op", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); }); @@ -145,7 +145,7 @@ test("restore on GHES with AC available ", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); @@ -371,7 +371,7 @@ test("restore with cache found for key", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); @@ -417,7 +417,7 @@ test("restore with cache found for restore key", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(infoMock).toHaveBeenCalledWith( `Cache restored from key: ${restoreKey}` @@ -465,7 +465,7 @@ test("restore with lookup-only set", async () => { expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); expect(setCacheHitOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", - "" + "false" ); expect(infoMock).toHaveBeenCalledWith( diff --git a/__tests__/restoreOnly.test.ts b/__tests__/restoreOnly.test.ts index 40875ec..8a0eb41 100644 --- a/__tests__/restoreOnly.test.ts +++ b/__tests__/restoreOnly.test.ts @@ -86,7 +86,7 @@ test("restore with no cache found", async () => { ); expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key); - expect(outputMock).toHaveBeenCalledWith("save-always-d18d746b9", ""); + expect(outputMock).toHaveBeenCalledWith("save-always-d18d746b9", "false"); expect(outputMock).toHaveBeenCalledTimes(2); expect(failedMock).toHaveBeenCalledTimes(0); @@ -170,7 +170,7 @@ 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).toHaveBeenCalledWith("save-always-d18d746b9", "false"); expect(outputMock).toHaveBeenCalledTimes(4); @@ -214,7 +214,7 @@ 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).toHaveBeenCalledWith("save-always-d18d746b9", "false"); expect(outputMock).toHaveBeenCalledTimes(4); diff --git a/src/restoreImpl.ts b/src/restoreImpl.ts index 0907e00..b71a0bd 100644 --- a/src/restoreImpl.ts +++ b/src/restoreImpl.ts @@ -13,7 +13,10 @@ export async function restoreImpl( stateProvider: IStateProvider, earlyExit?: boolean | undefined ): Promise { - core.setOutput(Outputs.SaveAlways, core.getInput(Inputs.SaveAlways)); + core.setOutput( + Outputs.SaveAlways, + core.getInput(Inputs.SaveAlways) || "false" + ); try { if (!utils.isCacheFeatureAvailable()) { From faaa3912ca1d75ce1c892389d8e13dc105443362 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Thu, 8 Feb 2024 20:52:30 -0500 Subject: [PATCH 03/14] Add save-always inpute/output test --- __tests__/restoreImpl.test.ts | 37 +++++++++++++++++++++++++++++++++++ src/utils/testUtils.ts | 4 ++++ 2 files changed, 41 insertions(+) diff --git a/__tests__/restoreImpl.test.ts b/__tests__/restoreImpl.test.ts index 130690c..bc40973 100644 --- a/__tests__/restoreImpl.test.ts +++ b/__tests__/restoreImpl.test.ts @@ -489,3 +489,40 @@ test("restore failure with earlyExit should call process exit", async () => { ); expect(processExitMock).toHaveBeenCalledWith(1); }); + +test("restore with save-always set", async () => { + jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); + const path = "node_modules"; + const key = "node-test"; + testUtils.setInputs({ + path: path, + key, + saveAlways: true + }); + + const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); + const restoreCacheMock = jest + .spyOn(cache, "restoreCache") + .mockImplementationOnce(() => { + return Promise.resolve(undefined); + }); + + await restoreImpl(new StateProvider()); + + expect(restoreCacheMock).toHaveBeenCalledTimes(1); + expect(restoreCacheMock).toHaveBeenCalledWith( + [path], + key, + [], + { + lookupOnly: false + }, + false + ); + + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); + expect(setCacheHitOutputMock).toHaveBeenCalledWith( + "save-always-d18d746b9", + "true" + ); +}); diff --git a/src/utils/testUtils.ts b/src/utils/testUtils.ts index ba0670b..84aeae9 100644 --- a/src/utils/testUtils.ts +++ b/src/utils/testUtils.ts @@ -16,6 +16,7 @@ interface CacheInput { enableCrossOsArchive?: boolean; failOnCacheMiss?: boolean; lookupOnly?: boolean; + saveAlways?: boolean; } export function setInputs(input: CacheInput): void { @@ -32,6 +33,8 @@ export function setInputs(input: CacheInput): void { setInput(Inputs.FailOnCacheMiss, input.failOnCacheMiss.toString()); input.lookupOnly !== undefined && setInput(Inputs.LookupOnly, input.lookupOnly.toString()); + input.saveAlways !== undefined && + setInput(Inputs.SaveAlways, input.saveAlways.toString()); } export function clearInputs(): void { @@ -42,4 +45,5 @@ export function clearInputs(): void { delete process.env[getInputName(Inputs.EnableCrossOsArchive)]; delete process.env[getInputName(Inputs.FailOnCacheMiss)]; delete process.env[getInputName(Inputs.LookupOnly)]; + delete process.env[getInputName(Inputs.SaveAlways)]; } From d776be45641c7c04a9130494deb4de7ab9b3850d Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Fri, 9 Feb 2024 02:32:10 -0500 Subject: [PATCH 04/14] Fix mock name --- __tests__/restoreImpl.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/__tests__/restoreImpl.test.ts b/__tests__/restoreImpl.test.ts index bc40973..75ed7e3 100644 --- a/__tests__/restoreImpl.test.ts +++ b/__tests__/restoreImpl.test.ts @@ -500,7 +500,7 @@ test("restore with save-always set", async () => { saveAlways: true }); - const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); + const setSaveAlwaysOutputMock = jest.spyOn(core, "setOutput"); const restoreCacheMock = jest .spyOn(cache, "restoreCache") .mockImplementationOnce(() => { @@ -520,8 +520,8 @@ test("restore with save-always set", async () => { false ); - expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); - expect(setCacheHitOutputMock).toHaveBeenCalledWith( + expect(setSaveAlwaysOutputMock).toHaveBeenCalledTimes(1); + expect(setSaveAlwaysOutputMock).toHaveBeenCalledWith( "save-always-d18d746b9", "true" ); From bd94e24ffb4075b7ee922dd8e5a29736390328a7 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Fri, 9 Feb 2024 11:17:15 -0500 Subject: [PATCH 05/14] Add save-always to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d1d2aef..f5ae8ee 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ If you are using a `self-hosted` Windows runner, `GNU tar` and `zstd` are requir * `enableCrossOsArchive` - An optional boolean when enabled, allows Windows runners to save or restore caches that can be restored or saved respectively on other platforms. Default: `false` * `fail-on-cache-miss` - Fail the workflow if cache entry is not found. Default: `false` * `lookup-only` - If true, only checks if cache entry exists and skips download. Does not change save cache behavior. Default: `false` +* `save-always` - If true, always saves the cache, even if the job fails. Requires a [step `id`](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsid). Default: `false` #### Environment Variables From 3e8104da648a17b7ac928f1298c7cf8ea9a39763 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Thu, 6 Jun 2024 20:32:21 -0400 Subject: [PATCH 06/14] Add e2e test --- .github/workflows/workflow.yml | 50 +++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 2a53c19..9bcbdf3 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -9,6 +9,7 @@ on: branches: - main - releases/** + - save-always-output jobs: # Build and unit test @@ -46,10 +47,10 @@ jobs: uses: actions/checkout@v3 - name: Generate files in working directory shell: bash - run: __tests__/create-cache-files.sh ${{ runner.os }} test-cache + run: __tests__/create-cache-files.sh ${{ runner.os }}-save test-cache - name: Generate files outside working directory shell: bash - run: __tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache + run: __tests__/create-cache-files.sh ${{ runner.os }}-save ~/test-cache - name: Save cache uses: ./ with: @@ -76,10 +77,51 @@ jobs: ~/test-cache - name: Verify cache files in working directory shell: bash - run: __tests__/verify-cache-files.sh ${{ runner.os }} test-cache + run: __tests__/verify-cache-files.sh ${{ runner.os }}-save test-cache - name: Verify cache files outside working directory shell: bash - run: __tests__/verify-cache-files.sh ${{ runner.os }} ~/test-cache + run: __tests__/verify-cache-files.sh ${{ runner.os }}-save ~/test-cache + + # End to end with save-always + test-save-always: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + fail-fast: false + runs-on: ${{ matrix.os }} + continue-on-error: true + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Save cache + id: save-always + uses: ./ + with: + key: test-${{ runner.os }}-${{ github.run_id }}.${{ github.run_attempt }} + path: test-cache + save-always: true + - name: Generate files + shell: bash + run: | + __tests__/create-cache-files.sh ${{ runner.os }}-save-always test-cache + exit 1 + test-save-always-restore: + needs: test-save-always + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + fail-fast: false + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Restore cache + uses: ./ + with: + key: test-${{ runner.os }}-${{ github.run_id }}.${{ github.run_attempt }} + path: test-cache + - name: Verify cache + run: __tests__/verify-cache-files.sh ${{ runner.os }}-save-always test-cache # End to end with proxy test-proxy-save: From 8c04f899de942ffd26bfe76c8ee4a0754e0c4639 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Thu, 6 Jun 2024 22:02:37 -0400 Subject: [PATCH 07/14] Remove test branch --- .github/workflows/workflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9bcbdf3..66112c8 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -9,7 +9,6 @@ on: branches: - main - releases/** - - save-always-output jobs: # Build and unit test From ed49aa27bc58edaffd5e10b28fe0a55150935993 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Thu, 6 Jun 2024 22:17:45 -0400 Subject: [PATCH 08/14] Require build --- .github/workflows/workflow.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 66112c8..0f478fb 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -36,6 +36,7 @@ jobs: # End to end save and restore test-save: + needs: build strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] @@ -83,6 +84,7 @@ jobs: # End to end with save-always test-save-always: + needs: build strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] @@ -124,6 +126,7 @@ jobs: # End to end with proxy test-proxy-save: + needs: build runs-on: ubuntu-latest container: image: ubuntu:latest From eb5e89cf798a44c1da52937a0a35811cd8ae4a35 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Fri, 7 Jun 2024 08:34:34 -0400 Subject: [PATCH 09/14] build --- dist/restore-only/index.js | 7 +++++-- dist/restore/index.js | 7 +++++-- dist/save-only/index.js | 6 ++++-- dist/save/index.js | 6 ++++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/dist/restore-only/index.js b/dist/restore-only/index.js index 9a59ac0..d16d713 100644 --- a/dist/restore-only/index.js +++ b/dist/restore-only/index.js @@ -59324,13 +59324,15 @@ var Inputs; Inputs["UploadChunkSize"] = "upload-chunk-size"; Inputs["EnableCrossOsArchive"] = "enableCrossOsArchive"; Inputs["FailOnCacheMiss"] = "fail-on-cache-miss"; - Inputs["LookupOnly"] = "lookup-only"; // Input for cache, restore action + Inputs["LookupOnly"] = "lookup-only"; + Inputs["SaveAlways"] = "save-always"; // Input for cache action })(Inputs = exports.Inputs || (exports.Inputs = {})); var Outputs; (function (Outputs) { Outputs["CacheHit"] = "cache-hit"; Outputs["CachePrimaryKey"] = "cache-primary-key"; - Outputs["CacheMatchedKey"] = "cache-matched-key"; // Output from restore action + Outputs["CacheMatchedKey"] = "cache-matched-key"; + Outputs["SaveAlways"] = "save-always-d18d746b9"; // Output from cache action, with unique suffix for detection in post-if })(Outputs = exports.Outputs || (exports.Outputs = {})); var State; (function (State) { @@ -59394,6 +59396,7 @@ const stateProvider_1 = __nccwpck_require__(1527); const utils = __importStar(__nccwpck_require__(6850)); function restoreImpl(stateProvider, earlyExit) { return __awaiter(this, void 0, void 0, function* () { + core.setOutput(constants_1.Outputs.SaveAlways, core.getInput(constants_1.Inputs.SaveAlways) || "false"); try { if (!utils.isCacheFeatureAvailable()) { core.setOutput(constants_1.Outputs.CacheHit, "false"); diff --git a/dist/restore/index.js b/dist/restore/index.js index 03a12b5..e593b03 100644 --- a/dist/restore/index.js +++ b/dist/restore/index.js @@ -59324,13 +59324,15 @@ var Inputs; Inputs["UploadChunkSize"] = "upload-chunk-size"; Inputs["EnableCrossOsArchive"] = "enableCrossOsArchive"; Inputs["FailOnCacheMiss"] = "fail-on-cache-miss"; - Inputs["LookupOnly"] = "lookup-only"; // Input for cache, restore action + Inputs["LookupOnly"] = "lookup-only"; + Inputs["SaveAlways"] = "save-always"; // Input for cache action })(Inputs = exports.Inputs || (exports.Inputs = {})); var Outputs; (function (Outputs) { Outputs["CacheHit"] = "cache-hit"; Outputs["CachePrimaryKey"] = "cache-primary-key"; - Outputs["CacheMatchedKey"] = "cache-matched-key"; // Output from restore action + Outputs["CacheMatchedKey"] = "cache-matched-key"; + Outputs["SaveAlways"] = "save-always-d18d746b9"; // Output from cache action, with unique suffix for detection in post-if })(Outputs = exports.Outputs || (exports.Outputs = {})); var State; (function (State) { @@ -59394,6 +59396,7 @@ const stateProvider_1 = __nccwpck_require__(1527); const utils = __importStar(__nccwpck_require__(6850)); function restoreImpl(stateProvider, earlyExit) { return __awaiter(this, void 0, void 0, function* () { + core.setOutput(constants_1.Outputs.SaveAlways, core.getInput(constants_1.Inputs.SaveAlways) || "false"); try { if (!utils.isCacheFeatureAvailable()) { core.setOutput(constants_1.Outputs.CacheHit, "false"); diff --git a/dist/save-only/index.js b/dist/save-only/index.js index f542b2c..ab1a399 100644 --- a/dist/save-only/index.js +++ b/dist/save-only/index.js @@ -59324,13 +59324,15 @@ var Inputs; Inputs["UploadChunkSize"] = "upload-chunk-size"; Inputs["EnableCrossOsArchive"] = "enableCrossOsArchive"; Inputs["FailOnCacheMiss"] = "fail-on-cache-miss"; - Inputs["LookupOnly"] = "lookup-only"; // Input for cache, restore action + Inputs["LookupOnly"] = "lookup-only"; + Inputs["SaveAlways"] = "save-always"; // Input for cache action })(Inputs = exports.Inputs || (exports.Inputs = {})); var Outputs; (function (Outputs) { Outputs["CacheHit"] = "cache-hit"; Outputs["CachePrimaryKey"] = "cache-primary-key"; - Outputs["CacheMatchedKey"] = "cache-matched-key"; // Output from restore action + Outputs["CacheMatchedKey"] = "cache-matched-key"; + Outputs["SaveAlways"] = "save-always-d18d746b9"; // Output from cache action, with unique suffix for detection in post-if })(Outputs = exports.Outputs || (exports.Outputs = {})); var State; (function (State) { diff --git a/dist/save/index.js b/dist/save/index.js index f137655..4906ce9 100644 --- a/dist/save/index.js +++ b/dist/save/index.js @@ -59324,13 +59324,15 @@ var Inputs; Inputs["UploadChunkSize"] = "upload-chunk-size"; Inputs["EnableCrossOsArchive"] = "enableCrossOsArchive"; Inputs["FailOnCacheMiss"] = "fail-on-cache-miss"; - Inputs["LookupOnly"] = "lookup-only"; // Input for cache, restore action + Inputs["LookupOnly"] = "lookup-only"; + Inputs["SaveAlways"] = "save-always"; // Input for cache action })(Inputs = exports.Inputs || (exports.Inputs = {})); var Outputs; (function (Outputs) { Outputs["CacheHit"] = "cache-hit"; Outputs["CachePrimaryKey"] = "cache-primary-key"; - Outputs["CacheMatchedKey"] = "cache-matched-key"; // Output from restore action + Outputs["CacheMatchedKey"] = "cache-matched-key"; + Outputs["SaveAlways"] = "save-always-d18d746b9"; // Output from cache action, with unique suffix for detection in post-if })(Outputs = exports.Outputs || (exports.Outputs = {})); var State; (function (State) { From bbec097e302b04059577d88afed16d23ef494047 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Fri, 7 Jun 2024 08:35:05 -0400 Subject: [PATCH 10/14] Add back test branch --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 0f478fb..1d73fa7 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -9,6 +9,7 @@ on: branches: - main - releases/** + - save-always-output jobs: # Build and unit test From edbb70333f0ad48e001a198b2fad9360f13ed5ab Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Fri, 7 Jun 2024 08:37:02 -0400 Subject: [PATCH 11/14] Remove needs: build --- .github/workflows/workflow.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 1d73fa7..9bcbdf3 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -37,7 +37,6 @@ jobs: # End to end save and restore test-save: - needs: build strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] @@ -85,7 +84,6 @@ jobs: # End to end with save-always test-save-always: - needs: build strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] @@ -127,7 +125,6 @@ jobs: # End to end with proxy test-proxy-save: - needs: build runs-on: ubuntu-latest container: image: ubuntu:latest From 286c02b2b24a58e4c661537a17c28f58f3a6aedb Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Fri, 7 Jun 2024 08:37:38 -0400 Subject: [PATCH 12/14] Remove test ranch again --- .github/workflows/workflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9bcbdf3..66112c8 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -9,7 +9,6 @@ on: branches: - main - releases/** - - save-always-output jobs: # Build and unit test From 72831e69e53ef5f4946db77eec864ae391b6a477 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Fri, 7 Jun 2024 16:42:25 -0400 Subject: [PATCH 13/14] Fix Windows false positive --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 66112c8..4e596d1 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -120,6 +120,7 @@ jobs: key: test-${{ runner.os }}-${{ github.run_id }}.${{ github.run_attempt }} path: test-cache - name: Verify cache + shell: bash run: __tests__/verify-cache-files.sh ${{ runner.os }}-save-always test-cache # End to end with proxy From d9536f63af679b1d0f62406d7503f213608210e5 Mon Sep 17 00:00:00 2001 From: Danny Gleckler Date: Tue, 11 Jun 2024 18:16:26 -0400 Subject: [PATCH 14/14] Clarify that test is expected to fail --- .github/workflows/workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 4e596d1..3bc8d50 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -82,7 +82,7 @@ jobs: run: __tests__/verify-cache-files.sh ${{ runner.os }}-save ~/test-cache # End to end with save-always - test-save-always: + test-save-always-with-failure: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] @@ -105,7 +105,7 @@ jobs: __tests__/create-cache-files.sh ${{ runner.os }}-save-always test-cache exit 1 test-save-always-restore: - needs: test-save-always + needs: test-save-always-with-failure strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest]