From 16450d284943c7f359ff5877743a0aaaa9fb6e5b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:07:23 +0000 Subject: [PATCH 1/4] Initial plan From 4fc844293d049af8ef7eae855b5466ceecdbad48 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:15:03 +0000 Subject: [PATCH 2/4] Add support for ignoring safe-outputs.jobs messages in handler managers Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../safe_output_project_handler_manager.cjs | 35 +++++++++++++ .../safe_output_unified_handler_manager.cjs | 43 +++++++++++++++- ...fe_output_unified_handler_manager.test.cjs | 51 ++++++++++++++++++- 3 files changed, 127 insertions(+), 2 deletions(-) diff --git a/actions/setup/js/safe_output_project_handler_manager.cjs b/actions/setup/js/safe_output_project_handler_manager.cjs index 8e94e15b59..30a748d4db 100644 --- a/actions/setup/js/safe_output_project_handler_manager.cjs +++ b/actions/setup/js/safe_output_project_handler_manager.cjs @@ -18,6 +18,30 @@ const { getErrorMessage } = require("./error_helpers.cjs"); const { writeSafeOutputSummaries } = require("./safe_output_summary.cjs"); const { loadTemporaryIdMap } = require("./temporary_id.cjs"); +/** + * Load custom safe output job types from environment variable + * These are job names defined in safe-outputs.jobs that are processed by custom jobs + * @returns {Set} Set of custom safe output job type names + */ +function loadCustomSafeOutputJobTypes() { + const safeOutputJobsEnv = process.env.GH_AW_SAFE_OUTPUT_JOBS; + if (!safeOutputJobsEnv) { + return new Set(); + } + + try { + const safeOutputJobs = JSON.parse(safeOutputJobsEnv); + // The environment variable is a map of job names to output keys + // We need the job names (keys) as the message types to ignore + const jobTypes = Object.keys(safeOutputJobs); + core.debug(`Loaded ${jobTypes.length} custom safe output job type(s): ${jobTypes.join(", ")}`); + return new Set(jobTypes); + } catch (error) { + core.warning(`Failed to parse GH_AW_SAFE_OUTPUT_JOBS: ${getErrorMessage(error)}`); + return new Set(); + } +} + /** * Handler map configuration for project-related safe outputs * Maps safe output types to their handler module file paths @@ -122,6 +146,9 @@ async function processMessages(messageHandlers, messages) { core.info(`Loaded temporary ID map with ${temporaryIdMap.size} entry(ies)`); } + // Load custom safe output job types that are processed by dedicated custom jobs + const customSafeOutputJobTypes = loadCustomSafeOutputJobTypes(); + core.info(`Processing ${messages.length} project-related message(s)...`); // Process messages in order of appearance @@ -137,6 +164,13 @@ async function processMessages(messageHandlers, messages) { const messageHandler = messageHandlers.get(messageType); if (!messageHandler) { + // Check if this message type is a custom safe output job + if (customSafeOutputJobTypes.has(messageType)) { + // Silently skip - this is handled by a custom safe output job + core.debug(`Message ${i + 1} (${messageType}) will be handled by custom safe output job`); + continue; + } + // Skip messages that are not project-related // These should be handled by other steps (main handler manager or standalone steps) core.debug(`Message ${i + 1} (${messageType}) is not a project-related type - skipping`); @@ -271,6 +305,7 @@ module.exports = { loadHandlers, processMessages, main, + loadCustomSafeOutputJobTypes, }; // Run main if this script is executed directly (not required as a module) diff --git a/actions/setup/js/safe_output_unified_handler_manager.cjs b/actions/setup/js/safe_output_unified_handler_manager.cjs index 2b6327158e..91467b7c63 100644 --- a/actions/setup/js/safe_output_unified_handler_manager.cjs +++ b/actions/setup/js/safe_output_unified_handler_manager.cjs @@ -143,6 +143,30 @@ const PROJECT_HANDLER_MAP = { */ const STANDALONE_STEP_TYPES = new Set(["assign_to_agent", "create_agent_session", "upload_asset", "noop"]); +/** + * Load custom safe output job types from environment variable + * These are job names defined in safe-outputs.jobs that are processed by custom jobs + * @returns {Set} Set of custom safe output job type names + */ +function loadCustomSafeOutputJobTypes() { + const safeOutputJobsEnv = process.env.GH_AW_SAFE_OUTPUT_JOBS; + if (!safeOutputJobsEnv) { + return new Set(); + } + + try { + const safeOutputJobs = JSON.parse(safeOutputJobsEnv); + // The environment variable is a map of job names to output keys + // We need the job names (keys) as the message types to ignore + const jobTypes = Object.keys(safeOutputJobs); + core.debug(`Loaded ${jobTypes.length} custom safe output job type(s): ${jobTypes.join(", ")}`); + return new Set(jobTypes); + } catch (error) { + core.warning(`Failed to parse GH_AW_SAFE_OUTPUT_JOBS: ${getErrorMessage(error)}`); + return new Set(); + } +} + /** * Project-related message types that are handled by project handlers * Used to provide more specific handling @@ -363,6 +387,9 @@ async function processMessages(messageHandlers, messages, projectOctokit = null) // Collect missing_tool and missing_data messages first const missings = collectMissingMessages(messages); + // Load custom safe output job types that are processed by dedicated custom jobs + const customSafeOutputJobTypes = loadCustomSafeOutputJobTypes(); + // Initialize unified temporary ID map // This will be populated by handlers as they create entities with temporary IDs // Stores both issue/PR references ({repo, number}) and project URLs ({projectUrl}) @@ -418,6 +445,20 @@ async function processMessages(messageHandlers, messages, projectOctokit = null) continue; } + // Check if this message type is a custom safe output job + if (customSafeOutputJobTypes.has(messageType)) { + // Silently skip - this is handled by a custom safe output job + core.debug(`Message ${i + 1} (${messageType}) will be handled by custom safe output job`); + results.push({ + type: messageType, + messageIndex: i, + success: false, + skipped: true, + reason: "Handled by custom safe output job", + }); + continue; + } + // Unknown message type - warn the user core.warning( `⚠️ No handler loaded for message type '${messageType}' (message ${i + 1}/${messages.length}). The message will be skipped. This may happen if the safe output type is not configured in the workflow's safe-outputs section.` @@ -1026,7 +1067,7 @@ async function main() { } } -module.exports = { main, loadConfig, loadHandlers, processMessages, setupProjectGitHubClient }; +module.exports = { main, loadConfig, loadHandlers, processMessages, setupProjectGitHubClient, loadCustomSafeOutputJobTypes }; // Run main if this script is executed directly (not required as a module) if (require.main === module) { diff --git a/actions/setup/js/safe_output_unified_handler_manager.test.cjs b/actions/setup/js/safe_output_unified_handler_manager.test.cjs index 28f05a0a0e..355e19d77c 100644 --- a/actions/setup/js/safe_output_unified_handler_manager.test.cjs +++ b/actions/setup/js/safe_output_unified_handler_manager.test.cjs @@ -1,7 +1,7 @@ // @ts-check import { describe, it, expect, beforeEach, vi } from "vitest"; -import { loadConfig, setupProjectGitHubClient } from "./safe_output_unified_handler_manager.cjs"; +import { loadConfig, setupProjectGitHubClient, loadCustomSafeOutputJobTypes } from "./safe_output_unified_handler_manager.cjs"; // Mock @actions/github vi.mock("@actions/github", () => ({ @@ -114,4 +114,53 @@ describe("Unified Safe Output Handler Manager", () => { expect(octokit).toHaveProperty("request"); }); }); + + describe("loadCustomSafeOutputJobTypes", () => { + beforeEach(() => { + // Clean up environment variables + delete process.env.GH_AW_SAFE_OUTPUT_JOBS; + }); + + it("should return empty set when GH_AW_SAFE_OUTPUT_JOBS is not set", () => { + const result = loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(0); + }); + + it("should parse and return custom job types from GH_AW_SAFE_OUTPUT_JOBS", () => { + process.env.GH_AW_SAFE_OUTPUT_JOBS = JSON.stringify({ + notion_add_comment: "comment_url", + slack_post_message: "message_url", + custom_job: "output_url", + }); + + const result = loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(3); + expect(result.has("notion_add_comment")).toBe(true); + expect(result.has("slack_post_message")).toBe(true); + expect(result.has("custom_job")).toBe(true); + }); + + it("should return empty set and warn when GH_AW_SAFE_OUTPUT_JOBS is invalid JSON", () => { + process.env.GH_AW_SAFE_OUTPUT_JOBS = "invalid json"; + + const result = loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(0); + expect(global.core.warning).toHaveBeenCalledWith(expect.stringContaining("Failed to parse GH_AW_SAFE_OUTPUT_JOBS")); + }); + + it("should handle empty object in GH_AW_SAFE_OUTPUT_JOBS", () => { + process.env.GH_AW_SAFE_OUTPUT_JOBS = JSON.stringify({}); + + const result = loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(0); + }); + }); }); From 89cb35ca117e77536c2492918b5dd00a6365288c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:22:12 +0000 Subject: [PATCH 3/4] Complete implementation for handling safe-outputs.jobs messages Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- docs/src/content/docs/agent-factory-status.mdx | 8 -------- .../src/content/docs/reference/frontmatter-full.md | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/src/content/docs/agent-factory-status.mdx b/docs/src/content/docs/agent-factory-status.mdx index 8ba7e7f401..68afe5f09e 100644 --- a/docs/src/content/docs/agent-factory-status.mdx +++ b/docs/src/content/docs/agent-factory-status.mdx @@ -82,15 +82,7 @@ These are experimental agentic workflows used by the GitHub Next team to learn, | [Example: Custom Error Patterns](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/example-custom-error-patterns.md) | copilot | [![Example: Custom Error Patterns](https://github.com/githubnext/gh-aw/actions/workflows/example-custom-error-patterns.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/example-custom-error-patterns.lock.yml) | - | - | | [Example: Properly Provisioned Permissions](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/example-permissions-warning.md) | copilot | [![Example: Properly Provisioned Permissions](https://github.com/githubnext/gh-aw/actions/workflows/example-permissions-warning.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/example-permissions-warning.lock.yml) | - | - | | [Firewall Test Agent](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/firewall.md) | copilot | [![Firewall Test Agent](https://github.com/githubnext/gh-aw/actions/workflows/firewall.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/firewall.lock.yml) | - | - | -<<<<<<< HEAD | [Functional Pragmatist](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/functional-pragmatist.md) | copilot | [![Functional Pragmatist](https://github.com/githubnext/gh-aw/actions/workflows/functional-pragmatist.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/functional-pragmatist.lock.yml) | `0 9 * * 2,4` | - | -======= -<<<<<<< HEAD -| [Functional Enhancer](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/functional-enhancer.md) | claude | [![Functional Enhancer](https://github.com/githubnext/gh-aw/actions/workflows/functional-enhancer.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/functional-enhancer.lock.yml) | `0 9 * * 2,4` | - | -======= -| [Functional Pragmatist](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/functional-programming-enhancer.md) | claude | [![Functional Pragmatist](https://github.com/githubnext/gh-aw/actions/workflows/functional-programming-enhancer.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/functional-programming-enhancer.lock.yml) | `0 9 * * 2,4` | - | ->>>>>>> ba904f257b69bfcc9738b01ca4c61995b23506a4 ->>>>>>> origin/main | [GitHub MCP Remote Server Tools Report Generator](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/github-mcp-tools-report.md) | claude | [![GitHub MCP Remote Server Tools Report Generator](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-tools-report.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-tools-report.lock.yml) | - | - | | [GitHub MCP Structural Analysis](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/github-mcp-structural-analysis.md) | claude | [![GitHub MCP Structural Analysis](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-structural-analysis.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/github-mcp-structural-analysis.lock.yml) | `0 11 * * 1-5` | - | | [GitHub Remote MCP Authentication Test](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/github-remote-mcp-auth-test.md) | copilot | [![GitHub Remote MCP Authentication Test](https://github.com/githubnext/gh-aw/actions/workflows/github-remote-mcp-auth-test.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/github-remote-mcp-auth-test.lock.yml) | - | - | diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index 74d3fcaca7..a9163ca45e 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -2157,6 +2157,13 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # Default project URL for update-project operations. When specified, safe output + # messages can omit the project field and will use this URL by default. Must be a + # valid GitHub Projects v2 URL. Overridden by explicit project field in safe + # output messages. + # (optional) + project: "example-value" + # Optional array of project views to create. Each view must have a name and # layout. Views are created during project setup. # (optional) @@ -2349,6 +2356,13 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # Default project URL for status update operations. When specified, safe output + # messages can omit the project field and will use this URL by default. Must be a + # valid GitHub Projects v2 URL. Overridden by explicit project field in safe + # output messages. + # (optional) + project: "example-value" + # Option 2: Enable project status updates with default configuration (max=1) create-project-status-update: null From 59ec8b2a1f4c76f3d2843413da68e7f6f227c66f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:41:46 +0000 Subject: [PATCH 4/4] Refactor: Move loadCustomSafeOutputJobTypes to safe_output_helpers Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/safe_output_helpers.cjs | 30 +++++++++++ actions/setup/js/safe_output_helpers.test.cjs | 49 ++++++++++++++++++ .../safe_output_project_handler_manager.cjs | 26 +--------- .../safe_output_unified_handler_manager.cjs | 27 +--------- ...fe_output_unified_handler_manager.test.cjs | 51 +------------------ 5 files changed, 83 insertions(+), 100 deletions(-) diff --git a/actions/setup/js/safe_output_helpers.cjs b/actions/setup/js/safe_output_helpers.cjs index dbd1f98d9c..2a925df020 100644 --- a/actions/setup/js/safe_output_helpers.cjs +++ b/actions/setup/js/safe_output_helpers.cjs @@ -228,8 +228,38 @@ function resolveTarget(params) { }; } +/** + * Load custom safe output job types from environment variable + * These are job names defined in safe-outputs.jobs that are processed by custom jobs + * @returns {Set} Set of custom safe output job type names + */ +function loadCustomSafeOutputJobTypes() { + const safeOutputJobsEnv = process.env.GH_AW_SAFE_OUTPUT_JOBS; + if (!safeOutputJobsEnv) { + return new Set(); + } + + try { + const safeOutputJobs = JSON.parse(safeOutputJobsEnv); + // The environment variable is a map of job names to output keys + // We need the job names (keys) as the message types to ignore + const jobTypes = Object.keys(safeOutputJobs); + if (typeof core !== "undefined") { + core.debug(`Loaded ${jobTypes.length} custom safe output job type(s): ${jobTypes.join(", ")}`); + } + return new Set(jobTypes); + } catch (error) { + if (typeof core !== "undefined") { + const { getErrorMessage } = require("./error_helpers.cjs"); + core.warning(`Failed to parse GH_AW_SAFE_OUTPUT_JOBS: ${getErrorMessage(error)}`); + } + return new Set(); + } +} + module.exports = { parseAllowedItems, parseMaxCount, resolveTarget, + loadCustomSafeOutputJobTypes, }; diff --git a/actions/setup/js/safe_output_helpers.test.cjs b/actions/setup/js/safe_output_helpers.test.cjs index 1789eefa29..da078938ce 100644 --- a/actions/setup/js/safe_output_helpers.test.cjs +++ b/actions/setup/js/safe_output_helpers.test.cjs @@ -453,4 +453,53 @@ describe("safe_output_helpers", () => { }); }); }); + + describe("loadCustomSafeOutputJobTypes", () => { + beforeEach(() => { + // Clean up environment variables + delete process.env.GH_AW_SAFE_OUTPUT_JOBS; + }); + + it("should return empty set when GH_AW_SAFE_OUTPUT_JOBS is not set", () => { + const result = helpers.loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(0); + }); + + it("should parse and return custom job types from GH_AW_SAFE_OUTPUT_JOBS", () => { + process.env.GH_AW_SAFE_OUTPUT_JOBS = JSON.stringify({ + notion_add_comment: "comment_url", + slack_post_message: "message_url", + custom_job: "output_url", + }); + + const result = helpers.loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(3); + expect(result.has("notion_add_comment")).toBe(true); + expect(result.has("slack_post_message")).toBe(true); + expect(result.has("custom_job")).toBe(true); + }); + + it("should return empty set when GH_AW_SAFE_OUTPUT_JOBS is invalid JSON", () => { + process.env.GH_AW_SAFE_OUTPUT_JOBS = "invalid json"; + + const result = helpers.loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(0); + // Note: Warning is logged but we don't test for it since core is not mocked in this test file + }); + + it("should handle empty object in GH_AW_SAFE_OUTPUT_JOBS", () => { + process.env.GH_AW_SAFE_OUTPUT_JOBS = JSON.stringify({}); + + const result = helpers.loadCustomSafeOutputJobTypes(); + + expect(result).toBeInstanceOf(Set); + expect(result.size).toBe(0); + }); + }); }); diff --git a/actions/setup/js/safe_output_project_handler_manager.cjs b/actions/setup/js/safe_output_project_handler_manager.cjs index 30a748d4db..32a0fcc140 100644 --- a/actions/setup/js/safe_output_project_handler_manager.cjs +++ b/actions/setup/js/safe_output_project_handler_manager.cjs @@ -17,30 +17,7 @@ const { loadAgentOutput } = require("./load_agent_output.cjs"); const { getErrorMessage } = require("./error_helpers.cjs"); const { writeSafeOutputSummaries } = require("./safe_output_summary.cjs"); const { loadTemporaryIdMap } = require("./temporary_id.cjs"); - -/** - * Load custom safe output job types from environment variable - * These are job names defined in safe-outputs.jobs that are processed by custom jobs - * @returns {Set} Set of custom safe output job type names - */ -function loadCustomSafeOutputJobTypes() { - const safeOutputJobsEnv = process.env.GH_AW_SAFE_OUTPUT_JOBS; - if (!safeOutputJobsEnv) { - return new Set(); - } - - try { - const safeOutputJobs = JSON.parse(safeOutputJobsEnv); - // The environment variable is a map of job names to output keys - // We need the job names (keys) as the message types to ignore - const jobTypes = Object.keys(safeOutputJobs); - core.debug(`Loaded ${jobTypes.length} custom safe output job type(s): ${jobTypes.join(", ")}`); - return new Set(jobTypes); - } catch (error) { - core.warning(`Failed to parse GH_AW_SAFE_OUTPUT_JOBS: ${getErrorMessage(error)}`); - return new Set(); - } -} +const { loadCustomSafeOutputJobTypes } = require("./safe_output_helpers.cjs"); /** * Handler map configuration for project-related safe outputs @@ -305,7 +282,6 @@ module.exports = { loadHandlers, processMessages, main, - loadCustomSafeOutputJobTypes, }; // Run main if this script is executed directly (not required as a module) diff --git a/actions/setup/js/safe_output_unified_handler_manager.cjs b/actions/setup/js/safe_output_unified_handler_manager.cjs index 91467b7c63..aa1a1c87c2 100644 --- a/actions/setup/js/safe_output_unified_handler_manager.cjs +++ b/actions/setup/js/safe_output_unified_handler_manager.cjs @@ -22,6 +22,7 @@ const { setCollectedMissings } = require("./missing_messages_helper.cjs"); const { writeSafeOutputSummaries } = require("./safe_output_summary.cjs"); const { getIssuesToAssignCopilot } = require("./create_issue.cjs"); const { getCampaignLabelsFromEnv } = require("./campaign_labels.cjs"); +const { loadCustomSafeOutputJobTypes } = require("./safe_output_helpers.cjs"); /** * Merge labels with trimming + case-insensitive de-duplication. @@ -143,30 +144,6 @@ const PROJECT_HANDLER_MAP = { */ const STANDALONE_STEP_TYPES = new Set(["assign_to_agent", "create_agent_session", "upload_asset", "noop"]); -/** - * Load custom safe output job types from environment variable - * These are job names defined in safe-outputs.jobs that are processed by custom jobs - * @returns {Set} Set of custom safe output job type names - */ -function loadCustomSafeOutputJobTypes() { - const safeOutputJobsEnv = process.env.GH_AW_SAFE_OUTPUT_JOBS; - if (!safeOutputJobsEnv) { - return new Set(); - } - - try { - const safeOutputJobs = JSON.parse(safeOutputJobsEnv); - // The environment variable is a map of job names to output keys - // We need the job names (keys) as the message types to ignore - const jobTypes = Object.keys(safeOutputJobs); - core.debug(`Loaded ${jobTypes.length} custom safe output job type(s): ${jobTypes.join(", ")}`); - return new Set(jobTypes); - } catch (error) { - core.warning(`Failed to parse GH_AW_SAFE_OUTPUT_JOBS: ${getErrorMessage(error)}`); - return new Set(); - } -} - /** * Project-related message types that are handled by project handlers * Used to provide more specific handling @@ -1067,7 +1044,7 @@ async function main() { } } -module.exports = { main, loadConfig, loadHandlers, processMessages, setupProjectGitHubClient, loadCustomSafeOutputJobTypes }; +module.exports = { main, loadConfig, loadHandlers, processMessages, setupProjectGitHubClient }; // Run main if this script is executed directly (not required as a module) if (require.main === module) { diff --git a/actions/setup/js/safe_output_unified_handler_manager.test.cjs b/actions/setup/js/safe_output_unified_handler_manager.test.cjs index 355e19d77c..28f05a0a0e 100644 --- a/actions/setup/js/safe_output_unified_handler_manager.test.cjs +++ b/actions/setup/js/safe_output_unified_handler_manager.test.cjs @@ -1,7 +1,7 @@ // @ts-check import { describe, it, expect, beforeEach, vi } from "vitest"; -import { loadConfig, setupProjectGitHubClient, loadCustomSafeOutputJobTypes } from "./safe_output_unified_handler_manager.cjs"; +import { loadConfig, setupProjectGitHubClient } from "./safe_output_unified_handler_manager.cjs"; // Mock @actions/github vi.mock("@actions/github", () => ({ @@ -114,53 +114,4 @@ describe("Unified Safe Output Handler Manager", () => { expect(octokit).toHaveProperty("request"); }); }); - - describe("loadCustomSafeOutputJobTypes", () => { - beforeEach(() => { - // Clean up environment variables - delete process.env.GH_AW_SAFE_OUTPUT_JOBS; - }); - - it("should return empty set when GH_AW_SAFE_OUTPUT_JOBS is not set", () => { - const result = loadCustomSafeOutputJobTypes(); - - expect(result).toBeInstanceOf(Set); - expect(result.size).toBe(0); - }); - - it("should parse and return custom job types from GH_AW_SAFE_OUTPUT_JOBS", () => { - process.env.GH_AW_SAFE_OUTPUT_JOBS = JSON.stringify({ - notion_add_comment: "comment_url", - slack_post_message: "message_url", - custom_job: "output_url", - }); - - const result = loadCustomSafeOutputJobTypes(); - - expect(result).toBeInstanceOf(Set); - expect(result.size).toBe(3); - expect(result.has("notion_add_comment")).toBe(true); - expect(result.has("slack_post_message")).toBe(true); - expect(result.has("custom_job")).toBe(true); - }); - - it("should return empty set and warn when GH_AW_SAFE_OUTPUT_JOBS is invalid JSON", () => { - process.env.GH_AW_SAFE_OUTPUT_JOBS = "invalid json"; - - const result = loadCustomSafeOutputJobTypes(); - - expect(result).toBeInstanceOf(Set); - expect(result.size).toBe(0); - expect(global.core.warning).toHaveBeenCalledWith(expect.stringContaining("Failed to parse GH_AW_SAFE_OUTPUT_JOBS")); - }); - - it("should handle empty object in GH_AW_SAFE_OUTPUT_JOBS", () => { - process.env.GH_AW_SAFE_OUTPUT_JOBS = JSON.stringify({}); - - const result = loadCustomSafeOutputJobTypes(); - - expect(result).toBeInstanceOf(Set); - expect(result.size).toBe(0); - }); - }); });