From 6e489a0cc232279a57802193dcdfd03d32de4a9a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Jul 2026 22:23:08 +0000 Subject: [PATCH 1/3] Initial plan From 42a6fc91820d9e97aa49a659d25bf3c72a588b8a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Jul 2026 22:38:50 +0000 Subject: [PATCH 2/3] fix(setup/js): replace isNaN, add parseInt radix, stringify setOutput, add .catch() to async entrypoints Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/assign_copilot_to_created_issues.cjs | 2 +- actions/setup/js/assign_milestone.cjs | 2 +- actions/setup/js/assign_to_agent.cjs | 4 ++-- actions/setup/js/autofix_code_scanning_alert.cjs | 2 +- actions/setup/js/check_skip_if_check_failing.cjs | 2 +- actions/setup/js/check_skip_if_helpers.cjs | 2 +- actions/setup/js/check_stop_time.cjs | 2 +- actions/setup/js/close_entity_helpers.cjs | 4 ++-- actions/setup/js/close_issue.cjs | 2 +- actions/setup/js/close_pull_request.cjs | 2 +- actions/setup/js/create_code_scanning_alert.cjs | 6 +++--- actions/setup/js/create_discussion.cjs | 2 +- actions/setup/js/create_issue.cjs | 2 +- actions/setup/js/create_pr_review_comment.cjs | 8 ++++---- actions/setup/js/create_project_status_update.cjs | 2 +- actions/setup/js/ephemerals.cjs | 4 ++-- actions/setup/js/error_recovery.cjs | 4 ++-- actions/setup/js/generate_usage_activity_summary.cjs | 2 +- actions/setup/js/github_rate_limit_logger.cjs | 2 +- actions/setup/js/merge_remote_agent_github_folder.cjs | 4 +++- actions/setup/js/parse_codex_log.cjs | 10 +++++----- actions/setup/js/parse_mcp_gateway_log.cjs | 5 ++++- actions/setup/js/parse_mcp_scripts_logs.cjs | 5 ++++- actions/setup/js/parse_token_usage.cjs | 5 ++++- actions/setup/js/safe_output_handler_manager.cjs | 6 +++--- actions/setup/js/safe_output_helpers.cjs | 8 ++++---- actions/setup/js/safe_output_type_validator.cjs | 6 +++--- actions/setup/js/safe_output_validator.cjs | 2 +- 28 files changed, 59 insertions(+), 48 deletions(-) diff --git a/actions/setup/js/assign_copilot_to_created_issues.cjs b/actions/setup/js/assign_copilot_to_created_issues.cjs index 17b64980f1d..77a74ee8cbe 100644 --- a/actions/setup/js/assign_copilot_to_created_issues.cjs +++ b/actions/setup/js/assign_copilot_to_created_issues.cjs @@ -54,7 +54,7 @@ async function main() { const repoSlug = parts[0]; const issueNumber = parseInt(parts[1], 10); - if (isNaN(issueNumber) || issueNumber <= 0) { + if (Number.isNaN(issueNumber) || issueNumber <= 0) { core.warning(`Invalid issue number in entry: ${entry}`); continue; } diff --git a/actions/setup/js/assign_milestone.cjs b/actions/setup/js/assign_milestone.cjs index d14dc992820..2e294de2c97 100644 --- a/actions/setup/js/assign_milestone.cjs +++ b/actions/setup/js/assign_milestone.cjs @@ -183,7 +183,7 @@ async function main(config = {}) { let milestoneNumber = Number(item.milestone_number); const milestoneTitle = item.milestone_title || null; - const hasMilestoneNumber = !isNaN(milestoneNumber) && milestoneNumber > 0; + const hasMilestoneNumber = !Number.isNaN(milestoneNumber) && milestoneNumber > 0; // Validate that at least one of milestone_number or milestone_title is provided if (!hasMilestoneNumber && !milestoneTitle) { diff --git a/actions/setup/js/assign_to_agent.cjs b/actions/setup/js/assign_to_agent.cjs index ff1dff969c9..3c09152628d 100644 --- a/actions/setup/js/assign_to_agent.cjs +++ b/actions/setup/js/assign_to_agent.cjs @@ -54,7 +54,7 @@ async function createAssignToAgentGitHubClient(config) { async function main(config = {}) { // Parse configuration (replaces env vars from the old standalone step) const maxCount = parseInt(String(config.max ?? "1"), 10); - if (isNaN(maxCount) || maxCount < 1) { + if (Number.isNaN(maxCount) || maxCount < 1) { throw new Error(`Invalid max value: ${config.max}. Must be a positive integer`); } const defaultAgent = String(config.name ?? "copilot").trim(); @@ -299,7 +299,7 @@ async function main(config = {}) { const issueNumber = type === "issue" ? number : null; const pullNumber = type === "pull request" ? number : null; - if (isNaN(number) || number <= 0) { + if (Number.isNaN(number) || number <= 0) { const error = `Invalid ${type} number: ${number}`; core.error(error); _allResults.push({ issue_number: issueNumber, pull_number: pullNumber, agent: agentName, owner: effectiveOwner, repo: effectiveRepo, success: false, error }); diff --git a/actions/setup/js/autofix_code_scanning_alert.cjs b/actions/setup/js/autofix_code_scanning_alert.cjs index 7dd5249c92a..ad5c0809e01 100644 --- a/actions/setup/js/autofix_code_scanning_alert.cjs +++ b/actions/setup/js/autofix_code_scanning_alert.cjs @@ -64,7 +64,7 @@ async function main(config = {}) { // Parse alert number const alertNumber = parseInt(String(message.alert_number), 10); - if (isNaN(alertNumber) || alertNumber <= 0) { + if (Number.isNaN(alertNumber) || alertNumber <= 0) { core.warning(`Invalid alert_number: ${message.alert_number}`); return { success: false, error: `Invalid alert_number: ${message.alert_number}` }; } diff --git a/actions/setup/js/check_skip_if_check_failing.cjs b/actions/setup/js/check_skip_if_check_failing.cjs index 9051488d426..6b4c397d751 100644 --- a/actions/setup/js/check_skip_if_check_failing.cjs +++ b/actions/setup/js/check_skip_if_check_failing.cjs @@ -67,7 +67,7 @@ function parseListEnv(envValue) { async function getCurrentRunCheckRunIds(owner, repo, runId) { if (!runId) return new Set(); const numericRunId = parseInt(runId, 10); - if (isNaN(numericRunId)) return new Set(); + if (Number.isNaN(numericRunId)) return new Set(); try { const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRun, { owner, diff --git a/actions/setup/js/check_skip_if_helpers.cjs b/actions/setup/js/check_skip_if_helpers.cjs index ed8813d5168..19d8e4f9a12 100644 --- a/actions/setup/js/check_skip_if_helpers.cjs +++ b/actions/setup/js/check_skip_if_helpers.cjs @@ -63,7 +63,7 @@ async function runSkipQueryGate(options) { core.info(`Running ${checkLabel} gate for workflow: ${workflowName}`); const threshold = parseInt(thresholdStr ?? "", 10); - if (isNaN(threshold) || threshold < 1) { + if (Number.isNaN(threshold) || threshold < 1) { core.setFailed(`${ERR_CONFIG}: Configuration error: ${thresholdEnvVar} must be a positive integer, got "${thresholdStr}".`); return; } diff --git a/actions/setup/js/check_stop_time.cjs b/actions/setup/js/check_stop_time.cjs index fc3ca7304ba..2ea0e18466d 100644 --- a/actions/setup/js/check_stop_time.cjs +++ b/actions/setup/js/check_stop_time.cjs @@ -22,7 +22,7 @@ async function main() { // Parse the stop time (format: "YYYY-MM-DD HH:MM:SS") const stopTimeDate = new Date(stopTime); - if (isNaN(stopTimeDate.getTime())) { + if (Number.isNaN(stopTimeDate.getTime())) { core.setFailed(`${ERR_VALIDATION}: Invalid stop-time format: ${stopTime}. Expected format: YYYY-MM-DD HH:MM:SS`); return; } diff --git a/actions/setup/js/close_entity_helpers.cjs b/actions/setup/js/close_entity_helpers.cjs index b917b2d93ac..a751e57b18d 100644 --- a/actions/setup/js/close_entity_helpers.cjs +++ b/actions/setup/js/close_entity_helpers.cjs @@ -156,7 +156,7 @@ function resolveEntityNumber(config, target, item, isEntityContext) { const targetNumber = item[config.numberField]; if (targetNumber) { const parsed = parseInt(targetNumber, 10); - if (isNaN(parsed) || parsed <= 0) { + if (Number.isNaN(parsed) || parsed <= 0) { return { success: false, message: `Invalid ${config.displayName} number specified: ${targetNumber}`, @@ -172,7 +172,7 @@ function resolveEntityNumber(config, target, item, isEntityContext) { if (target !== "triggering") { const parsed = parseInt(target, 10); - if (isNaN(parsed) || parsed <= 0) { + if (Number.isNaN(parsed) || parsed <= 0) { return { success: false, message: `Invalid ${config.displayName} number in target configuration: ${target}`, diff --git a/actions/setup/js/close_issue.cjs b/actions/setup/js/close_issue.cjs index 0eae6024a34..e1c018fa73e 100644 --- a/actions/setup/js/close_issue.cjs +++ b/actions/setup/js/close_issue.cjs @@ -224,7 +224,7 @@ async function main(config = {}) { // Not a temporary ID - parse as integer const issueNumber = parseInt(String(item.issue_number), 10); - if (isNaN(issueNumber)) { + if (Number.isNaN(issueNumber)) { return { success: false, error: `Invalid issue number: ${item.issue_number}` }; } return { success: true, entityNumber: issueNumber, owner: repoParts.owner, repo: repoParts.repo, entityRepo }; diff --git a/actions/setup/js/close_pull_request.cjs b/actions/setup/js/close_pull_request.cjs index 1271c775930..6522d0cc477 100644 --- a/actions/setup/js/close_pull_request.cjs +++ b/actions/setup/js/close_pull_request.cjs @@ -110,7 +110,7 @@ async function main(config = {}) { let prNumber; if (item.pull_request_number !== undefined) { prNumber = parseInt(String(item.pull_request_number), 10); - if (isNaN(prNumber)) { + if (Number.isNaN(prNumber)) { return { success: false, error: `Invalid pull request number: ${item.pull_request_number}` }; } } else { diff --git a/actions/setup/js/create_code_scanning_alert.cjs b/actions/setup/js/create_code_scanning_alert.cjs index 153c163b5a7..a5fa874a586 100644 --- a/actions/setup/js/create_code_scanning_alert.cjs +++ b/actions/setup/js/create_code_scanning_alert.cjs @@ -147,7 +147,7 @@ async function main(config = {}) { // Parse line number const line = parseInt(securityItem.line, 10); - if (isNaN(line) || line <= 0) { + if (Number.isNaN(line) || line <= 0) { core.warning(`Invalid line number: ${securityItem.line}`); return { success: false, @@ -166,7 +166,7 @@ async function main(config = {}) { }; } const parsedColumn = parseInt(securityItem.column, 10); - if (isNaN(parsedColumn) || parsedColumn <= 0) { + if (Number.isNaN(parsedColumn) || parsedColumn <= 0) { core.warning(`Invalid column number: ${securityItem.column}`); return { success: false, @@ -260,7 +260,7 @@ async function main(config = {}) { // Set outputs for the GitHub Action (these will be overwritten with each call) core.setOutput("sarif_file", sarifFilePath); - core.setOutput("findings_count", validFindings.length); + core.setOutput("findings_count", String(validFindings.length)); core.setOutput("artifact_uploaded", "pending"); core.setOutput("codeql_uploaded", "pending"); } catch (error) { diff --git a/actions/setup/js/create_discussion.cjs b/actions/setup/js/create_discussion.cjs index 78b4384e24c..cb81dfe66a0 100644 --- a/actions/setup/js/create_discussion.cjs +++ b/actions/setup/js/create_discussion.cjs @@ -304,7 +304,7 @@ async function main(config = {}) { if (rawCloseOlderKey && !closeOlderKey) { throw new Error(`${ERR_VALIDATION}: close-older-key "${rawCloseOlderKey}" is invalid: it must contain at least one alphanumeric character after normalization`); } - if (isNaN(minBodyLength) || minBodyLength < 0) { + if (Number.isNaN(minBodyLength) || minBodyLength < 0) { throw new Error(`${ERR_VALIDATION}: min_body_length must be a non-negative integer (got: ${config.min_body_length})`); } const includeFooter = parseBoolTemplatable(config.footer, true); diff --git a/actions/setup/js/create_issue.cjs b/actions/setup/js/create_issue.cjs index 6047b77fbfa..32587ed4b3d 100644 --- a/actions/setup/js/create_issue.cjs +++ b/actions/setup/js/create_issue.cjs @@ -704,7 +704,7 @@ async function main(config = {}) { } else { // It's a real issue number const parsed = parseInt(withoutHash, 10); - if (!isNaN(parsed)) { + if (!Number.isNaN(parsed)) { effectiveParentIssueNumber = parsed; } else { core.warning(`Invalid parent value: ${message.parent}. Expected either a valid temporary ID (format: aw_XXXXXXXXXXXX where X is a hex digit) or a numeric issue number.`); diff --git a/actions/setup/js/create_pr_review_comment.cjs b/actions/setup/js/create_pr_review_comment.cjs index d2f80190395..b2aa5ff32d7 100644 --- a/actions/setup/js/create_pr_review_comment.cjs +++ b/actions/setup/js/create_pr_review_comment.cjs @@ -175,7 +175,7 @@ async function main(config = {}) { // For target "*", we need an explicit PR number from the comment item if (commentItem.pull_request_number) { pullRequestNumber = parseInt(commentItem.pull_request_number, 10); - if (isNaN(pullRequestNumber) || pullRequestNumber <= 0) { + if (Number.isNaN(pullRequestNumber) || pullRequestNumber <= 0) { core.warning(`Invalid pull request number specified: ${commentItem.pull_request_number}`); return { success: false, @@ -192,7 +192,7 @@ async function main(config = {}) { } else if (commentTarget && commentTarget !== "triggering") { // Explicit PR number specified in target pullRequestNumber = parseInt(commentTarget, 10); - if (isNaN(pullRequestNumber) || pullRequestNumber <= 0) { + if (Number.isNaN(pullRequestNumber) || pullRequestNumber <= 0) { core.warning(`Invalid pull request number in target configuration: ${commentTarget}`); return { success: false, @@ -256,7 +256,7 @@ async function main(config = {}) { // Parse line numbers const line = parseInt(commentItem.line, 10); - if (isNaN(line) || line <= 0) { + if (Number.isNaN(line) || line <= 0) { core.warning(`Invalid line number: ${commentItem.line}`); return { success: false, @@ -267,7 +267,7 @@ async function main(config = {}) { let startLine = undefined; if (commentItem.start_line) { startLine = parseInt(commentItem.start_line, 10); - if (isNaN(startLine) || startLine <= 0 || startLine > line) { + if (Number.isNaN(startLine) || startLine <= 0 || startLine > line) { core.warning(`Invalid start_line number: ${commentItem.start_line} (must be <= line: ${line})`); return { success: false, diff --git a/actions/setup/js/create_project_status_update.cjs b/actions/setup/js/create_project_status_update.cjs index 6ab2b56decf..090666aaae7 100644 --- a/actions/setup/js/create_project_status_update.cjs +++ b/actions/setup/js/create_project_status_update.cjs @@ -237,7 +237,7 @@ function formatDate(date) { } // Otherwise parse and format const parsed = new Date(date); - if (isNaN(parsed.getTime())) { + if (Number.isNaN(parsed.getTime())) { core.warning(`Invalid date "${date}", using today`); return new Date().toISOString().split("T")[0]; } diff --git a/actions/setup/js/ephemerals.cjs b/actions/setup/js/ephemerals.cjs index 30c3bce3877..b55da0e4ee4 100644 --- a/actions/setup/js/ephemerals.cjs +++ b/actions/setup/js/ephemerals.cjs @@ -67,7 +67,7 @@ function extractExpirationDate(body) { const expirationDate = new Date(expirationISO); // Validate the date - if (!isNaN(expirationDate.getTime())) { + if (!Number.isNaN(expirationDate.getTime())) { return expirationDate; } } @@ -83,7 +83,7 @@ function extractExpirationDate(body) { const expirationDate = new Date(dateString); // Validate the date - if (!isNaN(expirationDate.getTime())) { + if (!Number.isNaN(expirationDate.getTime())) { return expirationDate; } } diff --git a/actions/setup/js/error_recovery.cjs b/actions/setup/js/error_recovery.cjs index fb32048be84..22f8d4cdb40 100644 --- a/actions/setup/js/error_recovery.cjs +++ b/actions/setup/js/error_recovery.cjs @@ -135,7 +135,7 @@ function getRetryAfterMs(error) { const retryAfter = headers["retry-after"]; if (retryAfter != null) { const seconds = parseInt(retryAfter, 10); - if (!isNaN(seconds) && seconds > 0) { + if (!Number.isNaN(seconds) && seconds > 0) { return seconds * 1000; } } @@ -144,7 +144,7 @@ function getRetryAfterMs(error) { const resetAt = headers["x-ratelimit-reset"]; if (resetAt != null) { const resetTimestampMs = parseInt(resetAt, 10) * 1000; - if (!isNaN(resetTimestampMs)) { + if (!Number.isNaN(resetTimestampMs)) { const waitMs = resetTimestampMs - Date.now(); if (waitMs > 0) { return waitMs; diff --git a/actions/setup/js/generate_usage_activity_summary.cjs b/actions/setup/js/generate_usage_activity_summary.cjs index 19e750c3610..58136adf567 100644 --- a/actions/setup/js/generate_usage_activity_summary.cjs +++ b/actions/setup/js/generate_usage_activity_summary.cjs @@ -146,7 +146,7 @@ function parseFirewallLogs() { let allowed = false; const code = parseInt(status, 10); - if (!isNaN(code) && [200, 206, 304].includes(code)) { + if (!Number.isNaN(code) && [200, 206, 304].includes(code)) { allowed = true; } diff --git a/actions/setup/js/github_rate_limit_logger.cjs b/actions/setup/js/github_rate_limit_logger.cjs index fc139b897f3..11293052966 100644 --- a/actions/setup/js/github_rate_limit_logger.cjs +++ b/actions/setup/js/github_rate_limit_logger.cjs @@ -71,7 +71,7 @@ function appendEntry(entry) { function parseResetTimestamp(resetHeader) { if (!resetHeader) return null; const seconds = parseInt(resetHeader, 10); - if (isNaN(seconds)) return null; + if (Number.isNaN(seconds)) return null; return new Date(seconds * 1000).toISOString(); } diff --git a/actions/setup/js/merge_remote_agent_github_folder.cjs b/actions/setup/js/merge_remote_agent_github_folder.cjs index 20bed192e63..a03e3422d95 100644 --- a/actions/setup/js/merge_remote_agent_github_folder.cjs +++ b/actions/setup/js/merge_remote_agent_github_folder.cjs @@ -435,7 +435,9 @@ async function main() { // Run if executed directly (not imported) if (require.main === module) { - main(); + main().catch(err => { + coreObj.setFailed(err && err.stack ? err.stack : String(err)); + }); } module.exports = { diff --git a/actions/setup/js/parse_codex_log.cjs b/actions/setup/js/parse_codex_log.cjs index bf76aad5905..7b9929210d3 100644 --- a/actions/setup/js/parse_codex_log.cjs +++ b/actions/setup/js/parse_codex_log.cjs @@ -29,7 +29,7 @@ function extractMCPInitialization(lines) { // Match: Found N MCP servers in configuration const countMatch = line.match(/Found (\d+) MCP servers? in configuration/i); if (countMatch) { - serverCount = parseInt(countMatch[1]); + serverCount = parseInt(countMatch[1], 10); } // Match: Connecting to MCP server: @@ -142,8 +142,8 @@ function extractCodexErrorMessages(lines) { // Match: Reconnecting... N/M (error message) - reconnect attempts with error details const reconnectMatch = line.match(/^Reconnecting\.\.\.\s+(\d+)\/(\d+)\s*\((.+)\)$/); if (reconnectMatch) { - const attempt = parseInt(reconnectMatch[1]); - const total = parseInt(reconnectMatch[2]); + const attempt = parseInt(reconnectMatch[1], 10); + const total = parseInt(reconnectMatch[2], 10); if (attempt > reconnectCount) reconnectCount = attempt; if (total > maxReconnects) maxReconnects = total; messages.add(reconnectMatch[3].trim()); @@ -795,7 +795,7 @@ function parseCodexLog(logContent) { // TokenCount(TokenCountEvent { ... total_tokens: 13281 ... const tokenCountMatches = logContent.matchAll(/total_tokens:\s*(\d+)/g); for (const match of tokenCountMatches) { - const tokens = parseInt(match[1]); + const tokens = parseInt(match[1], 10); totalTokens = Math.max(totalTokens, tokens); // Use the highest value (final total) } @@ -803,7 +803,7 @@ function parseCodexLog(logContent) { const finalTokensMatch = logContent.match(/tokens used\n([\d,]+)/); if (finalTokensMatch) { // Remove commas before parsing - totalTokens = parseInt(finalTokensMatch[1].replace(/,/g, "")); + totalTokens = parseInt(finalTokensMatch[1].replace(/,/g, ""), 10); } if (totalTokens > 0) { diff --git a/actions/setup/js/parse_mcp_gateway_log.cjs b/actions/setup/js/parse_mcp_gateway_log.cjs index e8b83fa253b..2e510c57df6 100644 --- a/actions/setup/js/parse_mcp_gateway_log.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.cjs @@ -1131,5 +1131,8 @@ if (typeof module !== "undefined" && module.exports) { // Run main if called directly if (require.main === module) { - main(); + main().catch(err => { + console.error(err && err.stack ? err.stack : String(err)); + process.exitCode = 1; + }); } diff --git a/actions/setup/js/parse_mcp_scripts_logs.cjs b/actions/setup/js/parse_mcp_scripts_logs.cjs index 0471c78efc3..37f6b50bbcf 100644 --- a/actions/setup/js/parse_mcp_scripts_logs.cjs +++ b/actions/setup/js/parse_mcp_scripts_logs.cjs @@ -412,5 +412,8 @@ if (typeof module !== "undefined" && module.exports) { // Run main if called directly if (require.main === module) { - main(); + main().catch(err => { + console.error(err && err.stack ? err.stack : String(err)); + process.exitCode = 1; + }); } diff --git a/actions/setup/js/parse_token_usage.cjs b/actions/setup/js/parse_token_usage.cjs index cb291e69c02..9b9ddd5cf31 100644 --- a/actions/setup/js/parse_token_usage.cjs +++ b/actions/setup/js/parse_token_usage.cjs @@ -235,5 +235,8 @@ if (typeof module !== "undefined" && module.exports) { // Run main if called directly if (require.main === module) { - main(); + main().catch(err => { + console.error(err && err.stack ? err.stack : String(err)); + process.exitCode = 1; + }); } diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index 81927104c16..13aee535f98 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -721,7 +721,7 @@ async function processMessages(messageHandlers, messages, onItemCreated = null) // This mirrors the precedence order used by individual safe output handlers. const rawNumber = message.item_number ?? message.issue_number ?? message.pull_request_number; const itemNumber = rawNumber != null ? parseInt(String(rawNumber), 10) : undefined; - const validNumber = itemNumber != null && !isNaN(itemNumber) ? itemNumber : undefined; + const validNumber = itemNumber != null && !Number.isNaN(itemNumber) ? itemNumber : undefined; const messageResult = { ...(validNumber != null ? { number: validNumber } : {}), @@ -1379,7 +1379,7 @@ async function main() { core.info("No safe-output messages available - nothing to process"); if (!isStaged) ensureManifestExists(); core.setOutput("temporary_id_map", "{}"); - core.setOutput("processed_count", 0); + core.setOutput("processed_count", "0"); return; } @@ -1410,7 +1410,7 @@ async function main() { if (!isStaged) ensureManifestExists(); // Set empty outputs for downstream steps core.setOutput("temporary_id_map", "{}"); - core.setOutput("processed_count", 0); + core.setOutput("processed_count", "0"); return; } diff --git a/actions/setup/js/safe_output_helpers.cjs b/actions/setup/js/safe_output_helpers.cjs index cd83467e10c..2b99e3236c2 100644 --- a/actions/setup/js/safe_output_helpers.cjs +++ b/actions/setup/js/safe_output_helpers.cjs @@ -39,7 +39,7 @@ function parseMaxCount(envValue, defaultValue = 3) { } const parsed = parseInt(envValue, 10); - if (isNaN(parsed) || parsed < 1) { + if (Number.isNaN(parsed) || parsed < 1) { return { valid: false, error: `Invalid max value: ${envValue}. Must be a positive integer`, @@ -155,7 +155,7 @@ function resolveTarget(params) { if (numberField) { itemNumber = typeof numberField === "number" ? numberField : parseInt(String(numberField), 10); - if (isNaN(itemNumber) || itemNumber <= 0) { + if (Number.isNaN(itemNumber) || itemNumber <= 0) { return { success: false, error: `Invalid ${fieldNames} specified: ${numberField}`, @@ -177,7 +177,7 @@ function resolveTarget(params) { } else if (target !== "triggering") { // Explicit number itemNumber = parseInt(target, 10); - if (isNaN(itemNumber) || itemNumber <= 0) { + if (Number.isNaN(itemNumber) || itemNumber <= 0) { // 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 @@ -296,7 +296,7 @@ function resolveIssueNumber(message) { let issueNumber; if (message.issue_number !== undefined) { issueNumber = parseInt(String(message.issue_number), 10); - if (isNaN(issueNumber)) { + if (Number.isNaN(issueNumber)) { return { success: false, error: `Invalid issue_number: ${message.issue_number}`, diff --git a/actions/setup/js/safe_output_type_validator.cjs b/actions/setup/js/safe_output_type_validator.cjs index 047cfdf13a6..430a72ba611 100644 --- a/actions/setup/js/safe_output_type_validator.cjs +++ b/actions/setup/js/safe_output_type_validator.cjs @@ -301,7 +301,7 @@ function validatePositiveInteger(value, fieldName, lineNum) { }; } const parsed = typeof value === "string" ? parseInt(value, 10) : value; - if (isNaN(parsed) || parsed <= 0 || !Number.isInteger(parsed)) { + if (Number.isNaN(parsed) || parsed <= 0 || !Number.isInteger(parsed)) { return { isValid: false, error: `Line ${lineNum}: ${fieldName} must be a valid positive integer (got: ${value})`, @@ -328,7 +328,7 @@ function validateOptionalPositiveInteger(value, fieldName, lineNum) { }; } const parsed = typeof value === "string" ? parseInt(value, 10) : value; - if (isNaN(parsed) || parsed <= 0 || !Number.isInteger(parsed)) { + if (Number.isNaN(parsed) || parsed <= 0 || !Number.isInteger(parsed)) { return { isValid: false, error: `Line ${lineNum}: ${fieldName} must be a valid positive integer (got: ${value})`, @@ -384,7 +384,7 @@ function validateIssueNumberOrTemporaryId(value, fieldName, lineNum) { } // Try to parse as positive integer const parsed = typeof value === "string" ? parseInt(value, 10) : value; - if (isNaN(parsed) || parsed <= 0 || !Number.isInteger(parsed)) { + if (Number.isNaN(parsed) || parsed <= 0 || !Number.isInteger(parsed)) { return { isValid: false, error: `Line ${lineNum}: ${fieldName} must be a positive integer or temporary ID (got: ${value})`, diff --git a/actions/setup/js/safe_output_validator.cjs b/actions/setup/js/safe_output_validator.cjs index 736041db6ba..8233c3255a5 100644 --- a/actions/setup/js/safe_output_validator.cjs +++ b/actions/setup/js/safe_output_validator.cjs @@ -166,7 +166,7 @@ function validateMaxCount(envValue, configDefault, fallbackDefault = 1) { } const parsed = parseInt(envValue, 10); - if (isNaN(parsed) || parsed < 1) { + if (Number.isNaN(parsed) || parsed < 1) { return { valid: false, error: `Invalid max value: ${envValue}. Must be a positive integer`, From 88af3e2d092e5be1846ebe16117a8921ed190716 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 02:10:42 +0000 Subject: [PATCH 3/3] fix(setup/js): stringify processed_count setOutput, update test assertions, add setFailed coverage Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .../js/create_code_scanning_alert.test.cjs | 2 +- .../setup/js/parse_mcp_gateway_log.test.cjs | 37 +++++++++++++++++++ .../setup/js/safe_output_handler_manager.cjs | 2 +- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/actions/setup/js/create_code_scanning_alert.test.cjs b/actions/setup/js/create_code_scanning_alert.test.cjs index 8f324ae7313..922c2f85bca 100644 --- a/actions/setup/js/create_code_scanning_alert.test.cjs +++ b/actions/setup/js/create_code_scanning_alert.test.cjs @@ -272,7 +272,7 @@ describe("create_code_scanning_alert (Handler Factory Architecture)", () => { await handler(message, {}); expect(mockCore.setOutput).toHaveBeenCalledWith("sarif_file", sarifFile); - expect(mockCore.setOutput).toHaveBeenCalledWith("findings_count", 1); + expect(mockCore.setOutput).toHaveBeenCalledWith("findings_count", "1"); expect(mockCore.setOutput).toHaveBeenCalledWith("artifact_uploaded", "pending"); expect(mockCore.setOutput).toHaveBeenCalledWith("codeql_uploaded", "pending"); }); diff --git a/actions/setup/js/parse_mcp_gateway_log.test.cjs b/actions/setup/js/parse_mcp_gateway_log.test.cjs index 385c7b13732..4904faaab55 100644 --- a/actions/setup/js/parse_mcp_gateway_log.test.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.test.cjs @@ -767,6 +767,43 @@ Some content here.`; fs.rmSync(tmpDir, { recursive: true, force: true }); } }); + + test("calls setFailed when an unexpected error is thrown inside main", async () => { + const originalExistsSync = fs.existsSync; + const originalReadFileSync = fs.readFileSync; + + const mockCore = { + info: vi.fn(), + debug: vi.fn(), + startGroup: vi.fn(), + endGroup: vi.fn(), + notice: vi.fn(), + warning: vi.fn(), + error: vi.fn(), + setFailed: vi.fn(), + exportVariable: vi.fn(), + setOutput: vi.fn(), + summary: { + addRaw: vi.fn().mockReturnThis(), + addDetails: vi.fn().mockReturnThis(), + write: vi.fn().mockRejectedValue(new Error("summary write failure")), + }, + }; + + fs.existsSync = vi.fn(() => false); + fs.readFileSync = vi.fn((p, enc) => originalReadFileSync(p, enc)); + global.core = mockCore; + + try { + const { main } = require("./parse_mcp_gateway_log.cjs"); + await main(); + expect(mockCore.setFailed).toHaveBeenCalledWith(expect.stringContaining("summary write failure")); + } finally { + fs.existsSync = originalExistsSync; + fs.readFileSync = originalReadFileSync; + delete global.core; + } + }); }); describe("printAllGatewayFiles", () => { diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index 13aee535f98..f2f8148f723 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -1566,7 +1566,7 @@ async function main() { } // Export processed count for consistency with project handler - core.setOutput("processed_count", successCount); + core.setOutput("processed_count", String(successCount)); // Export assign_to_agent outputs when the handler was loaded if (messageHandlers.has("assign_to_agent")) {