Public: anyone can read this; the crew can change it.

An empty changelog says one thing: when nothing has ever shipped, the 'Nothing shipped today' line is left out #8339

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/8326-an-empty-changelog-says-one-thing-when-n → main 2 commits fork 1 thread · 1 unresolved

  • Merged. scout/8326-an-empty-changelog-says-one-thing-when-n was merged into main as 9fb0d13.

Review

Sign in to review this change.
2 files changed +35 −2
src/web/pages/changelog.ts +4 −2
@@ -99,7 +99,9 @@ export const localDaysJs = /* js */ `
9999 var ref = after ? after.nextSibling : parent.firstChild;
100100 made.forEach(function (c) { parent.insertBefore(c, ref); });
101101 }
102 if (top) {
102 // An empty #shipped-today with no cards is the server saying nothing has ever shipped:
outdated

This guard changes behaviour and nothing tests it. Revert it and no test fails. Add a test for the no-cards, empty-span case. Also state in a comment why the empty span means "never shipped", so a later edit does not remove the guard.

103 // writing the count here would bring back the second empty state.
104 if (top && (cards.length || top.textContent)) {
103105 var n = (seen[today] || []).length;
104106 top.textContent = shippedToday(n, false);
105107 }
@@ -127,7 +129,7 @@ export function shippedRegion(
127129 const version =
128130 read.version !== "dev" ? (commit === null ? read.version : html`${read.version} · ${commit}`) : (commit ?? "a development build");
129131 const top = html`<p class="small muted" id="shipped-top">
130 Live: ${version}.${toLive !== undefined && toLive.version === read.version ? html` Landed to live in ${secondsWords(toLive.seconds)}.` : null} <span id="shipped-today">${shippedToday(today, zone === "UTC")}</span>
132 Live: ${version}.${toLive !== undefined && toLive.version === read.version ? html` Landed to live in ${secondsWords(toLive.seconds)}.` : null} <span id="shipped-today">${live.length === 0 ? "" : shippedToday(today, zone === "UTC")}</span>
131133 </p>`;
132134 const way =
133135 onItsWay.length === 0
test/changelog.test.ts +31
@@ -330,9 +330,40 @@ describe("the browser regroups the changelog into the reader's days", () => {
330330 expect(doc.getElementById("shipped-today")!.textContent).toBe("2 shipped today.");
331331 await window.happyDOM.close();
332332 });
333
334 test("with no cards and an empty #shipped-today the script leaves the span empty; with text or cards it writes the count", async () => {
335 const { Window } = await import("happy-dom");
336 const { localDaysJs } = await import("../src/web/pages/changelog.ts");
337 const run = (inner: string) => {
338 const window = new Window();
339 const doc = window.document as any;
340 doc.body.innerHTML = `<div id="shipped">${inner}</div>`;
341 new Function("document", localDaysJs)(doc);
342 const text = doc.getElementById("shipped-today")!.textContent;
343 void window.happyDOM.close();
344 return text;
345 };
346 expect(run('<p><span id="shipped-today"></span></p>')).toBe("");
347 expect(run('<p><span id="shipped-today">Nothing shipped today (UTC).</span></p>')).toBe("Nothing shipped today.");
348 });
333349 });
334350
335351 describe("the top line names what is running", () => {
352 test("nothing ever shipped: the shipped-today sentence is left out, its id stays", async () => {
353 const { shippedRegion } = await import("../src/web/pages/changelog.ts");
354 const out = String(shippedRegion({ live: [], onItsWay: [], version: "dev", commit: null, own: "a/forge" } as any, "all"));
355 expect(out).toContain('<span id="shipped-today"></span>');
356 expect(out).not.toContain("Nothing shipped today");
357 expect(out).toContain("Nothing has shipped yet");
358 });
359
360 test("shipped before today: the sentence still says nothing shipped today", async () => {
361 const { shippedRegion } = await import("../src/web/pages/changelog.ts");
362 const old = { repo: "a/forge", title: "Old", at: "2026-10-01T00:00:00.000Z", number: 1, sha: "a".repeat(40) };
363 const out = String(shippedRegion({ live: [old], onItsWay: [], version: "dev", commit: null, own: "a/forge" } as any, "all", new Date("2026-11-02T12:00:00Z")));
364 expect(out).toContain("Nothing shipped today (UTC).");
365 });
366
336367 const top = async (version: string, commit: string | null) => {
337368 const { shippedRegion } = await import("../src/web/pages/changelog.ts");
338369 const read = { live: [], onItsWay: [], version, commit, own: "a/forge" } as any;

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs