fix(changelog): renderizar parágrafo de resumo por versão

Parser ignorava texto livre entre o cabeçalho ## [versão] e a primeira
seção ###. Adicionado campo `summary` em ChangelogVersion e captura das
linhas de texto antes da primeira seção. ChangelogTab renderiza o resumo
logo abaixo do cabeçalho, antes das entradas técnicas.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-04-20 17:55:09 +00:00
parent ae9dd364c4
commit 6391f07eb6
2 changed files with 17 additions and 0 deletions

View File

@@ -38,6 +38,11 @@ export function ChangelogTab({ versions }: { versions: ChangelogVersion[] }) {
</span>
</div>
<div className="space-y-4 w-full mx-auto sm:w-3/4">
{version.summary && (
<p className="text-sm text-muted-foreground leading-relaxed">
{version.summary}
</p>
)}
{version.sections.map((section) => (
<div key={section.type}>
<Badge

View File

@@ -9,6 +9,7 @@ export type ChangelogSection = {
export type ChangelogVersion = {
version: string;
date: string;
summary?: string;
sections: ChangelogSection[];
/** Linha de contribuições/autor (pode conter markdown, ex: [Nome](url)) */
contributor?: string;
@@ -22,6 +23,7 @@ export function parseChangelog(): ChangelogVersion[] {
const versions: ChangelogVersion[] = [];
let currentVersion: ChangelogVersion | null = null;
let currentSection: ChangelogSection | null = null;
let summaryLines: string[] = [];
for (const line of lines) {
const versionMatch = line.match(/^## \[(.+?)\] - (.+)$/);
@@ -37,11 +39,16 @@ export function parseChangelog(): ChangelogVersion[] {
};
versions.push(currentVersion);
currentSection = null;
summaryLines = [];
continue;
}
const sectionMatch = line.match(/^### (.+)$/);
if (sectionMatch && currentVersion) {
if (summaryLines.length > 0) {
currentVersion.summary = summaryLines.join(" ").trim();
summaryLines = [];
}
if (currentSection) {
currentVersion.sections.push(currentSection);
}
@@ -55,6 +62,11 @@ export function parseChangelog(): ChangelogVersion[] {
continue;
}
if (currentVersion && !currentSection && line.trim()) {
summaryLines.push(line.trim());
continue;
}
// **Contribuições:** ou **Autor:** com texto/link opcional
const contributorMatch = line.match(
/^\*\*(?:Contribuições|Autor):\*\*\s*(.+)$/,