From f01652d80dd67c113009766ddfc677991f320a4c Mon Sep 17 00:00:00 2001 From: Edgars Date: Sun, 26 Jul 2026 18:50:29 +0100 Subject: [PATCH 1/2] fix: compile deploy scripts in a temporary directory --- src/commands/contracts/deploy.ts | 12 ++++++++++-- tests/actions/deploy.test.ts | 22 ++++++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/commands/contracts/deploy.ts b/src/commands/contracts/deploy.ts index d3eb1bcc..9abc875d 100644 --- a/src/commands/contracts/deploy.ts +++ b/src/commands/contracts/deploy.ts @@ -1,4 +1,5 @@ import fs from "fs"; +import os from "os"; import path from "path"; import {BaseAction} from "../../lib/actions/BaseAction"; import {pathToFileURL} from "url"; @@ -34,9 +35,14 @@ export class DeployAction extends BaseAction { } private async executeTsScript(filePath: string, rpcUrl?: string): Promise { - const outFile = filePath.replace(/\.ts$/, ".compiled.js"); + let tempDir: string | undefined; this.startSpinner(`Transpiling TypeScript file: ${filePath}`); try { + tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "genlayer-deploy-")); + const outFile = path.join( + tempDir, + path.basename(filePath).replace(/\.ts$/, ".compiled.js"), + ); buildSync({ entryPoints: [filePath], outfile: outFile, @@ -50,7 +56,9 @@ export class DeployAction extends BaseAction { } catch (error) { this.failSpinner(`Error executing: ${filePath}`, error); } finally { - fs.unlinkSync(outFile); + if (tempDir) { + fs.rmSync(tempDir, {recursive: true, force: true}); + } } } diff --git a/tests/actions/deploy.test.ts b/tests/actions/deploy.test.ts index 35ba7877..67204762 100644 --- a/tests/actions/deploy.test.ts +++ b/tests/actions/deploy.test.ts @@ -28,6 +28,8 @@ describe("DeployAction", () => { vi.clearAllMocks(); // Setup mocks before creating the action (needed for constructor) vi.mocked(os.homedir).mockReturnValue("/mocked/home"); + vi.mocked(os.tmpdir).mockReturnValue("/mocked/tmp"); + vi.mocked(fs.mkdtempSync).mockReturnValue("/mocked/tmp/genlayer-deploy-abc"); vi.mocked(fs.existsSync).mockReturnValue(true); vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify({activeAccount: "default"})); @@ -427,7 +429,7 @@ describe("DeployAction", () => { test("executeTsScript transpiles and executes TypeScript", async () => { const filePath = "/mocked/script.ts"; - const outFile = "/mocked/script.compiled.js"; + const outFile = "/mocked/tmp/genlayer-deploy-abc/script.compiled.js"; vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined); vi.mocked(buildSync).mockImplementation((() => {}) as any); @@ -446,7 +448,12 @@ describe("DeployAction", () => { }); expect(deployer["executeJsScript"]).toHaveBeenCalledWith(filePath, outFile, undefined); - expect(fs.unlinkSync).toHaveBeenCalledWith(outFile); + expect(fs.mkdtempSync).toHaveBeenCalledWith("/mocked/tmp/genlayer-deploy-"); + expect(fs.rmSync).toHaveBeenCalledWith("/mocked/tmp/genlayer-deploy-abc", { + recursive: true, + force: true, + }); + expect(fs.unlinkSync).not.toHaveBeenCalled(); }); test("deployScripts fails when deploy folder is missing", async () => { @@ -595,6 +602,10 @@ describe("DeployAction", () => { await deployer["executeTsScript"](filePath); expect(deployer["failSpinner"]).toHaveBeenCalledWith(`Error executing: ${filePath}`, error); + expect(fs.rmSync).toHaveBeenCalledWith("/mocked/tmp/genlayer-deploy-abc", { + recursive: true, + force: true, + }); }); test("deploys contract with rpc option", async () => { @@ -649,7 +660,7 @@ describe("DeployAction", () => { test("executeTsScript passes rpc url to executeJsScript", async () => { const filePath = "/mocked/script.ts"; - const outFile = "/mocked/script.compiled.js"; + const outFile = "/mocked/tmp/genlayer-deploy-abc/script.compiled.js"; const rpcUrl = "https://custom-rpc-url.com"; vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined); @@ -669,7 +680,10 @@ describe("DeployAction", () => { }); expect(deployer["executeJsScript"]).toHaveBeenCalledWith(filePath, outFile, rpcUrl); - expect(fs.unlinkSync).toHaveBeenCalledWith(outFile); + expect(fs.rmSync).toHaveBeenCalledWith("/mocked/tmp/genlayer-deploy-abc", { + recursive: true, + force: true, + }); }); test("deployScripts passes rpc url to script execution methods", async () => { From 036387332b6b9b5dd1e0e6e25fa2eedbb6b19d0b Mon Sep 17 00:00:00 2001 From: Edgars Date: Sun, 26 Jul 2026 18:59:31 +0100 Subject: [PATCH 2/2] test: make deploy temp paths cross-platform --- tests/actions/deploy.test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/actions/deploy.test.ts b/tests/actions/deploy.test.ts index 67204762..d3ebb609 100644 --- a/tests/actions/deploy.test.ts +++ b/tests/actions/deploy.test.ts @@ -1,6 +1,7 @@ import {describe, test, vi, beforeEach, afterEach, expect} from "vitest"; import fs from "fs"; import os from "os"; +import path from "path"; import {createClient, createAccount, isSuccessful, formatStakingAmount, DEPLOY_CALL_KEY} from "genlayer-js"; import {DeployAction, DeployOptions} from "../../src/commands/contracts/deploy"; import {buildSync} from "esbuild"; @@ -429,7 +430,7 @@ describe("DeployAction", () => { test("executeTsScript transpiles and executes TypeScript", async () => { const filePath = "/mocked/script.ts"; - const outFile = "/mocked/tmp/genlayer-deploy-abc/script.compiled.js"; + const outFile = path.join("/mocked/tmp/genlayer-deploy-abc", "script.compiled.js"); vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined); vi.mocked(buildSync).mockImplementation((() => {}) as any); @@ -448,7 +449,7 @@ describe("DeployAction", () => { }); expect(deployer["executeJsScript"]).toHaveBeenCalledWith(filePath, outFile, undefined); - expect(fs.mkdtempSync).toHaveBeenCalledWith("/mocked/tmp/genlayer-deploy-"); + expect(fs.mkdtempSync).toHaveBeenCalledWith(path.join("/mocked/tmp", "genlayer-deploy-")); expect(fs.rmSync).toHaveBeenCalledWith("/mocked/tmp/genlayer-deploy-abc", { recursive: true, force: true, @@ -660,7 +661,7 @@ describe("DeployAction", () => { test("executeTsScript passes rpc url to executeJsScript", async () => { const filePath = "/mocked/script.ts"; - const outFile = "/mocked/tmp/genlayer-deploy-abc/script.compiled.js"; + const outFile = path.join("/mocked/tmp/genlayer-deploy-abc", "script.compiled.js"); const rpcUrl = "https://custom-rpc-url.com"; vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined);