From eea86254b57592260b1aeb5bfe9f5641701f79b3 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste THERY Date: Sat, 18 Jul 2026 21:48:06 +0700 Subject: [PATCH] fix(release): preserve wrapped release notes Release highlights: - keep public release notes complete when Conventional Commit bullets wrap Release details: - **Release automation:** join indented bullet continuations before generating the curated GitHub release body - **Repository rules:** document the line-length-safe release note convention Verification: - pass pnpm validate after confirming the isolated retention test - prove wrapped detail and verification bullets remain complete in release notes --- AGENTS.md | 4 +++- CLAUDE.md | 4 +++- scripts/semantic-release-notes.mjs | 11 ++++++++++- scripts/semantic-release-smoke.mjs | 14 ++++++++++++-- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index bffbda7..8a4efc3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -58,7 +58,9 @@ sections with at least one bullet each: `Release highlights:`, `Release details:`, and `Verification:`. Highlights state user outcomes, details group the meaningful work by product area, and verification names the gates actually run. Never reduce a release to a generic subject - line or raw commit list. + line or raw commit list. Keep commit body lines within Commitlint's 100-character limit. When a + release bullet wraps, indent every continuation line by at least two spaces; the release notes + generator joins those lines into one complete public bullet. ## Code conventions diff --git a/CLAUDE.md b/CLAUDE.md index 6912532..058ba85 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,9 @@ Every commit promoted to `main` that can trigger semantic-release must include t sections with at least one bullet each: `Release highlights:`, `Release details:`, and `Verification:`. Highlights state user outcomes, details group meaningful work by product area, and verification names the gates actually run. Never reduce a release to a generic subject line or -raw commit list. +raw commit list. Keep commit body lines within Commitlint's 100-character limit. When a release +bullet wraps, indent every continuation line by at least two spaces; the release notes generator +joins those lines into one complete public bullet. ## Boundaries diff --git a/scripts/semantic-release-notes.mjs b/scripts/semantic-release-notes.mjs index 62af565..617f6d1 100644 --- a/scripts/semantic-release-notes.mjs +++ b/scripts/semantic-release-notes.mjs @@ -71,7 +71,16 @@ function parseSections(message) { activeSection = SECTION_LABELS[label] continue } - if (activeSection && /^-\s+\S/u.test(line)) sections[activeSection].push(line.trim()) + if (!activeSection) continue + if (/^-\s+\S/u.test(line)) { + sections[activeSection].push(line.trim()) + continue + } + if (/^\s{2,}\S/u.test(line)) { + const entries = sections[activeSection] + const entryIndex = entries.length - 1 + if (entryIndex >= 0) entries[entryIndex] = `${entries[entryIndex]} ${line.trim()}` + } } return Object.values(sections).every((entries) => entries.length > 0) ? sections : null diff --git a/scripts/semantic-release-smoke.mjs b/scripts/semantic-release-smoke.mjs index 9fb5e15..5536981 100644 --- a/scripts/semantic-release-smoke.mjs +++ b/scripts/semantic-release-smoke.mjs @@ -42,11 +42,13 @@ Release highlights: - make the public documentation easier to scan without losing technical depth Release details: -- **Documentation:** shorten every README and link advanced behavior to focused guides +- **Documentation:** shorten every README and link advanced behavior to + focused guides without losing the complete public context - **Landing:** replace the repeated hero copy with one clear product statement Verification: -- pass the complete pnpm validate release gate`, +- pass the complete pnpm validate release gate and preserve wrapped + verification evidence`, }, ], lastRelease: { gitTag: "v0.0.0" }, @@ -65,6 +67,14 @@ for (const expectedHeading of [ } assert.match(generatedNotes, /Documentation/u) assert.match(generatedNotes, /Landing/u) +assert.match( + generatedNotes, + /link advanced behavior to focused guides without losing the complete public context/u, +) +assert.match( + generatedNotes, + /pass the complete pnpm validate release gate and preserve wrapped verification evidence/u, +) assert.throws( () => verifyRelease({}, { commits: [{ message: "fix(core): terse release" }] }), /Release commits must contain/u,