From fa2f4155aae35c8c778c1660b04686818407b410 Mon Sep 17 00:00:00 2001
From: Matt Johnson-Pint <matt.johnson-pint@sentry.io>
Date: Fri, 18 Nov 2022 14:19:10 -0800
Subject: [PATCH] Add option reevaluate the key

---
 __tests__/save.test.ts | 28 ++++++++++++++++++++++++++++
 action.yml             |  4 ++++
 src/constants.ts       |  3 ++-
 src/save.ts            | 16 +++++++++++-----
 4 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/__tests__/save.test.ts b/__tests__/save.test.ts
index 4a3ae39..9d9b17b 100644
--- a/__tests__/save.test.ts
+++ b/__tests__/save.test.ts
@@ -389,3 +389,31 @@ test("save with valid inputs uploads a cache", async () => {
 
     expect(failedMock).toHaveBeenCalledTimes(0);
 });
+
+test("save with reevaluate-key uses the key", async () => {
+    const failedMock = jest.spyOn(core, "setFailed");
+
+    const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
+
+    const inputPath = "node_modules";
+    testUtils.setInput(Inputs.Path, inputPath);
+    testUtils.setInput(Inputs.Key, primaryKey);
+    testUtils.setInput(Inputs.ReevaluateKey, "true");
+    testUtils.setInput(Inputs.UploadChunkSize, "4000000");
+
+    const cacheId = 4;
+    const saveCacheMock = jest
+        .spyOn(cache, "saveCache")
+        .mockImplementationOnce(() => {
+            return Promise.resolve(cacheId);
+        });
+
+    await run();
+
+    expect(saveCacheMock).toHaveBeenCalledTimes(1);
+    expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, {
+        uploadChunkSize: 4000000
+    });
+
+    expect(failedMock).toHaveBeenCalledTimes(0);
+});
diff --git a/action.yml b/action.yml
index 3e158e3..678c139 100644
--- a/action.yml
+++ b/action.yml
@@ -14,6 +14,10 @@ inputs:
   upload-chunk-size:
     description: 'The chunk size used to split up large files during upload, in bytes'
     required: false
+  reevaluate-key:
+    description: 'If set to true, the key will be re-evaluated when saving the cache.'
+    required: false
+    default: false
 outputs:
   cache-hit:
     description: 'A boolean value to indicate an exact match was found for the primary key'
diff --git a/src/constants.ts b/src/constants.ts
index 133f47d..8c4ee39 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -2,7 +2,8 @@ export enum Inputs {
     Key = "key",
     Path = "path",
     RestoreKeys = "restore-keys",
-    UploadChunkSize = "upload-chunk-size"
+    UploadChunkSize = "upload-chunk-size",
+    ReevaluateKey = "reevaluate-key"
 }
 
 export enum Outputs {
diff --git a/src/save.ts b/src/save.ts
index a0a21bf..a83f521 100644
--- a/src/save.ts
+++ b/src/save.ts
@@ -26,11 +26,17 @@ async function run(): Promise<void> {
 
         const state = utils.getCacheState();
 
-        // Inputs are re-evaluted before the post action, so we want the original key used for restore
-        const primaryKey = core.getState(State.CachePrimaryKey);
-        if (!primaryKey) {
-            utils.logWarning(`Error retrieving key from state.`);
-            return;
+        let primaryKey : string;
+        if (core.getInput(Inputs.ReevaluateKey)?.toLowerCase() === 'true') {
+            // Inputs are re-evaluated before the post action
+            primaryKey = core.getInput(Inputs.Key);
+        } else {
+            // Get the original key used for restore from the cache
+            primaryKey = core.getState(State.CachePrimaryKey);
+            if (!primaryKey) {
+                utils.logWarning(`Error retrieving key from state.`);
+                return;
+            }
         }
 
         if (utils.isExactKeyMatch(primaryKey, state)) {