Skip to content

Server: Add GET /p2/{vendor}/{file} route#55

Merged
tangrufus merged 1 commit intomainfrom
p2
Apr 2, 2026
Merged

Server: Add GET /p2/{vendor}/{file} route#55
tangrufus merged 1 commit intomainfrom
p2

Conversation

@tangrufus
Copy link
Copy Markdown
Member

No description provided.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.40%. Comparing base (82abe2b) to head (b4ad623).
⚠️ Report is 4 commits behind head on main.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tangrufus tangrufus changed the title Add p2 route Add /p2/{vendor}/{file} route Apr 2, 2026
@tangrufus tangrufus changed the title Add /p2/{vendor}/{file} route Server: Add /p2/{vendor}/{file} route Apr 2, 2026
@tangrufus tangrufus changed the title Server: Add /p2/{vendor}/{file} route Server: Add GET /p2/{vendor}/{file} route Apr 2, 2026
@tangrufus tangrufus marked this pull request as ready for review April 2, 2026 05:29
Copilot AI review requested due to automatic review settings April 2, 2026 05:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 and handleP2 handler to serve stable *.json responses and 404 dev *~dev.json.
  • Enable "security-advisories.metadata": true in internal/server/static/packages.json so 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.

Comment on lines +76 to 86

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)
}

Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
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))
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
mux.HandleFunc("GET /p2/{vendor}/{file}", handleP2(store))
mux.HandleFunc("GET /p2/{vendor}/{file}", m(handleP2(store)))

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +81 to +90
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)
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +70 to 84
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)
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
@tangrufus tangrufus requested a review from Copilot April 2, 2026 06:57
@tangrufus tangrufus merged commit f0a2eaa into main Apr 2, 2026
19 checks passed
@tangrufus tangrufus deleted the p2 branch April 2, 2026 07:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +70 to 80
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)
}

Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants