From 204a0d504a1006cf78d8837fb98b8f5810cc46e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:41:41 +0000 Subject: [PATCH 1/3] Initial plan From 2c686d6b4af09d565a3fb58c706eda1fc2f3e431 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:49:21 +0000 Subject: [PATCH 2/3] Add core shim for Node.js execution - Create core_shim.cjs with minimal core object implementation - Load shim in safe-inputs and safe-outputs MCP servers - Add core_shim.cjs to setup.sh file lists for both servers - Add comprehensive tests for core shim Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/core_shim.cjs | 74 ++++++++++ actions/setup/js/core_shim.test.cjs | 146 +++++++++++++++++++ actions/setup/js/safe_inputs_mcp_server.cjs | 7 + actions/setup/js/safe_outputs_mcp_server.cjs | 7 + actions/setup/setup.sh | 2 + 5 files changed, 236 insertions(+) create mode 100644 actions/setup/js/core_shim.cjs create mode 100644 actions/setup/js/core_shim.test.cjs diff --git a/actions/setup/js/core_shim.cjs b/actions/setup/js/core_shim.cjs new file mode 100644 index 0000000000..ae5237bb7f --- /dev/null +++ b/actions/setup/js/core_shim.cjs @@ -0,0 +1,74 @@ +// @ts-check + +/** + * GitHub Actions Core Object Shim + * + * This module provides a lightweight shim of the @actions/core object for use + * in Node.js environments where @actions/core is not available (e.g., MCP servers, + * safe-inputs, safe-outputs running outside GitHub Actions). + * + * When running in GitHub Actions context with @actions/core available, this shim + * is not needed. However, when the same code needs to run in a Node.js environment, + * this shim provides compatible logging methods that fall back to console output. + * + * Usage: + * const core = require("./core_shim.cjs"); + * core.info("Information message"); + * core.warning("Warning message"); + * core.error("Error message"); + * core.debug("Debug message"); + * core.setFailed("Fatal error message"); + */ + +/** + * Core shim object that provides GitHub Actions core-compatible logging + * methods that work in both GitHub Actions and Node.js environments. + */ +const coreShim = { + /** + * Write an informational message + * @param {string} message - The message to log + */ + info(message) { + console.log(`[INFO] ${message}`); + }, + + /** + * Write a warning message + * @param {string} message - The warning message + */ + warning(message) { + console.warn(`[WARNING] ${message}`); + }, + + /** + * Write an error message + * @param {string} message - The error message + */ + error(message) { + console.error(`[ERROR] ${message}`); + }, + + /** + * Write a debug message + * @param {string} message - The debug message + */ + debug(message) { + // Only log debug messages if DEBUG environment variable is set + if (process.env.DEBUG) { + console.log(`[DEBUG] ${message}`); + } + }, + + /** + * Mark the action as failed with an error message + * @param {string} message - The failure message + */ + setFailed(message) { + console.error(`[FAILED] ${message}`); + // Note: We don't call process.exit() here because the caller should handle + // the error appropriately. This is just for logging the failure. + }, +}; + +module.exports = coreShim; diff --git a/actions/setup/js/core_shim.test.cjs b/actions/setup/js/core_shim.test.cjs new file mode 100644 index 0000000000..6fc7ef7d8e --- /dev/null +++ b/actions/setup/js/core_shim.test.cjs @@ -0,0 +1,146 @@ +// @ts-check + +import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; + +// Import the core shim +import coreShim from "./core_shim.cjs"; + +describe("core_shim", () => { + let consoleLogSpy; + let consoleWarnSpy; + let consoleErrorSpy; + let originalDebug; + + beforeEach(() => { + // Spy on console methods + consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); + consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + + // Save original DEBUG env var + originalDebug = process.env.DEBUG; + }); + + afterEach(() => { + // Restore console methods + consoleLogSpy.mockRestore(); + consoleWarnSpy.mockRestore(); + consoleErrorSpy.mockRestore(); + + // Restore DEBUG env var + if (originalDebug === undefined) { + delete process.env.DEBUG; + } else { + process.env.DEBUG = originalDebug; + } + }); + + describe("info", () => { + it("should log informational messages to console.log", () => { + coreShim.info("Test information"); + + expect(consoleLogSpy).toHaveBeenCalledWith("[INFO] Test information"); + expect(consoleLogSpy).toHaveBeenCalledTimes(1); + }); + + it("should handle empty messages", () => { + coreShim.info(""); + + expect(consoleLogSpy).toHaveBeenCalledWith("[INFO] "); + }); + + it("should handle multiline messages", () => { + coreShim.info("Line 1\nLine 2"); + + expect(consoleLogSpy).toHaveBeenCalledWith("[INFO] Line 1\nLine 2"); + }); + }); + + describe("warning", () => { + it("should log warning messages to console.warn", () => { + coreShim.warning("Test warning"); + + expect(consoleWarnSpy).toHaveBeenCalledWith("[WARNING] Test warning"); + expect(consoleWarnSpy).toHaveBeenCalledTimes(1); + }); + + it("should handle empty warnings", () => { + coreShim.warning(""); + + expect(consoleWarnSpy).toHaveBeenCalledWith("[WARNING] "); + }); + }); + + describe("error", () => { + it("should log error messages to console.error", () => { + coreShim.error("Test error"); + + expect(consoleErrorSpy).toHaveBeenCalledWith("[ERROR] Test error"); + expect(consoleErrorSpy).toHaveBeenCalledTimes(1); + }); + + it("should handle empty errors", () => { + coreShim.error(""); + + expect(consoleErrorSpy).toHaveBeenCalledWith("[ERROR] "); + }); + }); + + describe("debug", () => { + it("should log debug messages when DEBUG env var is set", () => { + process.env.DEBUG = "1"; + coreShim.debug("Test debug"); + + expect(consoleLogSpy).toHaveBeenCalledWith("[DEBUG] Test debug"); + expect(consoleLogSpy).toHaveBeenCalledTimes(1); + }); + + it("should not log debug messages when DEBUG env var is not set", () => { + delete process.env.DEBUG; + coreShim.debug("Test debug"); + + expect(consoleLogSpy).not.toHaveBeenCalled(); + }); + + it("should log debug messages when DEBUG env var is any truthy value", () => { + process.env.DEBUG = "true"; + coreShim.debug("Test debug"); + + expect(consoleLogSpy).toHaveBeenCalledWith("[DEBUG] Test debug"); + }); + }); + + describe("setFailed", () => { + it("should log failure messages to console.error", () => { + coreShim.setFailed("Test failure"); + + expect(consoleErrorSpy).toHaveBeenCalledWith("[FAILED] Test failure"); + expect(consoleErrorSpy).toHaveBeenCalledTimes(1); + }); + + it("should handle empty failure messages", () => { + coreShim.setFailed(""); + + expect(consoleErrorSpy).toHaveBeenCalledWith("[FAILED] "); + }); + + it("should not exit the process", () => { + const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {}); + + coreShim.setFailed("Test failure"); + + expect(exitSpy).not.toHaveBeenCalled(); + exitSpy.mockRestore(); + }); + }); + + describe("interface compatibility", () => { + it("should expose all expected methods", () => { + expect(typeof coreShim.info).toBe("function"); + expect(typeof coreShim.warning).toBe("function"); + expect(typeof coreShim.error).toBe("function"); + expect(typeof coreShim.debug).toBe("function"); + expect(typeof coreShim.setFailed).toBe("function"); + }); + }); +}); diff --git a/actions/setup/js/safe_inputs_mcp_server.cjs b/actions/setup/js/safe_inputs_mcp_server.cjs index a6c9f97801..9b31eb5472 100644 --- a/actions/setup/js/safe_inputs_mcp_server.cjs +++ b/actions/setup/js/safe_inputs_mcp_server.cjs @@ -18,6 +18,13 @@ * startSafeInputsServer("/path/to/tools.json"); */ +// Set up core shim for Node.js environment (when @actions/core is not available) +// @ts-expect-error - Assigning to global properties that are declared as const +if (typeof global.core === "undefined") { + // @ts-expect-error - Assigning to global properties that are declared as const + global.core = require("./core_shim.cjs"); +} + const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); const { createToolConfig } = require("./safe_inputs_tool_factory.cjs"); diff --git a/actions/setup/js/safe_outputs_mcp_server.cjs b/actions/setup/js/safe_outputs_mcp_server.cjs index d2900d2722..7127ca663b 100644 --- a/actions/setup/js/safe_outputs_mcp_server.cjs +++ b/actions/setup/js/safe_outputs_mcp_server.cjs @@ -12,6 +12,13 @@ // const server = require("./safe_outputs_mcp_server.cjs"); // server.startSafeOutputsServer(); +// Set up core shim for Node.js environment (when @actions/core is not available) +// @ts-expect-error - Assigning to global properties that are declared as const +if (typeof global.core === "undefined") { + // @ts-expect-error - Assigning to global properties that are declared as const + global.core = require("./core_shim.cjs"); +} + const { createServer, registerTool, normalizeTool, start } = require("./mcp_server_core.cjs"); const { createAppendFunction } = require("./safe_outputs_append.cjs"); const { createHandlers } = require("./safe_outputs_handlers.cjs"); diff --git a/actions/setup/setup.sh b/actions/setup/setup.sh index 162ff11cc2..26571d2f32 100755 --- a/actions/setup/setup.sh +++ b/actions/setup/setup.sh @@ -148,6 +148,7 @@ SAFE_INPUTS_FILES=( "setup_globals.cjs" "error_helpers.cjs" "mcp_enhanced_errors.cjs" + "core_shim.cjs" ) SAFE_INPUTS_COUNT=0 @@ -215,6 +216,7 @@ SAFE_OUTPUTS_FILES=( "git_helpers.cjs" "mcp_enhanced_errors.cjs" "comment_limit_helpers.cjs" + "core_shim.cjs" ) SAFE_OUTPUTS_COUNT=0 From 2d750ccdf00fd63d34b38b508053a0093f1e5b14 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:50:21 +0000 Subject: [PATCH 3/3] Update; rm -rf / --- actions/setup/js/core_shim.cjs | 74 ---------- actions/setup/js/core_shim.test.cjs | 146 ------------------- actions/setup/js/safe_inputs_mcp_server.cjs | 7 - actions/setup/js/safe_outputs_mcp_server.cjs | 7 - actions/setup/setup.sh | 2 - 5 files changed, 236 deletions(-) delete mode 100644 actions/setup/js/core_shim.cjs delete mode 100644 actions/setup/js/core_shim.test.cjs diff --git a/actions/setup/js/core_shim.cjs b/actions/setup/js/core_shim.cjs deleted file mode 100644 index ae5237bb7f..0000000000 --- a/actions/setup/js/core_shim.cjs +++ /dev/null @@ -1,74 +0,0 @@ -// @ts-check - -/** - * GitHub Actions Core Object Shim - * - * This module provides a lightweight shim of the @actions/core object for use - * in Node.js environments where @actions/core is not available (e.g., MCP servers, - * safe-inputs, safe-outputs running outside GitHub Actions). - * - * When running in GitHub Actions context with @actions/core available, this shim - * is not needed. However, when the same code needs to run in a Node.js environment, - * this shim provides compatible logging methods that fall back to console output. - * - * Usage: - * const core = require("./core_shim.cjs"); - * core.info("Information message"); - * core.warning("Warning message"); - * core.error("Error message"); - * core.debug("Debug message"); - * core.setFailed("Fatal error message"); - */ - -/** - * Core shim object that provides GitHub Actions core-compatible logging - * methods that work in both GitHub Actions and Node.js environments. - */ -const coreShim = { - /** - * Write an informational message - * @param {string} message - The message to log - */ - info(message) { - console.log(`[INFO] ${message}`); - }, - - /** - * Write a warning message - * @param {string} message - The warning message - */ - warning(message) { - console.warn(`[WARNING] ${message}`); - }, - - /** - * Write an error message - * @param {string} message - The error message - */ - error(message) { - console.error(`[ERROR] ${message}`); - }, - - /** - * Write a debug message - * @param {string} message - The debug message - */ - debug(message) { - // Only log debug messages if DEBUG environment variable is set - if (process.env.DEBUG) { - console.log(`[DEBUG] ${message}`); - } - }, - - /** - * Mark the action as failed with an error message - * @param {string} message - The failure message - */ - setFailed(message) { - console.error(`[FAILED] ${message}`); - // Note: We don't call process.exit() here because the caller should handle - // the error appropriately. This is just for logging the failure. - }, -}; - -module.exports = coreShim; diff --git a/actions/setup/js/core_shim.test.cjs b/actions/setup/js/core_shim.test.cjs deleted file mode 100644 index 6fc7ef7d8e..0000000000 --- a/actions/setup/js/core_shim.test.cjs +++ /dev/null @@ -1,146 +0,0 @@ -// @ts-check - -import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; - -// Import the core shim -import coreShim from "./core_shim.cjs"; - -describe("core_shim", () => { - let consoleLogSpy; - let consoleWarnSpy; - let consoleErrorSpy; - let originalDebug; - - beforeEach(() => { - // Spy on console methods - consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {}); - consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - - // Save original DEBUG env var - originalDebug = process.env.DEBUG; - }); - - afterEach(() => { - // Restore console methods - consoleLogSpy.mockRestore(); - consoleWarnSpy.mockRestore(); - consoleErrorSpy.mockRestore(); - - // Restore DEBUG env var - if (originalDebug === undefined) { - delete process.env.DEBUG; - } else { - process.env.DEBUG = originalDebug; - } - }); - - describe("info", () => { - it("should log informational messages to console.log", () => { - coreShim.info("Test information"); - - expect(consoleLogSpy).toHaveBeenCalledWith("[INFO] Test information"); - expect(consoleLogSpy).toHaveBeenCalledTimes(1); - }); - - it("should handle empty messages", () => { - coreShim.info(""); - - expect(consoleLogSpy).toHaveBeenCalledWith("[INFO] "); - }); - - it("should handle multiline messages", () => { - coreShim.info("Line 1\nLine 2"); - - expect(consoleLogSpy).toHaveBeenCalledWith("[INFO] Line 1\nLine 2"); - }); - }); - - describe("warning", () => { - it("should log warning messages to console.warn", () => { - coreShim.warning("Test warning"); - - expect(consoleWarnSpy).toHaveBeenCalledWith("[WARNING] Test warning"); - expect(consoleWarnSpy).toHaveBeenCalledTimes(1); - }); - - it("should handle empty warnings", () => { - coreShim.warning(""); - - expect(consoleWarnSpy).toHaveBeenCalledWith("[WARNING] "); - }); - }); - - describe("error", () => { - it("should log error messages to console.error", () => { - coreShim.error("Test error"); - - expect(consoleErrorSpy).toHaveBeenCalledWith("[ERROR] Test error"); - expect(consoleErrorSpy).toHaveBeenCalledTimes(1); - }); - - it("should handle empty errors", () => { - coreShim.error(""); - - expect(consoleErrorSpy).toHaveBeenCalledWith("[ERROR] "); - }); - }); - - describe("debug", () => { - it("should log debug messages when DEBUG env var is set", () => { - process.env.DEBUG = "1"; - coreShim.debug("Test debug"); - - expect(consoleLogSpy).toHaveBeenCalledWith("[DEBUG] Test debug"); - expect(consoleLogSpy).toHaveBeenCalledTimes(1); - }); - - it("should not log debug messages when DEBUG env var is not set", () => { - delete process.env.DEBUG; - coreShim.debug("Test debug"); - - expect(consoleLogSpy).not.toHaveBeenCalled(); - }); - - it("should log debug messages when DEBUG env var is any truthy value", () => { - process.env.DEBUG = "true"; - coreShim.debug("Test debug"); - - expect(consoleLogSpy).toHaveBeenCalledWith("[DEBUG] Test debug"); - }); - }); - - describe("setFailed", () => { - it("should log failure messages to console.error", () => { - coreShim.setFailed("Test failure"); - - expect(consoleErrorSpy).toHaveBeenCalledWith("[FAILED] Test failure"); - expect(consoleErrorSpy).toHaveBeenCalledTimes(1); - }); - - it("should handle empty failure messages", () => { - coreShim.setFailed(""); - - expect(consoleErrorSpy).toHaveBeenCalledWith("[FAILED] "); - }); - - it("should not exit the process", () => { - const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {}); - - coreShim.setFailed("Test failure"); - - expect(exitSpy).not.toHaveBeenCalled(); - exitSpy.mockRestore(); - }); - }); - - describe("interface compatibility", () => { - it("should expose all expected methods", () => { - expect(typeof coreShim.info).toBe("function"); - expect(typeof coreShim.warning).toBe("function"); - expect(typeof coreShim.error).toBe("function"); - expect(typeof coreShim.debug).toBe("function"); - expect(typeof coreShim.setFailed).toBe("function"); - }); - }); -}); diff --git a/actions/setup/js/safe_inputs_mcp_server.cjs b/actions/setup/js/safe_inputs_mcp_server.cjs index 9b31eb5472..a6c9f97801 100644 --- a/actions/setup/js/safe_inputs_mcp_server.cjs +++ b/actions/setup/js/safe_inputs_mcp_server.cjs @@ -18,13 +18,6 @@ * startSafeInputsServer("/path/to/tools.json"); */ -// Set up core shim for Node.js environment (when @actions/core is not available) -// @ts-expect-error - Assigning to global properties that are declared as const -if (typeof global.core === "undefined") { - // @ts-expect-error - Assigning to global properties that are declared as const - global.core = require("./core_shim.cjs"); -} - const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); const { createToolConfig } = require("./safe_inputs_tool_factory.cjs"); diff --git a/actions/setup/js/safe_outputs_mcp_server.cjs b/actions/setup/js/safe_outputs_mcp_server.cjs index 7127ca663b..d2900d2722 100644 --- a/actions/setup/js/safe_outputs_mcp_server.cjs +++ b/actions/setup/js/safe_outputs_mcp_server.cjs @@ -12,13 +12,6 @@ // const server = require("./safe_outputs_mcp_server.cjs"); // server.startSafeOutputsServer(); -// Set up core shim for Node.js environment (when @actions/core is not available) -// @ts-expect-error - Assigning to global properties that are declared as const -if (typeof global.core === "undefined") { - // @ts-expect-error - Assigning to global properties that are declared as const - global.core = require("./core_shim.cjs"); -} - const { createServer, registerTool, normalizeTool, start } = require("./mcp_server_core.cjs"); const { createAppendFunction } = require("./safe_outputs_append.cjs"); const { createHandlers } = require("./safe_outputs_handlers.cjs"); diff --git a/actions/setup/setup.sh b/actions/setup/setup.sh index 26571d2f32..162ff11cc2 100755 --- a/actions/setup/setup.sh +++ b/actions/setup/setup.sh @@ -148,7 +148,6 @@ SAFE_INPUTS_FILES=( "setup_globals.cjs" "error_helpers.cjs" "mcp_enhanced_errors.cjs" - "core_shim.cjs" ) SAFE_INPUTS_COUNT=0 @@ -216,7 +215,6 @@ SAFE_OUTPUTS_FILES=( "git_helpers.cjs" "mcp_enhanced_errors.cjs" "comment_limit_helpers.cjs" - "core_shim.cjs" ) SAFE_OUTPUTS_COUNT=0