From cae64ca3cdc901a87ed2d9eb4fa2ffa462e2139e Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Wed, 18 Mar 2020 13:43:56 +0000 Subject: [PATCH] Attempt to delete the archive after extraction (#209) This reduces storage space used once the Action has finished executing. --- __tests__/actionUtils.test.ts | 13 +++++++++++++ __tests__/restore.test.ts | 4 ++++ dist/restore/index.js | 28 ++++++++++++++++++++++------ dist/save/index.js | 5 +++++ src/restore.ts | 33 +++++++++++++++++++++------------ src/utils/actionUtils.ts | 5 +++++ 6 files changed, 70 insertions(+), 18 deletions(-) diff --git a/__tests__/actionUtils.test.ts b/__tests__/actionUtils.test.ts index f46d65d..d833171 100644 --- a/__tests__/actionUtils.test.ts +++ b/__tests__/actionUtils.test.ts @@ -1,4 +1,5 @@ import * as core from "@actions/core"; +import * as fs from "fs"; import * as os from "os"; import * as path from "path"; @@ -234,3 +235,15 @@ test("isValidEvent returns true for pull request event", () => { expect(isValidEvent).toBe(true); }); + +test("unlinkFile unlinks file", async () => { + const testDirectory = fs.mkdtempSync("unlinkFileTest"); + const testFile = path.join(testDirectory, "test.txt"); + fs.writeFileSync(testFile, "hello world"); + + await actionUtils.unlinkFile(testFile); + + expect(fs.existsSync(testFile)).toBe(false); + + fs.rmdirSync(testDirectory); +}); diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts index 212ec30..8d74fe6 100644 --- a/__tests__/restore.test.ts +++ b/__tests__/restore.test.ts @@ -241,6 +241,7 @@ test("restore with cache found", async () => { .mockReturnValue(fileSize); const extractTarMock = jest.spyOn(tar, "extractTar"); + const unlinkFileMock = jest.spyOn(actionUtils, "unlinkFile"); const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); await run(); @@ -258,6 +259,9 @@ test("restore with cache found", async () => { expect(extractTarMock).toHaveBeenCalledTimes(1); expect(extractTarMock).toHaveBeenCalledWith(archivePath, cachePath); + expect(unlinkFileMock).toHaveBeenCalledTimes(1); + expect(unlinkFileMock).toHaveBeenCalledWith(archivePath); + expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); expect(setCacheHitOutputMock).toHaveBeenCalledWith(true); diff --git a/dist/restore/index.js b/dist/restore/index.js index a3ea855..9483a2b 100644 --- a/dist/restore/index.js +++ b/dist/restore/index.js @@ -1651,6 +1651,7 @@ const io = __importStar(__webpack_require__(1)); const fs = __importStar(__webpack_require__(747)); const os = __importStar(__webpack_require__(87)); const path = __importStar(__webpack_require__(622)); +const util = __importStar(__webpack_require__(669)); const uuidV4 = __importStar(__webpack_require__(826)); const constants_1 = __webpack_require__(694); // From https://github.com/actions/toolkit/blob/master/packages/tool-cache/src/tool-cache.ts#L23 @@ -1743,6 +1744,10 @@ function isValidEvent() { return getSupportedEvents().includes(githubEvent); } exports.isValidEvent = isValidEvent; +function unlinkFile(path) { + return util.promisify(fs.unlink)(path); +} +exports.unlinkFile = unlinkFile; /***/ }), @@ -2831,18 +2836,29 @@ function run() { try { const cacheEntry = yield cacheHttpClient.getCacheEntry(keys); if (!((_a = cacheEntry) === null || _a === void 0 ? void 0 : _a.archiveLocation)) { - core.info(`Cache not found for input keys: ${keys.join(", ")}.`); + core.info(`Cache not found for input keys: ${keys.join(", ")}`); return; } const archivePath = path.join(yield utils.createTempDirectory(), "cache.tgz"); core.debug(`Archive Path: ${archivePath}`); // Store the cache result utils.setCacheState(cacheEntry); - // Download the cache from the cache entry - yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath); - const archiveFileSize = utils.getArchiveFileSize(archivePath); - core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); - yield tar_1.extractTar(archivePath, cachePath); + try { + // Download the cache from the cache entry + yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath); + const archiveFileSize = utils.getArchiveFileSize(archivePath); + core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + yield tar_1.extractTar(archivePath, cachePath); + } + finally { + // Try to delete the archive to save space + try { + yield utils.unlinkFile(archivePath); + } + catch (error) { + core.debug(`Failed to delete archive: ${error}`); + } + } const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheEntry); utils.setCacheHitOutput(isExactKeyMatch); core.info(`Cache restored from key: ${cacheEntry && cacheEntry.cacheKey}`); diff --git a/dist/save/index.js b/dist/save/index.js index e7e0eae..b3a9457 100644 --- a/dist/save/index.js +++ b/dist/save/index.js @@ -1651,6 +1651,7 @@ const io = __importStar(__webpack_require__(1)); const fs = __importStar(__webpack_require__(747)); const os = __importStar(__webpack_require__(87)); const path = __importStar(__webpack_require__(622)); +const util = __importStar(__webpack_require__(669)); const uuidV4 = __importStar(__webpack_require__(826)); const constants_1 = __webpack_require__(694); // From https://github.com/actions/toolkit/blob/master/packages/tool-cache/src/tool-cache.ts#L23 @@ -1743,6 +1744,10 @@ function isValidEvent() { return getSupportedEvents().includes(githubEvent); } exports.isValidEvent = isValidEvent; +function unlinkFile(path) { + return util.promisify(fs.unlink)(path); +} +exports.unlinkFile = unlinkFile; /***/ }), diff --git a/src/restore.ts b/src/restore.ts index 721a8e3..ce753bb 100644 --- a/src/restore.ts +++ b/src/restore.ts @@ -75,20 +75,29 @@ async function run(): Promise { // Store the cache result utils.setCacheState(cacheEntry); - // Download the cache from the cache entry - await cacheHttpClient.downloadCache( - cacheEntry.archiveLocation, - archivePath - ); + try { + // Download the cache from the cache entry + await cacheHttpClient.downloadCache( + cacheEntry.archiveLocation, + archivePath + ); - const archiveFileSize = utils.getArchiveFileSize(archivePath); - core.info( - `Cache Size: ~${Math.round( - archiveFileSize / (1024 * 1024) - )} MB (${archiveFileSize} B)` - ); + const archiveFileSize = utils.getArchiveFileSize(archivePath); + core.info( + `Cache Size: ~${Math.round( + archiveFileSize / (1024 * 1024) + )} MB (${archiveFileSize} B)` + ); - await extractTar(archivePath, cachePath); + await extractTar(archivePath, cachePath); + } finally { + // Try to delete the archive to save space + try { + await utils.unlinkFile(archivePath); + } catch (error) { + core.debug(`Failed to delete archive: ${error}`); + } + } const isExactKeyMatch = utils.isExactKeyMatch( primaryKey, diff --git a/src/utils/actionUtils.ts b/src/utils/actionUtils.ts index f6369fb..5fbe2cf 100644 --- a/src/utils/actionUtils.ts +++ b/src/utils/actionUtils.ts @@ -3,6 +3,7 @@ import * as io from "@actions/io"; import * as fs from "fs"; import * as os from "os"; import * as path from "path"; +import * as util from "util"; import * as uuidV4 from "uuid/v4"; import { Events, Outputs, State } from "../constants"; @@ -105,3 +106,7 @@ export function isValidEvent(): boolean { const githubEvent = process.env[Events.Key] || ""; return getSupportedEvents().includes(githubEvent); } + +export function unlinkFile(path: fs.PathLike): Promise { + return util.promisify(fs.unlink)(path); +}