From dfd8915e1a6ca3c98b3ac3f6676e1ec7b5b4b3a8 Mon Sep 17 00:00:00 2001
From: Vincent Clemson <vclemson07@gmail.com>
Date: Sun, 19 Jun 2022 20:12:49 -0400
Subject: [PATCH] add state save logic when selecting reevaluation

* add logic to not save state in restore step when setting `reeval` to true
* create infrastructure to set `Inputs.Reeval` input variable
  within tests
* `Inputs.Reeval` set to false for all save & restore tests
---
 __tests__/restore.test.ts |  8 ++++++++
 __tests__/save.test.ts    |  8 ++++++++
 dist/restore/index.js     | 13 +++++++++++--
 dist/save/index.js        | 13 +++++++++----
 src/restore.ts            |  7 ++++++-
 src/save.ts               |  8 ++++----
 src/utils/actionUtils.ts  |  8 ++++++++
 src/utils/testUtils.ts    |  6 ++++++
 8 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts
index b4dbba9..c19a286 100644
--- a/__tests__/restore.test.ts
+++ b/__tests__/restore.test.ts
@@ -27,11 +27,19 @@ beforeAll(() => {
             return actualUtils.getInputAsArray(name, options);
         }
     );
+
+    jest.spyOn(actionUtils, "getInputAsBoolean").mockImplementation(
+        (name, options) => {
+            const actualUtils = jest.requireActual("../src/utils/actionUtils");
+            return actualUtils.getInputAsBoolean(name, options);
+        }
+    );
 });
 
 beforeEach(() => {
     process.env[Events.Key] = Events.Push;
     process.env[RefKey] = "refs/heads/feature-branch";
+    testUtils.setInput(Inputs.Reeval, "false");
 
     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
diff --git a/__tests__/save.test.ts b/__tests__/save.test.ts
index 7598e0c..95d2b60 100644
--- a/__tests__/save.test.ts
+++ b/__tests__/save.test.ts
@@ -27,6 +27,13 @@ beforeAll(() => {
         }
     );
 
+    jest.spyOn(actionUtils, "getInputAsBoolean").mockImplementation(
+        (name, options) => {
+            const actualUtils = jest.requireActual("../src/utils/actionUtils");
+            return actualUtils.getInputAsBoolean(name, options);
+        }
+    );
+
     jest.spyOn(actionUtils, "getInputAsInt").mockImplementation(
         (name, options) => {
             return jest
@@ -52,6 +59,7 @@ beforeAll(() => {
 beforeEach(() => {
     process.env[Events.Key] = Events.Push;
     process.env[RefKey] = "refs/heads/feature-branch";
+    testUtils.setInput(Inputs.Reeval, "false");
 
     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false);
     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation(
diff --git a/dist/restore/index.js b/dist/restore/index.js
index a1bc1b5..4b1bcc4 100644
--- a/dist/restore/index.js
+++ b/dist/restore/index.js
@@ -37588,7 +37588,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
     return result;
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.getCacheState = exports.setOutputAndState = exports.setCacheHitOutput = exports.setCacheState = exports.isExactKeyMatch = exports.isGhes = void 0;
+exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsBoolean = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.getCacheState = exports.setOutputAndState = exports.setCacheHitOutput = exports.setCacheState = exports.isExactKeyMatch = exports.isGhes = void 0;
 const cache = __importStar(__webpack_require__(692));
 const core = __importStar(__webpack_require__(470));
 const constants_1 = __webpack_require__(196);
@@ -37646,6 +37646,11 @@ function getInputAsArray(name, options) {
         .filter(x => x !== "");
 }
 exports.getInputAsArray = getInputAsArray;
+function getInputAsBoolean(name, options) {
+    const value = core.getBooleanInput(name, options);
+    return value;
+}
+exports.getInputAsBoolean = getInputAsBoolean;
 function getInputAsInt(name, options) {
     const value = parseInt(core.getInput(name, options));
     if (isNaN(value) || value < 0) {
@@ -48993,7 +48998,11 @@ function run() {
                 return;
             }
             const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true });
-            core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
+            // when selecting to reevaluate primary key - state is saved in save step
+            const reeval = utils.getInputAsBoolean(constants_1.Inputs.Reeval);
+            if (!reeval) {
+                core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
+            }
             const restoreKeys = utils.getInputAsArray(constants_1.Inputs.RestoreKeys);
             const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, {
                 required: true
diff --git a/dist/save/index.js b/dist/save/index.js
index 4d7e109..f1da856 100644
--- a/dist/save/index.js
+++ b/dist/save/index.js
@@ -37588,7 +37588,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
     return result;
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.getCacheState = exports.setOutputAndState = exports.setCacheHitOutput = exports.setCacheState = exports.isExactKeyMatch = exports.isGhes = void 0;
+exports.isCacheFeatureAvailable = exports.getInputAsInt = exports.getInputAsBoolean = exports.getInputAsArray = exports.isValidEvent = exports.logWarning = exports.getCacheState = exports.setOutputAndState = exports.setCacheHitOutput = exports.setCacheState = exports.isExactKeyMatch = exports.isGhes = void 0;
 const cache = __importStar(__webpack_require__(692));
 const core = __importStar(__webpack_require__(470));
 const constants_1 = __webpack_require__(196);
@@ -37646,6 +37646,11 @@ function getInputAsArray(name, options) {
         .filter(x => x !== "");
 }
 exports.getInputAsArray = getInputAsArray;
+function getInputAsBoolean(name, options) {
+    const value = core.getBooleanInput(name, options);
+    return value;
+}
+exports.getInputAsBoolean = getInputAsBoolean;
 function getInputAsInt(name, options) {
     const value = parseInt(core.getInput(name, options));
     if (isNaN(value) || value < 0) {
@@ -46782,14 +46787,15 @@ function run() {
                     utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
                     return;
                 }
+                const state = utils.getCacheState();
                 let primaryKey = "";
-                const reeval = core.getBooleanInput(constants_1.Inputs.Reeval);
+                const reeval = utils.getInputAsBoolean(constants_1.Inputs.Reeval);
                 if (!reeval) {
                     // Inputs are reevaluted before the post action, so we want the original key used for restore
                     primaryKey = core.getState(constants_1.State.CachePrimaryKey);
                 }
                 else {
-                    // choose to reevaluate primary key - resave state to correctly test cache hit
+                    // choose to reevaluate primary key - resave state to correctly test cache hit on next run
                     primaryKey = core.getInput(constants_1.Inputs.Key, { required: true });
                     core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
                 }
@@ -46797,7 +46803,6 @@ function run() {
                     utils.logWarning(`Error retrieving key from state.`);
                     return;
                 }
-                const state = utils.getCacheState();
                 if (utils.isExactKeyMatch(primaryKey, state)) {
                     core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
                     return;
diff --git a/src/restore.ts b/src/restore.ts
index 648e4cb..cde8dd8 100644
--- a/src/restore.ts
+++ b/src/restore.ts
@@ -22,7 +22,12 @@ async function run(): Promise<void> {
         }
 
         const primaryKey = core.getInput(Inputs.Key, { required: true });
-        core.saveState(State.CachePrimaryKey, primaryKey);
+
+        // when selecting to reevaluate primary key - state is saved in save step
+        const reeval = utils.getInputAsBoolean(Inputs.Reeval);
+        if (!reeval) {
+            core.saveState(State.CachePrimaryKey, primaryKey);
+        }
 
         const restoreKeys = utils.getInputAsArray(Inputs.RestoreKeys);
         const cachePaths = utils.getInputAsArray(Inputs.Path, {
diff --git a/src/save.ts b/src/save.ts
index 1dfd059..e9fb026 100644
--- a/src/save.ts
+++ b/src/save.ts
@@ -26,13 +26,15 @@ async function run(): Promise<void> {
                 return;
             }
 
+            const state = utils.getCacheState();
+
             let primaryKey = "";
-            const reeval = core.getBooleanInput(Inputs.Reeval);
+            const reeval = utils.getInputAsBoolean(Inputs.Reeval);
             if (!reeval) {
                 // Inputs are reevaluted before the post action, so we want the original key used for restore
                 primaryKey = core.getState(State.CachePrimaryKey);
             } else {
-                // choose to reevaluate primary key - resave state to correctly test cache hit
+                // choose to reevaluate primary key - resave state to correctly test cache hit on next run
                 primaryKey = core.getInput(Inputs.Key, { required: true });
                 core.saveState(State.CachePrimaryKey, primaryKey);
             }
@@ -41,8 +43,6 @@ async function run(): Promise<void> {
                 return;
             }
 
-            const state = utils.getCacheState();
-
             if (utils.isExactKeyMatch(primaryKey, state)) {
                 core.info(
                     `Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
diff --git a/src/utils/actionUtils.ts b/src/utils/actionUtils.ts
index 69e0220..3da21f9 100644
--- a/src/utils/actionUtils.ts
+++ b/src/utils/actionUtils.ts
@@ -65,6 +65,14 @@ export function getInputAsArray(
         .filter(x => x !== "");
 }
 
+export function getInputAsBoolean(
+    name: string,
+    options?: core.InputOptions
+): boolean {
+    const value = core.getBooleanInput(name, options);
+    return value;    
+}
+
 export function getInputAsInt(
     name: string,
     options?: core.InputOptions
diff --git a/src/utils/testUtils.ts b/src/utils/testUtils.ts
index 9e2134f..3674eb0 100644
--- a/src/utils/testUtils.ts
+++ b/src/utils/testUtils.ts
@@ -12,12 +12,16 @@ export function setInput(name: string, value: string): void {
 interface CacheInput {
     path: string;
     key: string;
+    // onlyRestore: string;
+    // reeval: string;
     restoreKeys?: string[];
 }
 
 export function setInputs(input: CacheInput): void {
     setInput(Inputs.Path, input.path);
     setInput(Inputs.Key, input.key);
+    // setInput(Inputs.OnlyRestore, input.onlyRestore);
+    // setInput(Inputs.Reeval, input.reeval);
     input.restoreKeys &&
         setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
 }
@@ -27,4 +31,6 @@ export function clearInputs(): void {
     delete process.env[getInputName(Inputs.Key)];
     delete process.env[getInputName(Inputs.RestoreKeys)];
     delete process.env[getInputName(Inputs.UploadChunkSize)];
+    delete process.env[getInputName(Inputs.OnlyRestore)];
+    delete process.env[getInputName(Inputs.Reeval)];
 }