Files
PowerToys/tools/mcp/github-artifacts/test-github_issue_attachments.js
Gordon Lam 5422bc31bb docs(prompts): Enhance release notes generation and implement GitHub issue tools (#44762)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This update improves the release notes generation process by
restructuring documentation for clarity and enhancing workflows. It
introduces new tools for handling GitHub issue images and attachments,
along with automated tests to ensure functionality.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] Closes: N/A
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [x] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: N/A

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
The changes include updates to the release notes summarization process
and workflow documentation for better clarity. New scripts for managing
PR diffs, grouping, and milestone assignments have been added.
Additionally, tools for downloading images and attachments from GitHub
issues have been implemented, ensuring a more streamlined process.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Automated tests were added for the new GitHub issue tools, and all tests
passed successfully. Manual validation included testing the new
workflows and ensuring the documentation accurately reflects the changes
made.
```
2026-01-21 16:18:57 +08:00

142 lines
4.0 KiB
JavaScript

// Test script for github_issue_attachments tool
// Run with: node test-github_issue_attachments.js
// Make sure GITHUB_TOKEN is set in environment
import { spawn } from "child_process";
import fs from "fs/promises";
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const extractFolder = path.join(__dirname, "test-extracts");
const server = spawn("node", ["server.js"], {
stdio: ["pipe", "pipe", "inherit"],
env: { ...process.env }
});
// Send initialize request
const initRequest = {
jsonrpc: "2.0",
id: 1,
method: "initialize",
params: {
protocolVersion: "2024-11-05",
capabilities: {},
clientInfo: { name: "test-client", version: "1.0.0" }
}
};
server.stdin.write(JSON.stringify(initRequest) + "\n");
// Send list tools request
setTimeout(() => {
const listToolsRequest = {
jsonrpc: "2.0",
id: 2,
method: "tools/list",
params: {}
};
server.stdin.write(JSON.stringify(listToolsRequest) + "\n");
}, 500);
// Send call tool request - test with PowerToys issue that has ZIP attachments
setTimeout(() => {
const callToolRequest = {
jsonrpc: "2.0",
id: 3,
method: "tools/call",
params: {
name: "github_issue_attachments",
arguments: {
owner: "microsoft",
repo: "PowerToys",
issueNumber: 39476, // Has PowerToysReport_*.zip attachment
extractFolder: extractFolder,
maxFiles: 20
}
}
};
server.stdin.write(JSON.stringify(callToolRequest) + "\n");
}, 1000);
// Track summary
let summary = { zips: 0, files: 0, extractPath: "" };
let buffer = "";
// Read responses
server.stdout.on("data", (data) => {
buffer += data.toString();
// Try to parse complete JSON objects from buffer
const lines = buffer.split("\n");
buffer = lines.pop() || ""; // Keep incomplete line in buffer
for (const line of lines) {
if (!line.trim()) continue;
try {
const response = JSON.parse(line);
console.log("\n=== Response ===");
console.log("ID:", response.id);
if (response.result?.tools) {
console.log("Tools:", response.result.tools.map(t => t.name));
} else if (response.result?.content) {
for (const item of response.result.content) {
if (item.type === "text") {
// Truncate long file contents for display
const text = item.text;
if (text.startsWith("---") && text.length > 500) {
console.log(text.substring(0, 500) + "\n... [truncated]");
} else {
console.log(text);
}
// Track stats
if (text.includes("ZIP attachment")) {
const match = text.match(/Found (\d+) ZIP/);
if (match) summary.zips = parseInt(match[1]);
}
if (text.includes("extracted to:")) {
summary.extractPath = text.match(/extracted to: (.+)/)?.[1] || "";
}
if (text.includes("Files:")) {
summary.files = (text.match(/ /g) || []).length;
}
}
}
} else {
console.log("Result:", JSON.stringify(response.result, null, 2));
}
} catch (e) {
// Likely incomplete JSON, will be in next chunk
}
}
});
// Exit after 60 seconds (ZIP download may take time)
setTimeout(() => {
console.log("\n" + "=".repeat(50));
console.log("=== Test Summary ===");
console.log("=".repeat(50));
console.log(`ZIP files found: ${summary.zips}`);
console.log(`Files extracted: ${summary.files}`);
if (summary.extractPath) {
console.log(`Extract location: ${summary.extractPath}`);
}
console.log("=".repeat(50));
console.log("Cleaning up extracted files...");
fs.rm(extractFolder, { recursive: true, force: true })
.then(() => {
console.log("Cleanup done.");
})
.catch((err) => {
console.log(`Cleanup failed: ${err.message}`);
})
.finally(() => {
console.log("Test complete!");
server.kill();
process.exit(0);
});
}, 60000);