feat: group changelog bugfixes (#25597)

This commit is contained in:
Shoubhit Dash
2026-05-03 19:18:26 +05:30
committed by GitHub
parent e77867ef05
commit 0a7d02c87c
2 changed files with 36 additions and 9 deletions

View File

@@ -18,9 +18,12 @@ Do not use `git log` or author metadata when deciding attribution.
Rules: Rules:
- Write the final file with sections in this order: - Write the final file with release sections in this order:
`## Core`, `## TUI`, `## Desktop`, `## SDK`, `## Extensions` `## Core`, `## TUI`, `## Desktop`, `## SDK`, `## Extensions`
- Only include sections that have at least one notable entry - Only include sections that have at least one notable entry
- Within each release section, keep bug fixes grouped under `### Bugfixes`
- Keep other notable entries under `### Improvements` when a section has bug fixes too
- Omit empty subsections
- Keep one bullet per commit you keep - Keep one bullet per commit you keep
- Skip commits that are entirely internal, CI, tests, refactors, or otherwise not user-facing - Skip commits that are entirely internal, CI, tests, refactors, or otherwise not user-facing
- Start each bullet with a capital letter - Start each bullet with a capital letter

View File

@@ -82,6 +82,11 @@ function section(areas: Set<string>) {
return "Core" return "Core"
} }
function type(message: string) {
if (message.match(/fix/i)) return "Bugfixes"
return "Improvements"
}
function reverted(commits: Commit[]) { function reverted(commits: Commit[]) {
const seen = new Map<string, Commit>() const seen = new Map<string, Commit>()
@@ -193,13 +198,20 @@ async function thanks(from: string, to: string, reuse: boolean) {
} }
function format(from: string, to: string, list: Commit[], thanks: string[]) { function format(from: string, to: string, list: Commit[], thanks: string[]) {
const grouped = new Map<string, string[]>() const grouped = new Map<string, Map<string, string[]>>()
for (const title of order) grouped.set(title, []) for (const title of order) {
grouped.set(
title,
new Map([
["Improvements", []],
["Bugfixes", []],
]),
)
}
for (const commit of list) { for (const commit of list) {
const title = section(commit.areas)
const attr = commit.author && !team.includes(commit.author) ? ` (@${commit.author})` : "" const attr = commit.author && !team.includes(commit.author) ? ` (@${commit.author})` : ""
grouped.get(title)!.push(`- \`${commit.hash}\` ${commit.message}${attr}`) grouped.get(section(commit.areas))!.get(type(commit.message))!.push(`- \`${commit.hash}\` ${commit.message}${attr}`)
} }
const lines = [`Last release: ${ref(from)}`, `Target ref: ${to}`, ""] const lines = [`Last release: ${ref(from)}`, `Target ref: ${to}`, ""]
@@ -209,11 +221,23 @@ function format(from: string, to: string, list: Commit[], thanks: string[]) {
} }
for (const title of order) { for (const title of order) {
const entries = grouped.get(title) const groups = grouped.get(title)
if (!entries || entries.length === 0) continue if (!groups || [...groups.values()].every((entries) => entries.length === 0)) continue
lines.push(`## ${title}`) lines.push(`## ${title}`)
lines.push(...entries) const improvements = groups.get("Improvements")!
lines.push("") const bugfixes = groups.get("Bugfixes")!
if (bugfixes.length === 0) {
lines.push(...improvements)
lines.push("")
continue
}
for (const [subtitle, entries] of groups) {
if (entries.length === 0) continue
lines.push(`### ${subtitle}`)
lines.push(...entries)
lines.push("")
}
} }
if (thanks.length > 0) { if (thanks.length > 0) {