From 5167de009e6abe32d2009429529a9935c4888ef3 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Wed, 1 Apr 2026 04:48:12 +0000
Subject: [PATCH] jsweep: clean messages_run_status.cjs
- Extract renderConfiguredMessage() helper to eliminate 7x repeated pattern
(getMessages + toSnakeCase + ternary renderTemplate call)
- Remove unused /// directive
(module uses no github-script globals)
- Each exported function is now a readable one-liner
- Add comprehensive test file with 20 test cases covering all 7 functions,
default templates, custom templates, placeholder substitution,
camelCase/snake_case keys, and fallback behavior
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
actions/setup/js/messages_run_status.cjs | 73 +++-----
actions/setup/js/messages_run_status.test.cjs | 156 ++++++++++++++++++
2 files changed, 176 insertions(+), 53 deletions(-)
create mode 100644 actions/setup/js/messages_run_status.test.cjs
diff --git a/actions/setup/js/messages_run_status.cjs b/actions/setup/js/messages_run_status.cjs
index 88c95236409..e1d7e20526e 100644
--- a/actions/setup/js/messages_run_status.cjs
+++ b/actions/setup/js/messages_run_status.cjs
@@ -1,5 +1,4 @@
// @ts-check
-///
/**
* Run Status Message Module
@@ -10,6 +9,19 @@
const { getMessages, renderTemplate, toSnakeCase } = require("./messages_core.cjs");
+/**
+ * Renders a message using a custom template from config or a default template.
+ * @param {string} messageKey - Key in the messages config (e.g., "runStarted")
+ * @param {string} defaultTemplate - Default template string with {placeholder} syntax
+ * @param {Object} ctx - Context object for template substitution
+ * @returns {string} Rendered message
+ */
+function renderConfiguredMessage(messageKey, defaultTemplate, ctx) {
+ const messages = getMessages();
+ const template = messages?.[messageKey] ?? defaultTemplate;
+ return renderTemplate(template, toSnakeCase(ctx));
+}
+
/**
* @typedef {Object} RunStartedContext
* @property {string} workflowName - Name of the workflow
@@ -23,16 +35,7 @@ const { getMessages, renderTemplate, toSnakeCase } = require("./messages_core.cj
* @returns {string} Run-started message
*/
function getRunStartedMessage(ctx) {
- const messages = getMessages();
-
- // Create context with both camelCase and snake_case keys
- const templateContext = toSnakeCase(ctx);
-
- // Default run-started template
- const defaultMessage = "🚀 [{workflow_name}]({run_url}) has started processing this {event_type}";
-
- // Use custom message if configured
- return messages?.runStarted ? renderTemplate(messages.runStarted, templateContext) : renderTemplate(defaultMessage, templateContext);
+ return renderConfiguredMessage("runStarted", "🚀 [{workflow_name}]({run_url}) has started processing this {event_type}", ctx);
}
/**
@@ -47,16 +50,7 @@ function getRunStartedMessage(ctx) {
* @returns {string} Run-success message
*/
function getRunSuccessMessage(ctx) {
- const messages = getMessages();
-
- // Create context with both camelCase and snake_case keys
- const templateContext = toSnakeCase(ctx);
-
- // Default run-success template
- const defaultMessage = "✅ [{workflow_name}]({run_url}) completed successfully!";
-
- // Use custom message if configured
- return messages?.runSuccess ? renderTemplate(messages.runSuccess, templateContext) : renderTemplate(defaultMessage, templateContext);
+ return renderConfiguredMessage("runSuccess", "✅ [{workflow_name}]({run_url}) completed successfully!", ctx);
}
/**
@@ -72,16 +66,7 @@ function getRunSuccessMessage(ctx) {
* @returns {string} Run-failure message
*/
function getRunFailureMessage(ctx) {
- const messages = getMessages();
-
- // Create context with both camelCase and snake_case keys
- const templateContext = toSnakeCase(ctx);
-
- // Default run-failure template
- const defaultMessage = "❌ [{workflow_name}]({run_url}) {status}. Please review the logs for details.";
-
- // Use custom message if configured
- return messages?.runFailure ? renderTemplate(messages.runFailure, templateContext) : renderTemplate(defaultMessage, templateContext);
+ return renderConfiguredMessage("runFailure", "❌ [{workflow_name}]({run_url}) {status}. Please review the logs for details.", ctx);
}
/**
@@ -96,16 +81,7 @@ function getRunFailureMessage(ctx) {
* @returns {string} Detection-failure message
*/
function getDetectionFailureMessage(ctx) {
- const messages = getMessages();
-
- // Create context with both camelCase and snake_case keys
- const templateContext = toSnakeCase(ctx);
-
- // Default detection-failure template
- const defaultMessage = "⚠️ Security scanning failed for [{workflow_name}]({run_url}). Review the logs for details.";
-
- // Use custom message if configured
- return messages?.detectionFailure ? renderTemplate(messages.detectionFailure, templateContext) : renderTemplate(defaultMessage, templateContext);
+ return renderConfiguredMessage("detectionFailure", "⚠️ Security scanning failed for [{workflow_name}]({run_url}). Review the logs for details.", ctx);
}
/**
@@ -120,10 +96,7 @@ function getDetectionFailureMessage(ctx) {
* @returns {string} Pull-request-created message
*/
function getPullRequestCreatedMessage(ctx) {
- const messages = getMessages();
- const templateContext = toSnakeCase(ctx);
- const defaultMessage = "Pull request created: [#{item_number}]({item_url})";
- return messages?.pullRequestCreated ? renderTemplate(messages.pullRequestCreated, templateContext) : renderTemplate(defaultMessage, templateContext);
+ return renderConfiguredMessage("pullRequestCreated", "Pull request created: [#{item_number}]({item_url})", ctx);
}
/**
@@ -138,10 +111,7 @@ function getPullRequestCreatedMessage(ctx) {
* @returns {string} Issue-created message
*/
function getIssueCreatedMessage(ctx) {
- const messages = getMessages();
- const templateContext = toSnakeCase(ctx);
- const defaultMessage = "Issue created: [#{item_number}]({item_url})";
- return messages?.issueCreated ? renderTemplate(messages.issueCreated, templateContext) : renderTemplate(defaultMessage, templateContext);
+ return renderConfiguredMessage("issueCreated", "Issue created: [#{item_number}]({item_url})", ctx);
}
/**
@@ -157,10 +127,7 @@ function getIssueCreatedMessage(ctx) {
* @returns {string} Commit-pushed message
*/
function getCommitPushedMessage(ctx) {
- const messages = getMessages();
- const templateContext = toSnakeCase(ctx);
- const defaultMessage = "Commit pushed: [`{short_sha}`]({commit_url})";
- return messages?.commitPushed ? renderTemplate(messages.commitPushed, templateContext) : renderTemplate(defaultMessage, templateContext);
+ return renderConfiguredMessage("commitPushed", "Commit pushed: [`{short_sha}`]({commit_url})", ctx);
}
module.exports = {
diff --git a/actions/setup/js/messages_run_status.test.cjs b/actions/setup/js/messages_run_status.test.cjs
new file mode 100644
index 00000000000..cf28a6d9537
--- /dev/null
+++ b/actions/setup/js/messages_run_status.test.cjs
@@ -0,0 +1,156 @@
+// @ts-check
+import { describe, it, expect, beforeEach, vi } from "vitest";
+
+// messages_core.cjs calls core.warning on parse failures - provide a stub
+const mockCore = {
+ info: vi.fn(),
+ warning: vi.fn(),
+ error: vi.fn(),
+ setFailed: vi.fn(),
+ setOutput: vi.fn(),
+};
+global.core = mockCore;
+
+const { getRunStartedMessage, getRunSuccessMessage, getRunFailureMessage, getDetectionFailureMessage, getPullRequestCreatedMessage, getIssueCreatedMessage, getCommitPushedMessage } = require("./messages_run_status.cjs");
+
+const WORKFLOW = "My Workflow";
+const RUN_URL = "https://github.com/owner/repo/actions/runs/99";
+
+describe("messages_run_status", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ delete process.env.GH_AW_SAFE_OUTPUT_MESSAGES;
+ });
+
+ describe("getRunStartedMessage", () => {
+ it("returns default template with all placeholders substituted", () => {
+ const msg = getRunStartedMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, eventType: "issue" });
+ expect(msg).toBe(`🚀 [${WORKFLOW}](${RUN_URL}) has started processing this issue`);
+ });
+
+ it("supports different event types", () => {
+ expect(getRunStartedMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, eventType: "pull request" })).toContain("pull request");
+ expect(getRunStartedMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, eventType: "discussion" })).toContain("discussion");
+ });
+
+ it("uses custom template from config", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ runStarted: "Custom: {workflow_name} started" });
+ const msg = getRunStartedMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, eventType: "issue" });
+ expect(msg).toBe(`Custom: ${WORKFLOW} started`);
+ });
+
+ it("substitutes camelCase keys as well as snake_case", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ runStarted: "{workflowName} at {runUrl}" });
+ const msg = getRunStartedMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, eventType: "issue" });
+ expect(msg).toBe(`${WORKFLOW} at ${RUN_URL}`);
+ });
+ });
+
+ describe("getRunSuccessMessage", () => {
+ it("returns default template with placeholders substituted", () => {
+ const msg = getRunSuccessMessage({ workflowName: WORKFLOW, runUrl: RUN_URL });
+ expect(msg).toBe(`✅ [${WORKFLOW}](${RUN_URL}) completed successfully!`);
+ });
+
+ it("uses custom template from config", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ runSuccess: "Done: {workflow_name}" });
+ const msg = getRunSuccessMessage({ workflowName: WORKFLOW, runUrl: RUN_URL });
+ expect(msg).toBe(`Done: ${WORKFLOW}`);
+ });
+
+ it("ignores unrelated config keys and uses default", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ runStarted: "overridden" });
+ const msg = getRunSuccessMessage({ workflowName: WORKFLOW, runUrl: RUN_URL });
+ expect(msg).toContain("completed successfully");
+ });
+ });
+
+ describe("getRunFailureMessage", () => {
+ it("returns default template with status substituted", () => {
+ const msg = getRunFailureMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, status: "failed" });
+ expect(msg).toBe(`❌ [${WORKFLOW}](${RUN_URL}) failed. Please review the logs for details.`);
+ });
+
+ it("handles different status values", () => {
+ expect(getRunFailureMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, status: "was cancelled" })).toContain("was cancelled");
+ expect(getRunFailureMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, status: "timed out" })).toContain("timed out");
+ });
+
+ it("uses custom template from config", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ runFailure: "FAILED: {workflow_name} - {status}" });
+ const msg = getRunFailureMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, status: "failed" });
+ expect(msg).toBe(`FAILED: ${WORKFLOW} - failed`);
+ });
+ });
+
+ describe("getDetectionFailureMessage", () => {
+ it("returns default template with placeholders substituted", () => {
+ const msg = getDetectionFailureMessage({ workflowName: WORKFLOW, runUrl: RUN_URL });
+ expect(msg).toBe(`⚠️ Security scanning failed for [${WORKFLOW}](${RUN_URL}). Review the logs for details.`);
+ });
+
+ it("uses custom template from config", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ detectionFailure: "Security alert for {workflow_name}" });
+ const msg = getDetectionFailureMessage({ workflowName: WORKFLOW, runUrl: RUN_URL });
+ expect(msg).toBe(`Security alert for ${WORKFLOW}`);
+ });
+ });
+
+ describe("getPullRequestCreatedMessage", () => {
+ it("returns default template with item_number and item_url substituted", () => {
+ const msg = getPullRequestCreatedMessage({ itemNumber: 42, itemUrl: "https://github.com/owner/repo/pull/42" });
+ expect(msg).toBe("Pull request created: [#42](https://github.com/owner/repo/pull/42)");
+ });
+
+ it("uses custom template from config", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ pullRequestCreated: "PR #{item_number} ready" });
+ const msg = getPullRequestCreatedMessage({ itemNumber: 7, itemUrl: "https://github.com/owner/repo/pull/7" });
+ expect(msg).toBe("PR #7 ready");
+ });
+ });
+
+ describe("getIssueCreatedMessage", () => {
+ it("returns default template with item_number and item_url substituted", () => {
+ const msg = getIssueCreatedMessage({ itemNumber: 15, itemUrl: "https://github.com/owner/repo/issues/15" });
+ expect(msg).toBe("Issue created: [#15](https://github.com/owner/repo/issues/15)");
+ });
+
+ it("uses custom template from config", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ issueCreated: "New issue #{item_number}" });
+ const msg = getIssueCreatedMessage({ itemNumber: 3, itemUrl: "https://github.com/owner/repo/issues/3" });
+ expect(msg).toBe("New issue #3");
+ });
+ });
+
+ describe("getCommitPushedMessage", () => {
+ const SHA = "abc1234def5678901234567890123456789012ab";
+ const SHORT = "abc1234";
+ const COMMIT_URL = `https://github.com/owner/repo/commit/${SHA}`;
+
+ it("returns default template with short_sha and commit_url substituted", () => {
+ const msg = getCommitPushedMessage({ commitSha: SHA, shortSha: SHORT, commitUrl: COMMIT_URL });
+ expect(msg).toBe(`Commit pushed: [\`${SHORT}\`](${COMMIT_URL})`);
+ });
+
+ it("uses custom template from config", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ commitPushed: "Pushed {short_sha} to repo" });
+ const msg = getCommitPushedMessage({ commitSha: SHA, shortSha: SHORT, commitUrl: COMMIT_URL });
+ expect(msg).toBe(`Pushed ${SHORT} to repo`);
+ });
+
+ it("supports full SHA in custom template", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ commitPushed: "{commit_sha}" });
+ const msg = getCommitPushedMessage({ commitSha: SHA, shortSha: SHORT, commitUrl: COMMIT_URL });
+ expect(msg).toBe(SHA);
+ });
+ });
+
+ describe("fallback when config is missing keys", () => {
+ it("uses default template when only unrelated config keys are set", () => {
+ process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ footer: "custom footer" });
+ expect(getRunStartedMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, eventType: "issue" })).toContain("has started processing");
+ expect(getRunSuccessMessage({ workflowName: WORKFLOW, runUrl: RUN_URL })).toContain("completed successfully");
+ expect(getRunFailureMessage({ workflowName: WORKFLOW, runUrl: RUN_URL, status: "failed" })).toContain("failed");
+ });
+ });
+});