Skip to content

Commit f16a67f

Browse files
t3dotggclaude
andcommitted
fix(release): only generated notes use the summary layout, and partial model output is never published
Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent ed6ae26 commit f16a67f

4 files changed

Lines changed: 20 additions & 4 deletions

File tree

‎apps/desktop/src/updates/releaseNotes.test.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ describe("normalizeDesktopUpdateReleaseNotes", () => {
112112
]);
113113
});
114114

115+
it("reads handwritten notes with their own <details> as a list", () => {
116+
const result = normalizeDesktopUpdateReleaseNotes(
117+
"- Older fix\n- Newer fix\n<details><summary>Logs</summary>\n- hidden\n</details>",
118+
"1.2.3",
119+
"latest",
120+
);
121+
122+
expect(result.releaseNotes).toEqual([
123+
{ version: "1.2.3", items: ["hidden", "Logs", "Newer fix", "Older fix"], totalItems: 4 },
124+
]);
125+
});
126+
115127
it("dates the offered release from the feed and older nightlies by their build day", () => {
116128
const result = normalizeDesktopUpdateReleaseNotes(
117129
[

‎apps/desktop/src/updates/releaseNotes.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ function extractReleaseNoteSummary(summary: string): ExtractedReleaseNoteItems {
130130
function extractReleaseNoteItems(note: string | null | undefined): ExtractedReleaseNoteItems {
131131
if (!note) return { items: [], totalItems: 0 };
132132

133-
// Generated summaries fold GitHub's full list under <details>.
134-
const summaryEnd = note.search(/<details\b/i);
133+
// Generated summaries fold GitHub's full list under this exact <details> block.
134+
const summaryEnd = note.search(/<details>\s*<summary>\s*Full changelog\s*<\/summary>/i);
135135
if (summaryEnd >= 0) return extractReleaseNoteSummary(note.slice(0, summaryEnd));
136136
const items: string[] = [];
137137
let totalItems = 0;

‎apps/web/src/components/sidebar/SidebarUpdateReleaseNotes.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ export function SidebarUpdateReleaseNotes({
9696
const releaseUrl = getDesktopUpdateReleaseUrl(releaseNote.version);
9797
const omittedItemCount = Math.max(0, releaseNote.totalItems - releaseNote.items.length);
9898
const linkLabel =
99-
omittedItemCount === 0
99+
releaseNote.stats ??
100+
(omittedItemCount === 0
100101
? "View release on GitHub"
101-
: `${omittedItemCount} more ${omittedItemCount === 1 ? "change" : "changes"} on GitHub`;
102+
: `${omittedItemCount} more ${omittedItemCount === 1 ? "change" : "changes"} on GitHub`);
102103

103104
if (releaseNote.intro !== undefined) {
104105
return (

‎scripts/generate-release-notes.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const PullRequestQueryResponse = Schema.Struct({
8787
const GeneratedNotes = Schema.Struct({ body: Schema.String });
8888

8989
const SummaryResponse = Schema.Struct({
90+
status: Schema.String,
9091
output: Schema.Array(
9192
Schema.Struct({
9293
type: Schema.String,
@@ -284,6 +285,8 @@ const summarize = Effect.fn("generateReleaseNotes.summarize")(function* (input:
284285
outputTokens: response.usage?.output_tokens,
285286
}),
286287
);
288+
// An incomplete response can carry partial text; publishing it would cut the notes short.
289+
if (response.status !== "completed") return Option.none<string>();
287290
const text = response.output
288291
.flatMap((item) => item.content ?? [])
289292
.flatMap((part) => (part.type === "output_text" && part.text ? [part.text] : []))

0 commit comments

Comments
 (0)