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
2 changes: 1 addition & 1 deletion actions/setup/js/display_file_helpers.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function displayFileContent(filePath, fileName, maxBytes = 64 * 1024) {
}

// Only show content for specific file types
const displayExtensions = [".json", ".jsonl", ".log", ".txt"];
const displayExtensions = [".json", ".jsonl", ".log", ".txt", ".md", ".yml", ".yaml", ".toml"];
const fileExtension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
const shouldDisplayContent = displayExtensions.includes(fileExtension);

Expand Down
104 changes: 98 additions & 6 deletions actions/setup/js/display_file_helpers.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -162,27 +162,27 @@ describe("display_file_helpers", () => {

test("skips content display for unsupported file extensions", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "display-test-"));
const filePath = path.join(tmpDir, "test.md");
fs.writeFileSync(filePath, "# Markdown content");
const filePath = path.join(tmpDir, "test.pdf");
fs.writeFileSync(filePath, "PDF binary content");

const mockCore = { info: vi.fn(), startGroup: vi.fn(), endGroup: vi.fn(), warning: vi.fn() };
global.core = mockCore;

try {
displayFileContent(filePath, "test.md");
displayFileContent(filePath, "test.pdf");

// Check file info was displayed
expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("test.md"));
expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("test.pdf"));
expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("bytes"));

// Check message about not displaying content
expect(mockCore.info).toHaveBeenCalledWith(" (content not displayed for .md files)");
expect(mockCore.info).toHaveBeenCalledWith(" (content not displayed for .pdf files)");

// Should not start group for unsupported file type
expect(mockCore.startGroup).not.toHaveBeenCalled();

// Content should not be displayed
expect(mockCore.info).not.toHaveBeenCalledWith("# Markdown content");
expect(mockCore.info).not.toHaveBeenCalledWith("PDF binary content");
} finally {
delete global.core;
fs.rmSync(tmpDir, { recursive: true, force: true });
Expand Down Expand Up @@ -233,6 +233,98 @@ describe("display_file_helpers", () => {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});

test("displays content for .md files", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "display-test-"));
const filePath = path.join(tmpDir, "test.md");
fs.writeFileSync(filePath, "# Markdown Title\nSome content");

const mockCore = { info: vi.fn(), startGroup: vi.fn(), endGroup: vi.fn(), warning: vi.fn() };
global.core = mockCore;

try {
displayFileContent(filePath, "test.md");

// Check group was started
expect(mockCore.startGroup).toHaveBeenCalledWith("test.md");

// Check content was displayed
expect(mockCore.info).toHaveBeenCalledWith("# Markdown Title");
expect(mockCore.info).toHaveBeenCalledWith("Some content");
} finally {
delete global.core;
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});

test("displays content for .yml files", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "display-test-"));
const filePath = path.join(tmpDir, "config.yml");
fs.writeFileSync(filePath, "key: value\nanother: item");

const mockCore = { info: vi.fn(), startGroup: vi.fn(), endGroup: vi.fn(), warning: vi.fn() };
global.core = mockCore;

try {
displayFileContent(filePath, "config.yml");

// Check group was started
expect(mockCore.startGroup).toHaveBeenCalledWith("config.yml");

// Check content was displayed
expect(mockCore.info).toHaveBeenCalledWith("key: value");
expect(mockCore.info).toHaveBeenCalledWith("another: item");
} finally {
delete global.core;
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});

test("displays content for .yaml files", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "display-test-"));
const filePath = path.join(tmpDir, "config.yaml");
fs.writeFileSync(filePath, "name: test\nversion: 1.0");

const mockCore = { info: vi.fn(), startGroup: vi.fn(), endGroup: vi.fn(), warning: vi.fn() };
global.core = mockCore;

try {
displayFileContent(filePath, "config.yaml");

// Check group was started
expect(mockCore.startGroup).toHaveBeenCalledWith("config.yaml");

// Check content was displayed
expect(mockCore.info).toHaveBeenCalledWith("name: test");
expect(mockCore.info).toHaveBeenCalledWith("version: 1.0");
} finally {
delete global.core;
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});

test("displays content for .toml files", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "display-test-"));
const filePath = path.join(tmpDir, "config.toml");
fs.writeFileSync(filePath, '[package]\nname = "test"');

const mockCore = { info: vi.fn(), startGroup: vi.fn(), endGroup: vi.fn(), warning: vi.fn() };
global.core = mockCore;

try {
displayFileContent(filePath, "config.toml");

// Check group was started
expect(mockCore.startGroup).toHaveBeenCalledWith("config.toml");

// Check content was displayed
expect(mockCore.info).toHaveBeenCalledWith("[package]");
expect(mockCore.info).toHaveBeenCalledWith('name = "test"');
} finally {
delete global.core;
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});
});

describe("displayDirectory", () => {
Expand Down
15 changes: 0 additions & 15 deletions actions/setup/js/parse_mcp_gateway_log.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,6 @@ async function main() {
if (gatewayMdContent && gatewayMdContent.trim().length > 0) {
core.info(`Found gateway.md (${gatewayMdContent.length} bytes)`);

// Read gateway.log for core.info output instead of gateway.md
if (fs.existsSync(gatewayLogPath)) {
const gatewayLogContent = fs.readFileSync(gatewayLogPath, "utf8");
if (gatewayLogContent && gatewayLogContent.trim().length > 0) {
core.info(`Found gateway.log (${gatewayLogContent.length} bytes)`);
// Generate plain text summary for core.info from gateway.log
const plainTextSummary = generatePlainTextLegacySummary(gatewayLogContent, "");
core.info(plainTextSummary);
} else {
core.info("gateway.log is empty");
}
} else {
core.info(`No gateway.log found at: ${gatewayLogPath}`);
}

// Write the markdown directly to the step summary
core.summary.addRaw(gatewayMdContent).write();
return;
Expand Down
28 changes: 9 additions & 19 deletions actions/setup/js/parse_mcp_gateway_log.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -249,22 +249,19 @@ Some content here.`;
});

describe("main function behavior", () => {
// These tests verify that when gateway.md exists, gateway.log is printed to core.info
// and gateway.md is printed to step summary
// These tests verify that when gateway.md exists, it is written to step summary
const fs = require("fs");
const path = require("path");
const os = require("os");

test("when gateway.md and gateway.log both exist, prints gateway.log to core.info", async () => {
test("when gateway.md exists, writes it to step summary without gateway.log", async () => {
// Create a temporary directory for test files
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "mcp-test-"));
const gatewayMdPath = path.join(tmpDir, "gateway.md");
const gatewayLogPath = path.join(tmpDir, "gateway.log");

try {
// Write test files
// Write test file
fs.writeFileSync(gatewayMdPath, "# Gateway Summary\n\nSome markdown content");
fs.writeFileSync(gatewayLogPath, "Gateway log line 1\nGateway log line 2");

// Mock core and fs for the test
const mockCore = {
Expand All @@ -287,17 +284,13 @@ Some content here.`;

fs.existsSync = vi.fn(filepath => {
if (filepath === "/tmp/gh-aw/mcp-logs/gateway.md") return true;
if (filepath === "/tmp/gh-aw/mcp-logs/gateway.log") return true;
return originalExistsSync(filepath);
});

fs.readFileSync = vi.fn((filepath, encoding) => {
if (filepath === "/tmp/gh-aw/mcp-logs/gateway.md") {
return fs.readFileSync(gatewayMdPath, encoding);
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fs.readFileSync mock calls fs.readFileSync(gatewayMdPath, ...) inside its own mock implementation, which will recurse indefinitely because fs.readFileSync has already been replaced. Use the saved originalReadFileSync (or another unmocked reference) to read the temp file content.

Suggested change
return fs.readFileSync(gatewayMdPath, encoding);
return originalReadFileSync(gatewayMdPath, encoding);

Copilot uses AI. Check for mistakes.
}
if (filepath === "/tmp/gh-aw/mcp-logs/gateway.log") {
return fs.readFileSync(gatewayLogPath, encoding);
}
return originalReadFileSync(filepath, encoding);
});

Expand All @@ -308,16 +301,14 @@ Some content here.`;
const { main } = require("./parse_mcp_gateway_log.cjs");
await main();

// Verify gateway.log was printed to core.info
const infoCall = mockCore.info.mock.calls.find(call => call[0].includes("Gateway log line 1"));
expect(infoCall).toBeDefined();
expect(infoCall[0]).toContain("Gateway log line 1");
expect(infoCall[0]).toContain("Gateway log line 2");

// Verify gateway.md was written to step summary
expect(mockCore.summary.addRaw).toHaveBeenCalledWith(expect.stringContaining("Gateway Summary"));
expect(mockCore.summary.write).toHaveBeenCalled();

// Verify gateway.log content was NOT printed to core.info
const infoMessages = mockCore.info.mock.calls.map(call => call[0]).join("\n");
expect(infoMessages).not.toContain("Gateway log line");

// Restore original functions
fs.existsSync = originalExistsSync;
fs.readFileSync = originalReadFileSync;
Expand Down Expand Up @@ -408,10 +399,9 @@ Some content here.`;
expect(allOutput).toContain("Gateway log content");
expect(allOutput).toContain("Error message");

// Check .md file is listed but content is not displayed
// Check .md file is listed and content IS displayed (now supported)
expect(allOutput).toContain("gateway.md");
expect(allOutput).toContain("content not displayed for .md files");
expect(allOutput).not.toContain("# Gateway Summary");
expect(allOutput).toContain("# Gateway Summary");

// Restore original functions
fs.existsSync = originalExistsSync;
Expand Down
Loading