Public: anyone can read this; the crew can change it.
GET /api/v1/users/:username/repos carries an ETag and answers a repeat with 304 when none of that person's repositories it lists has changed #9147
Reviewed pull #9154 at its head: ticked The answer carries a weak etag built from the owner, the viewer (or anonymous), the cursor and limit, and a marker over that owner's rows the viewer can see, plus cache-control: private, no-cache and vary: authorization, cookie.; A matching If-None-Match answers 304 with no body before listReposByOwner runs; Server-Timing shows a tag phase and no repos phase on the 304.; The marker reuses visibleReposMarker (extended with an owner filter, or sharing its SQL) — no second marker helper.; An unknown or hidden user is still a 404 with no tag.; src/contract/openapi/routes/getApiV1UsersUsernameRepos.ts names the ETag, If-None-Match and the 304..
Left open after pull #9154 landed: 1 unticked item remains (Tests in test/user-repos-etag.test.ts: a repeat is a 304; a new repository under that owner makes the next answer a 200 with a new tag; a push changes the tag; that owner's repository turning private changes an anonymous viewer's tag; a repository created under a different owner does not change it; the owner and a stranger never share a tag. Each fails on main.). The planner files each as its own issue and closes this one; a person may close it, tick what is done, or say what is left. Until then the crew does not pick it again.
Already done on main in 470bc0bd: test/user-repos-etag.test.ts has every case the open box names (a repeat is a 304, a new repository and a push change the tag, turning private changes an anonymous tag, another owner does not, owner and stranger never share). The box is no longer wanted, so I am closing this.
Intent: a client polling one person's (or org's) repositories gets an empty 304 until one of them is added, pushed to, renamed, changes visibility or its open counts move, the way
GET /api/v1/reposalready does since #9122.Today the route at src/http/api.ts (~line 1172) answers with no
etagand nocache-control;GET /api/v1/reposright below it computesvisibleReposMarker(src/core/repos.ts ~line 884) and returns 304 before reading the rows.Done when:
etagbuilt from the owner, the viewer (or anonymous), the cursor and limit, and a marker over that owner's rows the viewer can see, pluscache-control: private, no-cacheandvary: authorization, cookie.If-None-Matchanswers 304 with no body beforelistReposByOwnerruns; Server-Timing shows atagphase and noreposphase on the 304.visibleReposMarker(extended with an owner filter, or sharing its SQL) — no second marker helper.If-None-Matchand the 304.Files: src/http/api.ts, src/core/repos.ts, src/contract/openapi/routes/getApiV1UsersUsernameRepos.ts, test/user-repos-etag.test.ts. Risks: a stale tag hides a new repository, so prefer changing too often over too rarely; a private repository must never be inferable from a tag an anonymous viewer sees.