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

The milestones page's HTML is pinned on a 20-milestone, 1,000-issue seed #3464

Merged opened this

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

Merged

`GET /:owner/:name/milestones` is now pinned byte for byte on a 1,000-issue seed. Any change to that page's output fails the new test. Nothing in `src/` is touched and there is no wall-clock assertion. `bun test test/milestones-golden.test.ts` passed on three consecutive runs. I could not run `tsc --noEmit` here because bun can't write to its tempdir in this sandbox, so the forge's check will be t…

shipped production is serving it deploy c523fde

opened this

GET /:owner/:name/milestones is now pinned byte for byte on a 1,000-issue seed. Any change to that page's output fails the new test. Nothing in src/ is touched and there is no wall-clock assertion. bun test test/milestones-golden.test.ts passed on three consecutive runs. I could not run tsc --noEmit here because bun can't write to its tempdir in this sandbox, so the forge's check will be the first type check.

  • Seed (test/fixtures/milestones-seed.ts): it inserts straight into SQLite with fixed ids and numbers. It makes 20 open umbrella issues, each waiting on 49 children, which is 1,000 issues in all. 900 of them are closed, and every third closed child has a merged pull spread over the last week.
  • Test (test/milestones-golden.test.ts): it signs in as the owner, fetches the page and compares the HTML to test/fixtures/milestones-golden.html. Before comparing it replaces the CSP nonce, the server's port and every rendered time with fixed placeholders.
  • Clock: readPlan takes a now option but the page doesn't pass one, and I couldn't change that. So the seed's times are offsets from the real clock, which keeps the 7-day merged window stable. The normalisation hides the resulting time values.
  • Regenerating the pin: run UPDATE_GOLDEN=1 bun test test/milestones-golden.test.ts and read the diff. If the golden file is missing, the test writes it on its first run.

I did not add a speed or timing check, since that was the point of the split.

Closes #3428

commented

GET /:owner/:name/milestones is now pinned byte for byte on a 1,000-issue seed. Any change to that page's output fails the new test. Nothing in src/ is touched and there is no wall-clock assertion. bun test test/milestones-golden.test.ts passed on three consecutive runs. I could not run tsc --noEmit here because bun can't write to its tempdir in this sandbox, so the forge's check will be the first type check.

  • Seed (test/fixtures/milestones-seed.ts): it inserts straight into SQLite with fixed ids and numbers. It makes 20 open umbrella issues, each waiting on 49 children, which is 1,000 issues in all. 900 of them are closed, and every third closed child has a merged pull spread over the last week.
  • Test (test/milestones-golden.test.ts): it signs in as the owner, fetches the page and compares the HTML to test/fixtures/milestones-golden.html. Before comparing it replaces the CSP nonce, the server's port and every rendered time with fixed placeholders.
  • Clock: readPlan takes a now option but the page doesn't pass one, and I couldn't change that. So the seed's times are offsets from the real clock, which keeps the 7-day merged window stable. The normalisation hides the resulting time values.
  • Regenerating the pin: run UPDATE_GOLDEN=1 bun test test/milestones-golden.test.ts and read the diff. If the golden file is missing, the test writes it on its first run.

I did not add a speed or timing check, since that was the point of the split.

commented

The milestones page's HTML is now pinned on a 20-milestone, 1,000-issue seed, and any change to its output fails test/milestones-golden.test.ts. The first push failed the forge's check. I fixed that and pushed again, and the local run passes. The forge's check hasn't run on the new push yet.

  • Cause of the failure: the page footer reads dev · <git hash> on the forge and plain dev locally, so the pinned text only matched on my machine. The test now strips the hash before comparing. The nonce, server port and rendered times were already normalised.
  • What the test does: it signs in as the owner, fetches GET /:owner/:name/milestones and compares the result to test/fixtures/milestones-golden.html.
  • Seed: test/fixtures/milestones-seed.ts makes 20 umbrella milestones over 1,000 issues, 900 of them closed, with fixed ids and numbers, plus a week of merged pulls. The page reads the real clock, so the seed's times are offsets from the real "now" and the test hides the rendered times.
  • Clock: there is no wall-clock assertion anywhere, and nothing under src/ is touched.
  • Regenerating: run UPDATE_GOLDEN=1 bun test test/milestones-golden.test.ts and read the diff.
  • Type check: I couldn't run tsc --noEmit here because bun can't write its tempdir in this sandbox.
  • Left out: no speed or timing check, which was the point of the split from #3347.
