Skip to content

Commit 5e335dc

Browse files
Copilotanupriya13
andcommitted
Improve commit summaries by extracting release notes from PR descriptions
Co-authored-by: anupriya13 <[email protected]>
1 parent 76db37e commit 5e335dc

File tree

1 file changed

+67
-3
lines changed

1 file changed

+67
-3
lines changed

packages/@rnw-scripts/generate-release-notes/generate-release-notes.js

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,53 @@ function filterCommitsByDate(commits) {
105105
});
106106
}
107107

108-
function categorizeCommits(commits) {
108+
function extractPRNumber(commitMessage) {
109+
// Extract PR number from commit message like "(#14813)"
110+
const match = commitMessage.match(/\(#(\d+)\)/);
111+
return match ? parseInt(match[1]) : null;
112+
}
113+
114+
async function fetchPRDetails(prNumber) {
115+
if (!prNumber) return null;
116+
117+
try {
118+
const url = `https://api.github.com/repos/${REPO}/pulls/${prNumber}`;
119+
const res = await fetch(url, { headers: HEADERS });
120+
121+
if (!res.ok) {
122+
console.warn(`Failed to fetch PR #${prNumber}: ${res.status}`);
123+
return null;
124+
}
125+
126+
return await res.json();
127+
} catch (error) {
128+
console.warn(`Error fetching PR #${prNumber}:`, error.message);
129+
return null;
130+
}
131+
}
132+
133+
function extractReleaseNotesSummary(prDescription) {
134+
if (!prDescription) return null;
135+
136+
// Look for the release notes summary marker
137+
const marker = 'Add a brief summary of the change to use in the release notes for the next release.';
138+
const markerIndex = prDescription.indexOf(marker);
139+
140+
if (markerIndex === -1) return null;
141+
142+
// Get text after the marker
143+
const afterMarker = prDescription.substring(markerIndex + marker.length);
144+
145+
// Extract the next line or paragraph after the marker
146+
const lines = afterMarker.split('\n').map(line => line.trim()).filter(line => line.length > 0);
147+
148+
if (lines.length === 0) return null;
149+
150+
// Return the first non-empty line after the marker
151+
return lines[0];
152+
}
153+
154+
async function categorizeCommits(commits) {
109155
// TODO: Update logic for commits categorisation, refer 'All Commits' section for all the commits.
110156
const categories = {
111157
'All Commits': [],
@@ -147,7 +193,25 @@ function categorizeCommits(commits) {
147193
const lowerMsg = msg.toLowerCase();
148194
const sha = c.sha.slice(0, 7);
149195
const url = c.html_url;
150-
const entry = `- ${msg.split('\n')[0]} [${msg.split('\n')[0]} · ${REPO}@${sha} (github.com)](${url})`;
196+
const commitTitle = msg.split('\n')[0];
197+
198+
// Try to get a better summary from PR description
199+
const prNumber = extractPRNumber(commitTitle);
200+
let summary = commitTitle;
201+
202+
if (prNumber) {
203+
console.log(`Fetching PR details for #${prNumber}...`);
204+
const prDetails = await fetchPRDetails(prNumber);
205+
if (prDetails) {
206+
const releaseNotesSummary = extractReleaseNotesSummary(prDetails.body);
207+
if (releaseNotesSummary) {
208+
summary = releaseNotesSummary;
209+
console.log(`Found release notes summary for PR #${prNumber}: ${summary}`);
210+
}
211+
}
212+
}
213+
214+
const entry = `- ${summary} [${commitTitle} · ${REPO}@${sha} (github.com)](${url})`;
151215

152216
const matched = Object.keys(keywords).filter((k) =>
153217
keywords[k].some((word) => lowerMsg.includes(word))
@@ -198,7 +262,7 @@ function generateReleaseNotes(commits, categories) {
198262
async function main() {
199263
const commits = await fetchCommits();
200264
const filtered = filterCommitsByDate(commits);
201-
const categories = categorizeCommits(filtered);
265+
const categories = await categorizeCommits(filtered);
202266
const notes = generateReleaseNotes(filtered, categories);
203267
fs.writeFileSync('release_notes.md', notes, 'utf8');
204268
}

0 commit comments

Comments
 (0)