draft-release: framing-intro line-breaks render as hard breaks in release body #54

Closed
opened 2026-06-25 01:22:41 +02:00 by quartermaster · 0 comments

Symptom

Release headers/bodies show hard line breaks where the CHANGELOG framing intro paragraphs were soft-wrapped. Operator has had to remove them manually on multiple cuts (v0.3.3, v0.3.4 confirmed). "Again" pattern → recurring footgun.

Root cause

scripts/draft-release.sh extracts the CHANGELOG section via changelog_get_section_content and posts it verbatim as the release body. The framing intro paragraphs in our CHANGELOG style are hard-wrapped at ~70 chars per line (markdown convention for source readability) — single newlines within a paragraph.

Forgejo's release-body markdown renderer treats single newlines as hard breaks (GitHub-Flavored Markdown behavior — line break preservation), not as soft-wrap-to-space. So the source:

The auto-fire of `release-draft` on prep-PR merge has been retired:
`release-draft` is now **operator-dispatched only** via
`workflow_dispatch` with an explicit `tag` input.

renders with three visible line breaks instead of as one wrapped paragraph.

Two fix dispositions

(A) Author-side discipline — stop hard-wrapping paragraphs in CHANGELOG. Write framing intros as single long lines, accept ugly source for clean output. Trade-off: CHANGELOG source becomes harder to read in editors that don't soft-wrap, but renders cleanly everywhere.

(B) Toolkit-side normalizationdraft-release.sh or changelog_get_section_content unwraps single newlines (= treat as space) and preserves double newlines (= paragraph break) before posting to the Forgejo API. Standard Markdown reflow. Trade-off: introduces a normalization step that has to handle edge cases (code blocks, lists, etc.).

(B) is the substrate-honest fix — it doesn't ask consumers to remember a wrap-discipline. (A) is the quick patch.

Acceptance criteria

  • Disposition picked (A vs B) — disposition (B) picked; landed as awk-based paragraph normalizer in scripts/draft-release.sh at commit 232ca39 (v0.6.2 substrate sweep, closes #54).
  • If (B): unwrap logic preserves code fences, lists, blockquotes — doesn't reflow inside them — verified: the awk block in draft-release.sh (lines ~130–165 on forgejo/main) tracks in_fence for ``` toggles, and skips join for structural markdown (headings #, list items -/*/+/N., blockquotes >, tables |, hr ---).
  • Tested against v0.3.3 + v0.3.4 CHANGELOG sections: produces clean wrapping in Forgejo release UI — bats coverage folded at commit 2d6d1e6 ("fold(Surveyor 2c1e): #54 test coverage") adding 3 tests to tests/draft-release.bats, incl. wrapped-paragraph-joined asserting hard-wrapped paragraphs join to single-line + list items NOT joined into prev paragraph.
  • Future cuts don't require manual line-break removal — empirically clean across ~27 cuts from v0.6.2 (first cut post-fix, 2026-06-26) through v0.33.0 (2026-07-24); no operator-reported recurrences.

Refs

Surfaced by operator on v0.3.4 cut, 2026-06-25. Recurring (v0.3.3 confirmed; older cuts likely too).


AC-hygiene sweep 2026-07-24 (Quartermaster; per Bosun 3f6b dispatch): all 4 ACs substrate-verified as done-not-ticked → ticked with evidence pointers.

## Symptom Release headers/bodies show hard line breaks where the CHANGELOG framing intro paragraphs were soft-wrapped. Operator has had to remove them manually on multiple cuts (v0.3.3, v0.3.4 confirmed). "Again" pattern → recurring footgun. ## Root cause `scripts/draft-release.sh` extracts the CHANGELOG section via `changelog_get_section_content` and posts it verbatim as the release body. The framing intro paragraphs in our CHANGELOG style are **hard-wrapped at ~70 chars per line** (markdown convention for source readability) — single newlines within a paragraph. Forgejo's release-body markdown renderer treats single newlines as hard breaks (GitHub-Flavored Markdown behavior — line break preservation), not as soft-wrap-to-space. So the source: ``` The auto-fire of `release-draft` on prep-PR merge has been retired: `release-draft` is now **operator-dispatched only** via `workflow_dispatch` with an explicit `tag` input. ``` renders with three visible line breaks instead of as one wrapped paragraph. ## Two fix dispositions **(A) Author-side discipline** — stop hard-wrapping paragraphs in CHANGELOG. Write framing intros as single long lines, accept ugly source for clean output. Trade-off: CHANGELOG source becomes harder to read in editors that don't soft-wrap, but renders cleanly everywhere. **(B) Toolkit-side normalization** — `draft-release.sh` or `changelog_get_section_content` unwraps single newlines (= treat as space) and preserves double newlines (= paragraph break) before posting to the Forgejo API. Standard Markdown reflow. Trade-off: introduces a normalization step that has to handle edge cases (code blocks, lists, etc.). (B) is the substrate-honest fix — it doesn't ask consumers to remember a wrap-discipline. (A) is the quick patch. ## Acceptance criteria - [x] Disposition picked (A vs B) — disposition (B) picked; landed as awk-based paragraph normalizer in `scripts/draft-release.sh` at commit `232ca39` (v0.6.2 substrate sweep, closes #54). - [x] If (B): unwrap logic preserves code fences, lists, blockquotes — doesn't reflow inside them — verified: the awk block in `draft-release.sh` (lines ~130–165 on `forgejo/main`) tracks `in_fence` for `` ``` `` toggles, and skips join for structural markdown (headings `#`, list items `-`/`*`/`+`/`N.`, blockquotes `>`, tables `|`, hr `---`). - [x] Tested against v0.3.3 + v0.3.4 CHANGELOG sections: produces clean wrapping in Forgejo release UI — bats coverage folded at commit `2d6d1e6` ("fold(Surveyor 2c1e): #54 test coverage") adding 3 tests to `tests/draft-release.bats`, incl. `wrapped-paragraph-joined` asserting hard-wrapped paragraphs join to single-line + list items NOT joined into prev paragraph. - [x] Future cuts don't require manual line-break removal — empirically clean across ~27 cuts from v0.6.2 (first cut post-fix, 2026-06-26) through v0.33.0 (2026-07-24); no operator-reported recurrences. ## Refs Surfaced by operator on v0.3.4 cut, 2026-06-25. Recurring (v0.3.3 confirmed; older cuts likely too). --- _AC-hygiene sweep 2026-07-24 (Quartermaster; per Bosun 3f6b dispatch): all 4 ACs substrate-verified as done-not-ticked → ticked with evidence pointers._
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#54
No description provided.