From 80640a33353daa7039832feecbaf9e58cba49e39 Mon Sep 17 00:00:00 2001 From: Sam Eagen Date: Tue, 3 Sep 2024 16:45:06 -0400 Subject: [PATCH 1/2] Remove destination folder if mpm fails --- src/mpm.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mpm.ts b/src/mpm.ts index 7556be1..60ba2d6 100644 --- a/src/mpm.ts +++ b/src/mpm.ts @@ -2,6 +2,7 @@ import * as exec from "@actions/exec"; import * as tc from "@actions/tool-cache"; +import {rmRF} from "@actions/io"; import * as path from "path"; import * as matlab from "./matlab"; import properties from "./properties.json"; @@ -68,6 +69,9 @@ export async function install(mpmPath: string, release: matlab.Release, products const exitCode = await exec.exec(mpmPath, mpmArguments); if (exitCode !== 0) { + // Fully remove failed MATLAB installation for self-hosted runners + await rmRF(destination); + return Promise.reject(Error(`Script exited with non-zero code ${exitCode}`)); } return From b410805f0e96244a23acaf3867e8e414fc617d8f Mon Sep 17 00:00:00 2001 From: Sam Eagen Date: Wed, 4 Sep 2024 11:00:35 -0400 Subject: [PATCH 2/2] Remove potentially poisoned MATLAB intall when mpm fails --- src/mpm.ts | 8 +++++--- src/mpm.unit.test.ts | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mpm.ts b/src/mpm.ts index 60ba2d6..5d3efec 100644 --- a/src/mpm.ts +++ b/src/mpm.ts @@ -67,11 +67,13 @@ export async function install(mpmPath: string, release: matlab.Release, products } mpmArguments = mpmArguments.concat("--products", ...parsedProducts); - const exitCode = await exec.exec(mpmPath, mpmArguments); - if (exitCode !== 0) { + const exitCode = await exec.exec(mpmPath, mpmArguments).catch(async e => { // Fully remove failed MATLAB installation for self-hosted runners await rmRF(destination); - + throw e; + }); + if (exitCode !== 0) { + await rmRF(destination); return Promise.reject(Error(`Script exited with non-zero code ${exitCode}`)); } return diff --git a/src/mpm.unit.test.ts b/src/mpm.unit.test.ts index 3644b0e..37d2cf5 100644 --- a/src/mpm.unit.test.ts +++ b/src/mpm.unit.test.ts @@ -2,6 +2,7 @@ import * as exec from "@actions/exec"; import * as tc from "@actions/tool-cache"; +import * as io from "@actions/io"; import * as path from "path"; import * as mpm from "./mpm"; import * as script from "./script"; @@ -9,6 +10,7 @@ import * as script from "./script"; jest.mock("@actions/core"); jest.mock("@actions/exec"); jest.mock("@actions/tool-cache"); +jest.mock("@actions/io"); jest.mock("./script"); afterEach(() => { @@ -101,11 +103,13 @@ describe("setup mpm", () => { describe("mpm install", () => { let execMock: jest.Mock; + let rmRFMock: jest.Mock; const mpmPath = "mpm"; const releaseInfo = {name: "r2022b", version: "9.13.0", update: "", isPrerelease: false}; const mpmRelease = "r2022b"; beforeEach(() => { execMock = exec.exec as jest.Mock; + rmRFMock = io.rmRF as jest.Mock; }); it("works with multiline products list", async () => { @@ -161,10 +165,19 @@ describe("mpm install", () => { expect(execMock.mock.calls[0][1]).toMatchObject(expectedMpmArgs); }); - it("rejects on failed install", async () => { + it("rejects and cleans on mpm rejection", async () => { + const destination = "/opt/matlab"; + const products = ["MATLAB", "Compiler"]; + execMock.mockRejectedValue(1); + await expect(mpm.install(mpmPath, releaseInfo, products, destination)).rejects.toBeDefined(); + expect(rmRFMock).toHaveBeenCalledWith(destination); + }); + + it("rejects and cleans on failed install", async () => { const destination = "/opt/matlab"; const products = ["MATLAB", "Compiler"]; execMock.mockResolvedValue(1); await expect(mpm.install(mpmPath, releaseInfo, products, destination)).rejects.toBeDefined(); + expect(rmRFMock).toHaveBeenCalledWith(destination); }); });