diff --git a/.github/scripts/generate-announcement.js b/.github/scripts/generate-announcement.js index 3b28f6373..2cb36ae95 100644 --- a/.github/scripts/generate-announcement.js +++ b/.github/scripts/generate-announcement.js @@ -1,4 +1,5 @@ const fs = require("fs"); +const { execFileSync } = require("child_process"); // ====================================================== // Configuration @@ -13,6 +14,12 @@ const event = JSON.parse( const owner = event.repository.owner.login; const repo = event.repository.name; +// ====================================================== +// GitHub API +// ====================================================== + +const API = `https://api.github.com/repos/${owner}/${repo}`; + const headers = { Authorization: `Bearer ${token}`, Accept: "application/vnd.github+json" @@ -37,7 +44,95 @@ async function githubGet(url) { } return response.json(); +} + +// ====================================================== +// Copilot Summarization +// ====================================================== + +function summarizePR(pr) { + + const changes = pr.files + .map(file => { + return `File: ${file.filename} +Status: ${file.status} +Changes: +${file.patch || "No patch available."}`; + }) + .join("\n\n"); + + const prompt = ` +You are writing a weekly developer announcement for Shopware developers. + +Analyze this merged documentation PR. + +PR title: +${pr.title} + +PR description: +${pr.body || "No description provided."} + +Changed files: +${changes} + +Write a concise, developer-focused summary. + +Focus on: +- What changed +- What developers need to know +- Why the change matters to developers +- Any API, CLI, migration, compatibility, configuration, or workflow impact + +Rules: +- Write 2-3 sentences only. +- Do not mention the PR number. +- Do not mention that you are an AI. +- Do not reproduce the PR checklist. +- Do not reproduce links or HTML comments. +- Do not simply repeat the PR description. +- Focus on the actual developer impact. +`; + + try { + + const summary = execFileSync( + "copilot", + [ + "-p", + prompt, + "-s", + "--no-ask-user" + ], + { + encoding: "utf8", + maxBuffer: 1024 * 1024 + } + ); + return summary.trim(); + + } catch (error) { + + console.error( + `Copilot summarization failed for PR #${pr.number}:`, + error.message + ); + + // Fallback + if (!pr.body || pr.body.trim() === "") { + return pr.title; + } + + const summaryMatch = pr.body.match( + /## Summary\s*([\s\S]*?)(?=\n## |\n---|$)/i + ); + + if (summaryMatch) { + return summaryMatch[1].trim(); + } + + return pr.body.split("\n")[0].trim(); + } } // ====================================================== @@ -83,11 +178,11 @@ async function githubGet(url) { const prNumber = item.number; const pr = await githubGet( - `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}` + `${API}/pulls/${prNumber}` ); const files = await githubGet( - `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files` + `${API}/pulls/${prNumber}/files` ); announcementPRs.push({ @@ -115,17 +210,48 @@ async function githubGet(url) { } //-------------------------------------------------- - // Print collected data + // Build Weekly Announcement + //-------------------------------------------------- + + let markdown = "# Weekly Developer Announcement\n\n"; + + for (const pr of announcementPRs) { + + console.log( + `Generating AI summary for PR #${pr.number}...` + ); + + const summary = summarizePR(pr); + + markdown += `## ${pr.title}\n\n`; + + markdown += `${summary}\n\n`; + + markdown += "---\n\n"; + + } + + //-------------------------------------------------- + // Print announcement //-------------------------------------------------- console.log(""); + console.log(markdown); + + //-------------------------------------------------- + // Create downloadable file + //-------------------------------------------------- - console.log( - JSON.stringify( - announcementPRs, - null, - 2 - ) + fs.writeFileSync( + "announcement.md", + markdown, + "utf8" ); -})(); + console.log(""); + console.log("=========================================="); + console.log("Announcement file generated successfully"); + console.log("=========================================="); + console.log("File: announcement.md"); + +})(); \ No newline at end of file diff --git a/.github/workflows/weekly-developer-announcement.yml b/.github/workflows/weekly-developer-announcement.yml index a9faf365a..749386d5b 100644 --- a/.github/workflows/weekly-developer-announcement.yml +++ b/.github/workflows/weekly-developer-announcement.yml @@ -4,8 +4,9 @@ on: workflow_dispatch: permissions: - contents: write - pull-requests: write + contents: read + pull-requests: read + copilot-requests: write jobs: generate: @@ -20,7 +21,24 @@ jobs: with: node-version: 20 + - name: Setup Copilot CLI + run: npm install -g @github/copilot + - name: Generate Weekly Announcement env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: node .github/scripts/generate-announcement.js \ No newline at end of file + run: node .github/scripts/generate-announcement.js + + - name: Verify announcement file + run: | + echo "Checking generated file..." + ls -la announcement.md + echo "File size:" + wc -c announcement.md + + - name: Upload Announcement + uses: actions/upload-artifact@v4 + with: + name: weekly-developer-announcement + path: announcement.md + if-no-files-found: error \ No newline at end of file