Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 81 additions & 3 deletions actions/setup/js/parse_mcp_gateway_log.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ async function main() {
const gatewayMdContent = fs.readFileSync(gatewayMdPath, "utf8");
if (gatewayMdContent && gatewayMdContent.trim().length > 0) {
core.info(`Found gateway.md (${gatewayMdContent.length} bytes)`);

// Generate plain text summary for core.info
const plainTextSummary = generatePlainTextGatewaySummary(gatewayMdContent);
core.info(plainTextSummary);

// Write the markdown directly to the step summary
core.summary.addRaw(gatewayMdContent).write();
core.info("MCP gateway markdown summary added to step summary");
return;
}
} else {
Expand Down Expand Up @@ -61,16 +65,88 @@ async function main() {
return;
}

// Generate plain text summary for core.info
const plainTextSummary = generatePlainTextLegacySummary(gatewayLogContent, stderrLogContent);
core.info(plainTextSummary);

// Generate step summary for both logs
const summary = generateGatewayLogSummary(gatewayLogContent, stderrLogContent);
core.summary.addRaw(summary).write();

core.info("MCP gateway log summary added to step summary");
} catch (error) {
core.setFailed(getErrorMessage(error));
}
}

/**
* Generates a plain text summary from gateway.md content for console output
* @param {string} gatewayMdContent - The gateway.md markdown content
* @returns {string} Plain text summary for console output
*/
function generatePlainTextGatewaySummary(gatewayMdContent) {
const lines = [];

// Header
lines.push("=== MCP Gateway Logs ===");
lines.push("");

// Strip markdown formatting for plain text display
const plainText = gatewayMdContent
.replace(/<details>/g, "")
.replace(/<\/details>/g, "")
.replace(/<summary>(.*?)<\/summary>/g, "$1")
.replace(/```[\s\S]*?```/g, match => {
// Extract content from code blocks
return match.replace(/```[a-z]*\n?/g, "").replace(/```$/g, "");
})
.replace(/\*\*(.*?)\*\*/g, "$1") // Remove bold
.replace(/\*(.*?)\*/g, "$1") // Remove italic
.replace(/`(.*?)`/g, "$1") // Remove inline code
.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") // Remove links, keep text
.replace(/^#+\s+/gm, "") // Remove heading markers
.replace(/^\|-+.*-+\|$/gm, "") // Remove table separator lines
.replace(/^\|/gm, "") // Remove leading pipe from table rows
.replace(/\|$/gm, "") // Remove trailing pipe from table rows
.replace(/\s*\|\s*/g, " ") // Replace remaining pipes with spaces
.trim();

lines.push(plainText);
lines.push("");

return lines.join("\n");
}

/**
* Generates a plain text summary from legacy log files for console output
* @param {string} gatewayLogContent - The gateway.log content
* @param {string} stderrLogContent - The stderr.log content
* @returns {string} Plain text summary for console output
*/
function generatePlainTextLegacySummary(gatewayLogContent, stderrLogContent) {
const lines = [];

// Header
lines.push("=== MCP Gateway Logs ===");
lines.push("");

// Add gateway.log if it has content
if (gatewayLogContent && gatewayLogContent.trim().length > 0) {
lines.push("Gateway Log (gateway.log):");
lines.push("");
lines.push(gatewayLogContent.trim());
lines.push("");
}

// Add stderr.log if it has content
if (stderrLogContent && stderrLogContent.trim().length > 0) {
lines.push("Gateway Log (stderr.log):");
lines.push("");
lines.push(stderrLogContent.trim());
lines.push("");
}

return lines.join("\n");
}

/**
* Generates a markdown summary of MCP gateway logs
* @param {string} gatewayLogContent - The gateway.log content
Expand Down Expand Up @@ -108,6 +184,8 @@ if (typeof module !== "undefined" && module.exports) {
module.exports = {
main,
generateGatewayLogSummary,
generatePlainTextGatewaySummary,
generatePlainTextLegacySummary,
};
}

Expand Down
143 changes: 142 additions & 1 deletion actions/setup/js/parse_mcp_gateway_log.test.cjs
Original file line number Diff line number Diff line change
@@ -1,13 +1,154 @@
// @ts-check
/// <reference types="@actions/github-script" />

const { generateGatewayLogSummary } = require("./parse_mcp_gateway_log.cjs");
const { generateGatewayLogSummary, generatePlainTextGatewaySummary, generatePlainTextLegacySummary } = require("./parse_mcp_gateway_log.cjs");

describe("parse_mcp_gateway_log", () => {
// Note: The main() function now checks for gateway.md first before falling back to log files.
// If gateway.md exists, its content is written directly to the step summary.
// These tests focus on the fallback generateGatewayLogSummary function used when gateway.md is not present.

describe("generatePlainTextGatewaySummary", () => {
test("generates plain text summary from markdown content", () => {
const gatewayMdContent = `<details>
<summary>MCP Gateway Summary</summary>

**Statistics**

| Metric | Count |
|--------|-------|
| Requests | 42 |

**Details**

Some *italic* and **bold** text with \`code\`.

[Link text](http://example.com)

\`\`\`json
{"key": "value"}
\`\`\`

</details>`;

const summary = generatePlainTextGatewaySummary(gatewayMdContent);

expect(summary).toContain("=== MCP Gateway Logs ===");
expect(summary).toContain("MCP Gateway Summary");
expect(summary).toContain("Statistics");
expect(summary).toContain("Requests");
expect(summary).toContain("42");
expect(summary).toContain("Details");
expect(summary).toContain("Some italic and bold text with code");
expect(summary).toContain("Link text");
expect(summary).toContain('{"key": "value"}');

// Should not contain markdown syntax
expect(summary).not.toContain("<details>");
expect(summary).not.toContain("**bold**");
expect(summary).not.toContain("*italic*");
expect(summary).not.toContain("`code`");
expect(summary).not.toContain("[Link");
});

test("handles empty markdown content", () => {
const summary = generatePlainTextGatewaySummary("");

expect(summary).toContain("=== MCP Gateway Logs ===");
});

test("handles markdown with code blocks", () => {
const gatewayMdContent = `\`\`\`bash
echo "Hello World"
\`\`\``;

const summary = generatePlainTextGatewaySummary(gatewayMdContent);

expect(summary).toContain('echo "Hello World"');
expect(summary).not.toContain("```");
});

test("handles markdown with multiple sections", () => {
const gatewayMdContent = `# Heading 1

## Heading 2

### Heading 3

Some content here.`;

const summary = generatePlainTextGatewaySummary(gatewayMdContent);

expect(summary).toContain("Heading 1");
expect(summary).toContain("Heading 2");
expect(summary).toContain("Heading 3");
expect(summary).toContain("Some content here.");
expect(summary).not.toContain("#");
});
});

describe("generatePlainTextLegacySummary", () => {
test("generates summary with both gateway.log and stderr.log", () => {
const gatewayLogContent = "Gateway started\nServer listening on port 8080";
const stderrLogContent = "Debug: connection accepted\nDebug: request processed";

const summary = generatePlainTextLegacySummary(gatewayLogContent, stderrLogContent);

expect(summary).toContain("=== MCP Gateway Logs ===");
expect(summary).toContain("Gateway Log (gateway.log):");
expect(summary).toContain("Gateway started");
expect(summary).toContain("Server listening on port 8080");
expect(summary).toContain("Gateway Log (stderr.log):");
expect(summary).toContain("Debug: connection accepted");
expect(summary).toContain("Debug: request processed");
});

test("generates summary with only gateway.log content", () => {
const gatewayLogContent = "Gateway started\nServer ready";
const stderrLogContent = "";

const summary = generatePlainTextLegacySummary(gatewayLogContent, stderrLogContent);

expect(summary).toContain("=== MCP Gateway Logs ===");
expect(summary).toContain("Gateway Log (gateway.log):");
expect(summary).toContain("Gateway started");
expect(summary).not.toContain("Gateway Log (stderr.log):");
});

test("generates summary with only stderr.log content", () => {
const gatewayLogContent = "";
const stderrLogContent = "Error: connection failed\nRetrying...";

const summary = generatePlainTextLegacySummary(gatewayLogContent, stderrLogContent);

expect(summary).toContain("=== MCP Gateway Logs ===");
expect(summary).not.toContain("Gateway Log (gateway.log):");
expect(summary).toContain("Gateway Log (stderr.log):");
expect(summary).toContain("Error: connection failed");
});

test("handles empty log content for both files", () => {
const gatewayLogContent = "";
const stderrLogContent = "";

const summary = generatePlainTextLegacySummary(gatewayLogContent, stderrLogContent);

expect(summary).toContain("=== MCP Gateway Logs ===");
});

test("trims whitespace from log content", () => {
const gatewayLogContent = "\n\n Gateway log with whitespace \n\n";
const stderrLogContent = "\n\n Stderr log with whitespace \n\n";

const summary = generatePlainTextLegacySummary(gatewayLogContent, stderrLogContent);

expect(summary).toContain("Gateway log with whitespace");
expect(summary).toContain("Stderr log with whitespace");
expect(summary).not.toContain("\n\n Gateway log");
expect(summary).not.toContain("\n\n Stderr log");
});
});

describe("generateGatewayLogSummary", () => {
test("generates summary with both gateway.log and stderr.log", () => {
const gatewayLogContent = "Gateway started\nServer listening on port 8080";
Expand Down
Loading