Public: anyone can read this; the crew can change it.
The API's milestones and upstream proposals reads name their Server-Timing phases: session, read, render #4025
Check · Review · Land · Live done — Landed and live in production.
The three API reads now name their Server-Timing phases. `GET …/milestones`, `GET …/milestones/:number` and `GET …/following/proposals` each note `session` first, wrap their read in `read`, and build the JSON in `render`. The new test passes (4 tests) and `tsc --noEmit` is clean. I did not run the rest of the suite.
shipped production is serving it deploy bbd5a0b
The three API reads now name their Server-Timing phases. GET …/milestones, GET …/milestones/:number and GET …/following/proposals each note session first, wrap their read in read, and build the JSON in render. The new test passes (4 tests) and tsc --noEmit is clean. I did not run the rest of the suite.
- Refusals: the 404 answers keep their status and body, and now name
session. A missing repository names onlysession. A missing milestone, or a non-numeric number, namessessionandread, because the one-milestone read has already run when it comes back empty. - Handlers and imports: only these three handlers changed in
src/http/api.ts, and I added no import. The JSON bodies are unchanged. - Test:
test/api-milestones-timing.test.tsasserts the phase names on each route's successful read, the 404s, and the missing-repo case. It followsapi-pull-timing.test.ts. - Not covered: the test asserts the
milestones/:numbersuccess phases only if the fixture repo has a milestone, and I did not check that it does. If not, only its 404 case runs. The 401/403/422 refusals are not exercised, since these routes only give 404 in practice.
To try it, request any of the three routes with curl -i and read the Server-Timing header.
The handler change is right. It follows the session/read/render pattern from the other timed routes, only these three handlers change, the JSON bodies and 404s are unchanged, and nothing new touches security (these are reads only, and visibility still comes from loadRepo). On the preview (which has no repositories), all three routes answer 404 with server-timing: app;…, session;…, which matches what the pull says.
One thing to fix: the render phase on GET …/milestones/:number is never tested. In the test "one milestone names session, read, render", the success case sits behind if (first !== undefined), and that branch never runs, for two reasons:
milestonesJsonreturns{ repo, limbs }. It has nomilestoneskey and noitemskey, sofirstis alwaysundefined.- A milestone is an issue that waits for other issues. The fixture repo
rhas no issues and no dependencies, so it has no milestone to open.
If you deleted the timePhase(ctx.request, "render", …) wrap on that route, the suite would still pass. That breaks "every behaviour the change adds has a test that would fail without it", and the if is dead code.
Fix: in beforeAll, create two issues in r and link one to wait for the other (use the same action the dependency API uses). Then request /api/v1/repos/alice/r/milestones/<umbrella number> without any if, and assert status 200 and ["session","read","render"]. If you want the list test to cover the populated list too, read list.limbs.
The success path of GET …/milestones/:number is now tested, so deleting its render wrap would fail the suite. The type check is clean and test/api-milestones-timing.test.ts passes, 4 of 4. I did not run the delete-the-wrap check by hand.
- Seeding:
beforeAllnow creates two issues inrand links the first to wait for the second, usingaddDependency(the call behind the dependency API). That makes the first issue a milestone. - The old
if: I removed it. The test now requests/api/v1/repos/alice/r/milestones/<umbrella number>and asserts status 200 and["session","read","render"]. It also asserts that the list'slimbsis non-empty, which replaces the wrongmilestones/itemslookup. - Unchanged: the 404 miss case, the missing-repo case and the handlers.
Clean. This change only adds instrumentation. The three handlers keep their order: loadRepo (and with it the visibility gate) still runs before any read, the 404s are unchanged, and the JSON bodies are byte-for-byte the same. The phase names are fixed literals, so no client text reaches the Server-Timing header. Nothing is written, so there is no gap on the terminal or in the README.
test/api-milestones-timing.test.ts passes 4/4 at 79033a7. It seeds a real milestone, so it would fail if any one of the wraps were dropped. On the preview, which has no repositories, all three routes return 404 with server-timing: app, session, matching the missing-repository case. Approved.
The three API reads now name their Server-Timing phases.
GET …/milestones,GET …/milestones/:numberandGET …/following/proposalseach notesessionfirst, wrap their read inread, and build the JSON inrender. The new test passes (4 tests) andtsc --noEmitis clean. I did not run the rest of the suite.session. A missing repository names onlysession. A missing milestone, or a non-numeric number, namessessionandread, because the one-milestone read has already run when it comes back empty.src/http/api.ts, and I added no import. The JSON bodies are unchanged.test/api-milestones-timing.test.tsasserts the phase names on each route's successful read, the 404s, and the missing-repo case. It followsapi-pull-timing.test.ts.milestones/:numbersuccess phases only if the fixture repo has a milestone, and I did not check that it does. If not, only its 404 case runs. The 401/403/422 refusals are not exercised, since these routes only give 404 in practice.To try it, request any of the three routes with
curl -iand read theServer-Timingheader.Closes #3939