Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #55 +/- ##
==========================================
+ Coverage 91.35% 91.40% +0.04%
==========================================
Files 22 23 +1
Lines 4791 4814 +23
==========================================
+ Hits 4377 4400 +23
Misses 382 382
Partials 32 32 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
/p2/{vendor}/{file} route/p2/{vendor}/{file} route
/p2/{vendor}/{file} routeGET /p2/{vendor}/{file} route
There was a problem hiding this comment.
Pull request overview
Adds Composer/Packagist-style p2 endpoints for per-package security advisory discovery and enables Composer to use them via packages.json metadata.
Changes:
- Add
GET /p2/{vendor}/{file}route andhandleP2handler to serve stable*.jsonresponses and 404 dev*~dev.json. - Enable
"security-advisories.metadata": trueininternal/server/static/packages.jsonso Composer clients query/p2/endpoints. - Add/update OpenSpec specs + archived change docs describing the new behavior and verification steps.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| openspec/specs/server-p2/spec.md | New spec describing stable/dev p2 endpoint behavior and packages.json metadata requirement. |
| openspec/config.yaml | Adds OpenSpec config scaffold for spec-driven artifacts. |
| openspec/changes/archive/2026-04-02-add-p2-route/tasks.md | Checklist of implementation steps and verification commands. |
| openspec/changes/archive/2026-04-02-add-p2-route/specs/p2-package-metadata/spec.md | Archived spec copy for the change. |
| openspec/changes/archive/2026-04-02-add-p2-route/proposal.md | Archived proposal describing endpoints and packages.json flag change. |
| openspec/changes/archive/2026-04-02-add-p2-route/design.md | Archived design detailing ServeMux routing approach and response format. |
| openspec/changes/archive/2026-04-02-add-p2-route/.openspec.yaml | OpenSpec change metadata. |
| internal/server/static/packages.json | Flips security-advisories.metadata to true to activate p2 advisory lookups. |
| internal/server/routes.go | Registers the new GET /p2/{vendor}/{file} route. |
| internal/server/handle_p2.go | Implements p2 handler (stable .json served, ~dev.json 404). |
| internal/server/handle_p2_test.go | Updates/adds tests for stable/dev and known/unknown package cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| srv := newTestServerWithData(tt.data) | ||
| req := httptest.NewRequest(http.MethodGet, tt.path, http.NoBody) | ||
| rec := httptest.NewRecorder() | ||
|
|
||
| srv := newTestServer() | ||
| req := httptest.NewRequest(method, tt.path, http.NoBody) | ||
| rec := httptest.NewRecorder() | ||
| srv.ServeHTTP(rec, req) | ||
|
|
||
| srv.ServeHTTP(rec, req) | ||
| if rec.Code != tt.wantCode { | ||
| t.Errorf("status = %d, want %d", rec.Code, tt.wantCode) | ||
| } | ||
|
|
There was a problem hiding this comment.
The p2 tests no longer assert the Cache-Control: max-age=86400 header, even though the spec requires it for both stable and dev paths and other server tests verify Cache-Control behavior. Consider re-adding the Cache-Control assertion here to prevent regressions in caching semantics.
| mux.HandleFunc("GET /api/security-advisories/{$}", withCacheControl("max-age=3600")(m(hAdvs))) | ||
| mux.HandleFunc("POST /api/security-advisories/{$}", withCacheControl("max-age=3600")(hAdvs)) | ||
|
|
||
| mux.HandleFunc("GET /p2/{vendor}/{file}", handleP2(store)) |
There was a problem hiding this comment.
addRoutes sets up m := withConditionalGet(modTime) and applies it to other GET endpoints (/api/security-advisories/ and static files), but the new /p2/ GET route isn't wrapped. This means no Last-Modified header and no If-Modified-Since short-circuit for p2 responses, which can increase bandwidth and is inconsistent with other cacheable GET routes. Consider registering this route as m(handleP2(store)) (and/or through the same wrapper pattern used elsewhere).
| mux.HandleFunc("GET /p2/{vendor}/{file}", handleP2(store)) | |
| mux.HandleFunc("GET /p2/{vendor}/{file}", m(handleP2(store))) |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| srv.ServeHTTP(rec, req) | ||
|
|
||
| srv.ServeHTTP(rec, req) | ||
| if rec.Code != tt.wantCode { | ||
| t.Errorf("status = %d, want %d", rec.Code, tt.wantCode) | ||
| } | ||
|
|
||
| if rec.Code != http.StatusNotFound { | ||
| t.Errorf("status code = %d, want %d", rec.Code, http.StatusNotFound) | ||
| } | ||
| gotCT := rec.Header().Get("Content-Type") | ||
| if tt.wantCT != "" && gotCT != tt.wantCT { | ||
| t.Errorf("Content-Type = %q, want %q", gotCT, tt.wantCT) | ||
| } |
There was a problem hiding this comment.
handle_p2_test.go no longer asserts the Cache-Control: max-age=86400 header for the new /p2/ endpoints, even though the spec explicitly requires it for both stable and ~dev paths. Please add an assertion (at least for one 200 case and one 404 case) so a future middleware/route change can’t silently drop the required caching header.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| srv.ServeHTTP(rec, req) | ||
|
|
||
| srv.ServeHTTP(rec, req) | ||
| if rec.Code != tt.wantCode { | ||
| t.Errorf("status = %d, want %d", rec.Code, tt.wantCode) | ||
| } | ||
|
|
||
| if rec.Code != http.StatusNotFound { | ||
| t.Errorf("status code = %d, want %d", rec.Code, http.StatusNotFound) | ||
| } | ||
| gotCT := rec.Header().Get("Content-Type") | ||
| if tt.wantCT != "" && gotCT != tt.wantCT { | ||
| t.Errorf("Content-Type = %q, want %q", gotCT, tt.wantCT) | ||
| } | ||
|
|
||
| gotCC := rec.Header().Get("Cache-Control") | ||
| wantCC := "max-age=86400" | ||
| if gotCC != wantCC { | ||
| t.Errorf("Cache-Control header = %q, want %q", gotCC, wantCC) | ||
| } | ||
| }) | ||
| gotBody := rec.Body.String() | ||
| if tt.wantBody != "" && gotBody != tt.wantBody { | ||
| t.Errorf("body = %q, want %q", gotBody, tt.wantBody) | ||
| } |
There was a problem hiding this comment.
The p2 tests no longer assert the Cache-Control: max-age=86400 header even though the spec/requirements in this PR call it out and other route tests (e.g. static handlers) verify Cache-Control explicitly. Adding an assertion here would prevent regressions if middleware/route wiring changes.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| srv.ServeHTTP(rec, req) | ||
|
|
||
| srv.ServeHTTP(rec, req) | ||
| if rec.Code != tt.wantCode { | ||
| t.Errorf("status = %d, want %d", rec.Code, tt.wantCode) | ||
| } | ||
|
|
||
| if rec.Code != http.StatusNotFound { | ||
| t.Errorf("status code = %d, want %d", rec.Code, http.StatusNotFound) | ||
| } | ||
| gotCT := rec.Header().Get("Content-Type") | ||
| if tt.wantCT != "" && gotCT != tt.wantCT { | ||
| t.Errorf("Content-Type = %q, want %q", gotCT, tt.wantCT) | ||
| } | ||
|
|
There was a problem hiding this comment.
P2 routes are required (per spec) to include Cache-Control: max-age=86400 for both stable and ~dev paths, but this test no longer asserts that header. Add an assertion for Cache-Control (ideally for all cases, including 404) so regressions in middleware/route wrapping get caught.
No description provided.