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

GET /api/v1/repos/:owner/:name/builds/:label/shots carries an ETag and answers a repeat with 304 until a shot is added, removed or reordered #9288

Merged opened this

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

Merged

`GET /api/v1/repos/:owner/:name/builds/:label/shots` now carries a weak ETag and answers a repeat that holds it with 304. `bun x tsc --noEmit`, `scripts/gate.ts` and `test/build-shots.test.ts` (12 pass) are green here. The forge's full check hasn't run yet. I did not start the app and request the route by hand.

shipped production is serving it deploy 5a6a4f7

opened this

GET /api/v1/repos/:owner/:name/builds/:label/shots now carries a weak ETag and answers a repeat that holds it with 304. bun x tsc --noEmit, scripts/gate.ts and test/build-shots.test.ts (12 pass) are green here. The forge's full check hasn't run yet. I did not start the app and request the route by hand.

  • Tag: it is computed from the exact JSON bytes sent, using weakEtag and holds from src/http/etag.ts, the same shape as the builds list in src/http/api/builds.ts. An upload, pick, caption edit, reorder or delete changes the body, so it changes the tag.
  • Headers: the answer and the 304 both send cache-control: private, no-cache and vary: authorization, cookie, so shared caches can't keep a private repository's gallery. The security floor headers are on the 304 too.
  • Test: the new test in test/build-shots.test.ts checks that a repeat with the tag gets 304 with an empty body, and that the tag changes after an upload, a reorder and a delete (a stale tag then gets 200). I did not run it against the old code to confirm it fails there. The old route sent no ETag at all, so the W/" check would have failed.
  • Not done: GET …/shots/looks (the pickable looks list) has no tag. The issue named only the gallery route.

Closes #9276

commented

GET /api/v1/repos/:owner/:name/builds/:label/shots now carries a weak ETag and answers a repeat that holds it with 304. bun x tsc --noEmit, scripts/gate.ts and test/build-shots.test.ts (12 pass) are green here. The forge's full check hasn't run yet. I did not start the app and request the route by hand.

  • Tag: it is computed from the exact JSON bytes sent, using weakEtag and holds from src/http/etag.ts, the same shape as the builds list in src/http/api/builds.ts. An upload, pick, caption edit, reorder or delete changes the body, so it changes the tag.
  • Headers: the answer and the 304 both send cache-control: private, no-cache and vary: authorization, cookie, so shared caches can't keep a private repository's gallery. The security floor headers are on the 304 too.
  • Test: the new test in test/build-shots.test.ts checks that a repeat with the tag gets 304 with an empty body, and that the tag changes after an upload, a reorder and a delete (a stale tag then gets 200). I did not run it against the old code to confirm it fails there. The old route sent no ETag at all, so the W/" check would have failed.
  • Not done: GET …/shots/looks (the pickable looks list) has no tag. The issue named only the gallery route.
commented

GET /api/v1/repos/:owner/:name/builds/:label/shots now sends a weak ETag and answers a repeat that holds it with 304. The first push failed the gate rule that wants a "Try:" line in a commit message. I pushed a new commit that adds it, and nothing else changed. I didn't re-run the gate or the tests after that push, so the forge's check is the next confirmation. Before the first push, scripts/gate.ts was clean, tsc was clean, and test/build-shots.test.ts passed 12 of 12.

  • What changed: the tag is computed from the exact JSON sent, using weakEtag and holds from src/http/etag.ts. An upload, pick, caption edit, reorder or delete changes the body, so it changes the tag. The answer and the 304 both send cache-control: private, no-cache and vary: authorization, cookie, so shared caches can't keep a private repository's gallery. The security floor headers are on the 304 too.
  • Tests: a new test in test/build-shots.test.ts checks that a repeat with the tag gets an empty 304. It also checks that the tag changes after an upload, a reorder and a delete, and that a stale tag then gets 200. I didn't run it against the old code, which sent no ETag and would have failed the W/" check.
  • Not done: GET …/shots/looks (the pickable looks list) still has no tag. The issue named only the gallery route.
  • Try it: on the preview, request /api/v1/repos/<owner>/<name>/builds/<label>/shots with a bearer token and note the etag. Then repeat the request with if-none-match: <etag> and expect a 304.
Approved

Clean. The tag is weakEtag of the exact JSON sent, 304 uses holds(), same shape as builds.ts. cache-control private, no-cache plus vary on 200 and 304; floor headers verified in the test. Test covers repeat 304, upload, move, delete and a stale tag giving 200, and fails without the change. Small, no new dependency, no README edit. The looks route is rightly left out.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs