From 4c79718f6bd8b6adfe6bf23b4dbf6595d3e7c864 Mon Sep 17 00:00:00 2001
From: Gregorio Litenstein <g.litenstein@gmail.com>
Date: Mon, 3 Feb 2025 15:18:50 -0300
Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20accidentally=20deleting=20cache?=
 =?UTF-8?q?=20from=20base=20branch?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Gregorio Litenstein <g.litenstein@gmail.com>
---
 src/saveImpl.ts          |  1 +
 src/utils/actionUtils.ts | 55 ++++++++++++++++++++++++++++++----------
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/src/saveImpl.ts b/src/saveImpl.ts
index 1ac1882..1035e15 100644
--- a/src/saveImpl.ts
+++ b/src/saveImpl.ts
@@ -69,6 +69,7 @@ export async function saveImpl(
             );
         }
         if (utils.isExactKeyMatch(primaryKey, restoredKey)) {
+            /* istanbul ignore next */
             const { GITHUB_TOKEN, GITHUB_REPOSITORY } = process.env || null;
             if (GITHUB_TOKEN && GITHUB_REPOSITORY && refreshCache === true) {
                 core.info(
diff --git a/src/utils/actionUtils.ts b/src/utils/actionUtils.ts
index 9657285..22a7cc4 100644
--- a/src/utils/actionUtils.ts
+++ b/src/utils/actionUtils.ts
@@ -28,32 +28,61 @@ export function isExactKeyMatch(key: string, cacheKey?: string): boolean {
     );
 }
 
-export async function deleteCacheByKey(key: string, owner: string, repo: string) {
+export function logWarning(message: string): void {
+    const warningPrefix = "[warning]";
+    core.info(`${warningPrefix}${message}`);
+}
+
+export async function deleteCacheByKey(key: string, owner: string, repo: string) : Promise <number | void> {
     const octokit = new Octokit();
     let response;
     try {
-        response = await octokit.rest.actions.deleteActionsCacheByKey({
+        const gitRef = process.env[RefKey];
+        let cacheEntry = await octokit.rest.actions.getActionsCacheList({
+            owner: owner,
+            repo: repo,
+            key: key,
+            ref: gitRef
+            });
+        const { data: {
+            total_count,
+            actions_caches
+            }
+        } = cacheEntry;
+        if (total_count !== 1 || total_count !== actions_caches.length) { // leave all find logic to the actual cache implementation. We just want to make sure we're returned a single element so we don't accidentally delete an entry that belongs to a different gitref.
+            if (total_count > 1) {
+                exports.logWarning(`More than one cache entry found for key ${key}`);
+            }
+            else if (total_count === 0 || actions_caches.length === 0) {
+                exports.logWarning(`No cache entries for key ${key} belong to gitref ${gitRef}.`);
+            }
+            // This situation is likely never actually going to come up.
+            // Istanbul is being dumb and I can't ignore this path.
+            else if (total_count !== actions_caches.length) {
+                exports.logWarning(`Reported cache entry matches for ${key} does not match length of 'actions_caches' array in API response.`);
+            }
+            core.info(`Skip trying to delete cache entry for key ${key}.`)
+            return;
+        }
+        let id = actions_caches[0].id;
+        response = await octokit.rest.actions.deleteActionsCacheById({
             owner: owner,
             repo: repo,
-            key: key
+            cache_id: id
             });
-        if (response.status === 200) {
-            core.info(`Succesfully deleted cache with key: ${response.data.actions_caches[0].key}`);
+        if (response.status === 204) {
+            core.info(`Succesfully deleted cache with key: ${key}, id: ${id}`);
+             return 204;
         }
     } catch (e) {
         if (e instanceof RequestError) {
             let err = e as RequestError;
             let errData = err.response?.data as any | undefined;
-            exports.logWarning(`${err.name} '${err.status}: ${errData?.message}' trying to delete cache with key: ${key}`);
+            exports.logWarning(`Github API reported error: ${err.name} '${err.status}: ${errData?.message}'`);
         }
-        response = e;
+        core.info(`Couldn't delete cache entry for key ${key}.`)
+        return;
     }
-    return response;
-}
-
-export function logWarning(message: string): void {
-    const warningPrefix = "[warning]";
-    core.info(`${warningPrefix}${message}`);
 }
 
 // Cache token authorized for all events that are tied to a ref