From 4aa9687a5953be0846bec52256b223b8ba1c1d4c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 18:08:17 +0000 Subject: [PATCH 1/3] Initial plan From 78e9871a0e88a0e6c73144a89213d9e0d4f84faa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 18:23:12 +0000 Subject: [PATCH 2/3] Add test for update_issue with invalid target Co-authored-by: eaftan <4733401+eaftan@users.noreply.github.com> --- actions/setup/js/safe_output_helpers.test.cjs | 11 +++++ .../js/test_update_issue_invalid_target.cjs | 48 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 actions/setup/js/test_update_issue_invalid_target.cjs diff --git a/actions/setup/js/safe_output_helpers.test.cjs b/actions/setup/js/safe_output_helpers.test.cjs index fc774d08efa..361aa00c824 100644 --- a/actions/setup/js/safe_output_helpers.test.cjs +++ b/actions/setup/js/safe_output_helpers.test.cjs @@ -393,6 +393,17 @@ describe("safe_output_helpers", () => { expect(result.contextType).toBe("issue"); }); + it("should fail for invalid explicit number with correct error message", () => { + const result = helpers.resolveTarget({ + ...baseParams, + targetConfig: "event", + }); + expect(result.success).toBe(false); + expect(result.error).toContain("Invalid issue number"); + expect(result.error).not.toContain("pull request"); + expect(result.shouldFail).toBe(true); + }); + it("should resolve wildcard with issue_number", () => { const result = helpers.resolveTarget({ ...baseParams, diff --git a/actions/setup/js/test_update_issue_invalid_target.cjs b/actions/setup/js/test_update_issue_invalid_target.cjs new file mode 100644 index 00000000000..c2326c9ac28 --- /dev/null +++ b/actions/setup/js/test_update_issue_invalid_target.cjs @@ -0,0 +1,48 @@ +// Quick test to verify update_issue behavior with invalid target +const { main } = require("./update_issue.cjs"); + +// Mock global objects +global.core = { + info: (...args) => console.log("INFO:", ...args), + warning: (...args) => console.log("WARNING:", ...args), + error: (...args) => console.log("ERROR:", ...args), + debug: () => {}, + setOutput: () => {}, +}; + +global.github = { + rest: { + issues: { + get: async () => ({ data: { body: "old body", number: 230 } }), + update: async (params) => { + console.log("UPDATE CALLED:", params); + return { data: { number: params.issue_number, html_url: "https://github.com/test/test/issues/230", title: "Test" } }; + }, + }, + }, +}; + +global.context = { + eventName: "issues", + repo: { owner: "test", repo: "test" }, + serverUrl: "https://github.com", + runId: 12345, + payload: { issue: { number: 100 } }, +}; + +async function test() { + console.log("\n=== Testing update_issue with target='event' ===\n"); + + const handler = await main({ target: "event", allow_body: true, max: 10 }); + const message = { + type: "update_issue", + body: "New body content", + }; + + const result = await handler(message, {}); + + console.log("\n=== Result ==="); + console.log(JSON.stringify(result, null, 2)); +} + +test().catch(console.error); From 521b5c05dddda265be02e2cbe344a9f71a5df3f1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 18:31:05 +0000 Subject: [PATCH 3/3] Fix error message for invalid target configuration with helpful guidance Co-authored-by: eaftan <4733401+eaftan@users.noreply.github.com> --- actions/setup/js/safe_output_helpers.cjs | 30 +++++++++++- actions/setup/js/safe_output_helpers.test.cjs | 4 +- .../js/test_update_issue_invalid_target.cjs | 48 ------------------- 3 files changed, 31 insertions(+), 51 deletions(-) delete mode 100644 actions/setup/js/test_update_issue_invalid_target.cjs diff --git a/actions/setup/js/safe_output_helpers.cjs b/actions/setup/js/safe_output_helpers.cjs index d248483f128..dbd1f98d9c5 100644 --- a/actions/setup/js/safe_output_helpers.cjs +++ b/actions/setup/js/safe_output_helpers.cjs @@ -151,10 +151,36 @@ function resolveTarget(params) { // Explicit number itemNumber = parseInt(target, 10); if (isNaN(itemNumber) || itemNumber <= 0) { - const itemTypeName = supportsPR || supportsIssue ? "issue" : "pull request"; + // Determine the correct item type name based on what the handler supports + // Convention: supportsPR=true means both issues and PRs (unless supportsIssue explicitly says otherwise) + // supportsIssue=true means issues only + // supportsPR=false with supportsIssue=false/undefined means PRs only + let itemTypeName; + let helpText = ""; + + if (supportsIssue === true) { + // Issues only + itemTypeName = "issue"; + helpText = `Make sure you're using a proper expression like "\${{ github.event.issue.number }}" and that the workflow is running in an issue context.`; + } else if (supportsPR === true) { + // Both issues and PRs (supportsPR=true is used by handlers that support both) + itemTypeName = "issue or pull request"; + helpText = `Make sure you're using a proper expression like "\${{ github.event.issue.number }}" for issues or "\${{ github.event.pull_request.number }}" for pull requests, and that the workflow is running in the correct context.`; + } else { + // PRs only (supportsPR=false, supportsIssue=false/undefined) + itemTypeName = "pull request"; + helpText = `Make sure you're using a proper expression like "\${{ github.event.pull_request.number }}" and that the workflow is running in a pull request context.`; + } + + // Provide helpful error message if target looks like a failed expression evaluation + let errorMessage = `Invalid ${itemTypeName} number in target configuration: ${target}`; + if (target === "event" || target === "[object Object]" || target.includes("github.event")) { + errorMessage += `. It looks like the target contains a GitHub Actions expression that didn't evaluate correctly. ${helpText}`; + } + return { success: false, - error: `Invalid ${itemTypeName} number in target configuration: ${target}`, + error: errorMessage, shouldFail: true, }; } diff --git a/actions/setup/js/safe_output_helpers.test.cjs b/actions/setup/js/safe_output_helpers.test.cjs index 361aa00c824..1789eefa29d 100644 --- a/actions/setup/js/safe_output_helpers.test.cjs +++ b/actions/setup/js/safe_output_helpers.test.cjs @@ -137,7 +137,7 @@ describe("safe_output_helpers", () => { targetConfig: "invalid", }); expect(result.success).toBe(false); - expect(result.error).toContain("Invalid issue number"); + expect(result.error).toContain("Invalid issue or pull request number"); expect(result.shouldFail).toBe(true); }); @@ -400,6 +400,8 @@ describe("safe_output_helpers", () => { }); expect(result.success).toBe(false); expect(result.error).toContain("Invalid issue number"); + expect(result.error).toContain("GitHub Actions expression that didn't evaluate correctly"); + expect(result.error).toContain("github.event.issue.number"); expect(result.error).not.toContain("pull request"); expect(result.shouldFail).toBe(true); }); diff --git a/actions/setup/js/test_update_issue_invalid_target.cjs b/actions/setup/js/test_update_issue_invalid_target.cjs deleted file mode 100644 index c2326c9ac28..00000000000 --- a/actions/setup/js/test_update_issue_invalid_target.cjs +++ /dev/null @@ -1,48 +0,0 @@ -// Quick test to verify update_issue behavior with invalid target -const { main } = require("./update_issue.cjs"); - -// Mock global objects -global.core = { - info: (...args) => console.log("INFO:", ...args), - warning: (...args) => console.log("WARNING:", ...args), - error: (...args) => console.log("ERROR:", ...args), - debug: () => {}, - setOutput: () => {}, -}; - -global.github = { - rest: { - issues: { - get: async () => ({ data: { body: "old body", number: 230 } }), - update: async (params) => { - console.log("UPDATE CALLED:", params); - return { data: { number: params.issue_number, html_url: "https://github.com/test/test/issues/230", title: "Test" } }; - }, - }, - }, -}; - -global.context = { - eventName: "issues", - repo: { owner: "test", repo: "test" }, - serverUrl: "https://github.com", - runId: 12345, - payload: { issue: { number: 100 } }, -}; - -async function test() { - console.log("\n=== Testing update_issue with target='event' ===\n"); - - const handler = await main({ target: "event", allow_body: true, max: 10 }); - const message = { - type: "update_issue", - body: "New body content", - }; - - const result = await handler(message, {}); - - console.log("\n=== Result ==="); - console.log(JSON.stringify(result, null, 2)); -} - -test().catch(console.error);