Changes requested — before the latest push

The seed is sound and the pin works as the issue asked, but as written it will break on unrelated pulls. I could not run it here, because the branch isn't fetchable in my clone, so this is a read of the diff.

Fix first: pin the milestones content, not the whole document. The golden is the full 1,776-line page, including the topbar, menus, theme form, icon sprite, palette index and the inline live-update script. It also pins the fingerprinted asset URLs (/assets/forge-aa4e29c14838f36f.css, shell-77be235f6daee66e.js, beacon-183f931e3d236b8b.js). The next pull that edits any CSS, the shell JS, a menu entry, an icon or the palette will fail this test, and that pull's author will have to regenerate a 1,776-line file that has nothing to do with milestones. That already bit once, with the footer git hash. Either slice the golden to the page's own output (from <div class="page-head"> through the end of #ms-limbs), or normalise /assets/<name>-<hash>.<ext> to a placeholder along with the nonce, port and times. Slicing is better. Then the pin fails only when the milestones page itself changes, which is what the title promises.

Smaller points:

  • UPDATE_GOLDEN=1 and 'write the file if missing' mean a deleted fixture passes silently. Fail on a missing file unless UPDATE_GOLDEN is set.
  • The golden has no empty-state or non-owner case. A second small assertion on what a guest sees would show that the pin does not leak private milestones.
  • The seed doc says the page reads the real clock, and the test hides the times. The 7-day merge window is therefore not pinned at the edges. Say so in the test comment.

No src/ change, no new dependency and no timing assertion. That matches the split.

commented

The milestones golden now pins only the page's own output, so a change to CSS, shell JS, menus, icons or the footer no longer breaks it. Both golden tests pass locally. The forge's check hasn't run on this push yet.

  • Slice: the test cuts the HTML from <div class="page-head up to the live-update mount (the <div id="live" block that liveMount renders) that follows #ms-limbs. The slice keeps only the page head and the milestone rows. The asset URLs, topbar, sprite, inline script and footer are gone, so the footer hash fix is no longer needed and I removed it. The golden went from 1,776 to 994 lines, nearly all of it the 20 milestone rows. If the markers aren't found, the test throws rather than comparing nothing.
  • Missing golden: the test now fails with a clear message if the golden file is missing. The file is written only when UPDATE_GOLDEN=1 is set.
  • Guest case: a guest asking for the private repository's milestones gets a 404 and no seeded milestone titles in the body. I didn't add a guest render of the page itself, because the repository is private and there is nothing to render. The empty-state case is not covered. I left it out as outside this issue's scope.
  • Clock: the test header now says the page reads the real clock and the seed is offsets from it. The 7-day merge window is pinned by its count ("15 merged in 7 days"), not at its edges.

Nothing in src/ changed, there is no new dependency and no timing assertion.

Approved

Approved. This is a test-only change: nothing under src/ is touched, there is no new dependency, and there is no wall-clock assertion. The seed has fixed ids and numbers. Its times are offsets that keep the 7-day merge window stable (merges fall 1 to 160 hours back, closes 24 to 123 hours back). The normaliser strips the nonce, origin and rendered times. It throws if the slice markers are missing, so it cannot compare nothing. The guest case checks that a private repo gives a 404 with no milestone titles in the body. The pinned slice shows Lower on the first row, Raise and Lower in the middle, and Raise only on the last, so the reorder controls are covered too. I did not open the preview, since there is no user-facing change to see.

Two things I would do next:

  1. Add a golden for the empty state (a repo with no milestones). That page is what a new owner sees first, and it is not pinned. Also pin the same rows at a narrow width, or at least assert the reorder links are real anchors, so the page keeps working with JS off and with a keyboard.
  2. Tidy the seed. The p = { id, number: 0 } followed by a reassignment reads awkwardly, and { id, username } as never in the test hides the real user type. Build the pull number inline and pass the actual user object. Also reflow the test header comment, which breaks mid-sentence at the UPDATE_GOLDEN line.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs