From e44e77f96836dea77bb6dbf3e4861aa7a01aa8e9 Mon Sep 17 00:00:00 2001
From: "Jason T. Greene" <jason.greene@redhat.com>
Date: Wed, 29 Jan 2020 16:53:20 -0500
Subject: [PATCH] Add a restore-only option to support pulling without saving a
 cache entry

---
 __tests__/save.test.ts | 44 ++++++++++++++++++++++++++++++++++++++++++
 action.yml             |  3 +++
 src/constants.ts       |  3 ++-
 src/save.ts            |  7 +++++++
 4 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/__tests__/save.test.ts b/__tests__/save.test.ts
index b355076..75938f1 100644
--- a/__tests__/save.test.ts
+++ b/__tests__/save.test.ts
@@ -376,3 +376,47 @@ test("save with valid inputs uploads a cache", async () => {
 
     expect(failedMock).toHaveBeenCalledTimes(0);
 });
+
+test("save skipped with restore only", async () => {
+    const infoMock = jest.spyOn(core, "info");
+
+    const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
+    const cacheEntry: ArtifactCacheEntry = {
+        cacheKey: "Linux-node-",
+        scope: "refs/heads/master",
+        creationTime: "2019-11-13T19:18:02+00:00",
+        archiveLocation: "www.actionscache.test/download"
+    };
+
+    jest.spyOn(core, "getState")
+        // Cache Entry State
+        .mockImplementationOnce(() => {
+            return JSON.stringify(cacheEntry);
+        })
+        // Cache Key State
+        .mockImplementationOnce(() => {
+            return primaryKey;
+        });
+
+    const inputPath = "node_modules";
+    testUtils.setInput(Inputs.Path, inputPath);
+    testUtils.setInput(Inputs.RestoreOnly, "true");
+
+    const cacheId = 4;
+    const reserveCacheMock = jest
+        .spyOn(cacheHttpClient, "reserveCache")
+        .mockImplementationOnce(() => {
+            return Promise.resolve(cacheId);
+        });
+
+    const saveCacheMock = jest.spyOn(cacheHttpClient, "saveCache");
+
+    await run();
+
+    expect(infoMock).toHaveBeenCalledWith(
+        "Cache action configured for restore-only, skipping save step"
+    );
+
+    expect(reserveCacheMock).toHaveBeenCalledTimes(0);
+    expect(saveCacheMock).toHaveBeenCalledTimes(0);
+});
diff --git a/action.yml b/action.yml
index cc77f1b..7af781e 100644
--- a/action.yml
+++ b/action.yml
@@ -11,6 +11,9 @@ inputs:
   restore-keys:
     description: 'An ordered list of keys to use for restoring the cache if no cache hit occurred for key'
     required: false
+  restore-only:
+    description: 'Disables saving a new cache entry when true'
+    required: 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 5f26e8c..9c41c59 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,7 +1,8 @@
 export enum Inputs {
     Key = "key",
     Path = "path",
-    RestoreKeys = "restore-keys"
+    RestoreKeys = "restore-keys",
+    RestoreOnly = "restore-only"
 }
 
 export enum Outputs {
diff --git a/src/save.ts b/src/save.ts
index ee64e42..cf4facf 100644
--- a/src/save.ts
+++ b/src/save.ts
@@ -18,6 +18,13 @@ async function run(): Promise<void> {
             return;
         }
 
+        if (core.getInput(Inputs.RestoreOnly) === "true") {
+            core.info(
+                "Cache action configured for restore-only, skipping save step"
+            );
+            return;
+        }
+
         const state = utils.getCacheState();
 
         // Inputs are re-evaluted before the post action, so we want the original key used for restore