From 7506e9a6dc813cafa3b8d73f90af94db9deb92a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 04:29:56 +0000 Subject: [PATCH 1/2] refactor: dedupe mention-alias normalization and JSONL iteration helpers - add_comment.cjs: extract normalizeMentionAliases() to remove duplicated alias-trimming pipeline between preResolvedMentionAliases and configuredMentionAliases - add_reaction.cjs: simplify REACTION_MAP membership check to use the 'in' operator instead of Object.prototype.hasOwnProperty.call - ai_credits_context.cjs: reuse iterateJSONLFiles() inside iterateAuditEntries() instead of duplicating the file-read/parse loop No behavior changes. Validated with targeted vitest suite (275 tests passed across add_comment, ai_credits_context, add_reaction, and add_reaction_and_edit_comment test files), make lint (0 new warnings), and make build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- actions/setup/js/add_comment.cjs | 16 ++++++++++++---- actions/setup/js/add_reaction.cjs | 2 +- actions/setup/js/ai_credits_context.cjs | 17 +---------------- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/actions/setup/js/add_comment.cjs b/actions/setup/js/add_comment.cjs index 7078fc56482..00c86fde8a8 100644 --- a/actions/setup/js/add_comment.cjs +++ b/actions/setup/js/add_comment.cjs @@ -72,6 +72,16 @@ function normalizeWorkflowIdList(ids) { ]; } +/** + * Normalize a list of mention aliases: trim, strip leading "@" characters, and drop empty entries. + * @param {unknown} aliases + * @returns {string[]} + */ +function normalizeMentionAliases(aliases) { + if (!Array.isArray(aliases)) return []; + return aliases.map(alias => (typeof alias === "string" ? alias.trim().replace(/^@+/, "") : "")).filter(alias => alias.length > 0); +} + /** * Resolve effective event name/payload for native and forwarded contexts. * Supports: @@ -408,10 +418,8 @@ async function main(config = {}) { const requiredLabels = Array.isArray(config.required_labels) ? config.required_labels : []; const requiredTitlePrefix = config.required_title_prefix || ""; const mentionsDisabled = config.mentions === false || config.mentions?.enabled === false; - const preResolvedMentionAliases = - !mentionsDisabled && Array.isArray(config.allowedMentionAliases) ? config.allowedMentionAliases.map(alias => (typeof alias === "string" ? alias.trim().replace(/^@+/, "") : "")).filter(alias => alias.length > 0) : []; - const configuredMentionAliases = - !mentionsDisabled && Array.isArray(config.mentions?.allowed) ? config.mentions.allowed.map(alias => (typeof alias === "string" ? alias.trim().replace(/^@+/, "") : "")).filter(alias => alias.length > 0) : []; + const preResolvedMentionAliases = !mentionsDisabled ? normalizeMentionAliases(config.allowedMentionAliases) : []; + const configuredMentionAliases = !mentionsDisabled ? normalizeMentionAliases(config.mentions?.allowed) : []; // Create an authenticated GitHub client. Uses config["github-token"] when set // (for cross-repository operations), otherwise falls back to the step-level github. diff --git a/actions/setup/js/add_reaction.cjs b/actions/setup/js/add_reaction.cjs index 2c73eda195e..4fba262355f 100644 --- a/actions/setup/js/add_reaction.cjs +++ b/actions/setup/js/add_reaction.cjs @@ -30,7 +30,7 @@ async function main() { core.info(`Adding reaction: ${reaction}`); // Validate reaction type - if (!Object.prototype.hasOwnProperty.call(REACTION_MAP, reaction)) { + if (!(reaction in REACTION_MAP)) { core.setFailed(`${ERR_VALIDATION}: Invalid reaction type: ${reaction}. Valid reactions are: ${Object.keys(REACTION_MAP).join(", ")}`); return; } diff --git a/actions/setup/js/ai_credits_context.cjs b/actions/setup/js/ai_credits_context.cjs index 70ae4b3a79a..824ee467183 100644 --- a/actions/setup/js/ai_credits_context.cjs +++ b/actions/setup/js/ai_credits_context.cjs @@ -206,22 +206,7 @@ function parseAICreditsErrorInfoFromAuditEntry(entry) { function iterateAuditEntries(auditJsonlPathOverride, defaultValue, contentGuard, accumulate) { try { const auditJsonlPath = resolveFirewallAuditLogPath(auditJsonlPathOverride); - if (!fs.existsSync(auditJsonlPath)) return defaultValue; - const content = fs.readFileSync(auditJsonlPath, "utf8"); - if (!content.trim()) return defaultValue; - if (contentGuard && !contentGuard(content)) return defaultValue; - let result = defaultValue; - for (const line of content.split("\n")) { - const trimmed = line.trim(); - if (!trimmed || trimmed[0] !== "{") continue; - try { - const nextResult = accumulate(result, JSON.parse(trimmed)); - if (nextResult !== undefined) result = nextResult; - } catch { - // ignore malformed lines - } - } - return result; + return iterateJSONLFiles([auditJsonlPath], defaultValue, contentGuard, accumulate); } catch { return defaultValue; } From b6fe1d0a9a5d645508298821cbc5ae65a79b7cbb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 05:48:35 +0000 Subject: [PATCH 2/2] fix: restore own-property reaction validation Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/add_reaction.cjs | 2 +- actions/setup/js/add_reaction.test.cjs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/add_reaction.cjs b/actions/setup/js/add_reaction.cjs index 4fba262355f..75a6916a9dd 100644 --- a/actions/setup/js/add_reaction.cjs +++ b/actions/setup/js/add_reaction.cjs @@ -30,7 +30,7 @@ async function main() { core.info(`Adding reaction: ${reaction}`); // Validate reaction type - if (!(reaction in REACTION_MAP)) { + if (!Object.hasOwn(REACTION_MAP, reaction)) { core.setFailed(`${ERR_VALIDATION}: Invalid reaction type: ${reaction}. Valid reactions are: ${Object.keys(REACTION_MAP).join(", ")}`); return; } diff --git a/actions/setup/js/add_reaction.test.cjs b/actions/setup/js/add_reaction.test.cjs index c6678b2be62..9ea42604a3e 100644 --- a/actions/setup/js/add_reaction.test.cjs +++ b/actions/setup/js/add_reaction.test.cjs @@ -107,6 +107,15 @@ describe("add_reaction", () => { expect(mockGithub.request).not.toHaveBeenCalled(); }); + it("should reject inherited property names as invalid reaction types", async () => { + process.env.GH_AW_REACTION = "constructor"; + + await runScript(); + + expect(mockCore.setFailed).toHaveBeenCalledWith(expect.stringContaining("Invalid reaction type")); + expect(mockGithub.request).not.toHaveBeenCalled(); + }); + it("should accept all valid reaction types", async () => { const validReactions = ["+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", "eyes"];