Add goproxy virtual repositories #159

Merged
benvin merged 7 commits from benvin/virtual-go into master 2026-10-19 21:39:50 +11:00
Member

Go clients need one GOPROXY for internal and public modules; goproxy has no virtual type, so a local goproxy repo and proxy.golang.org cannot be served together.

  • union member @v/lists; compute @latest over the union (highest release, else highest prerelease)
  • 302 @latest and .info/.mod/.zip to the first member with that version, root-relative and no-store; probe .info for unlisted pseudo-versions
  • validate case-encoded module paths and versions
  • fail closed with 502 on a member error, skip members answering 404/410
  • cache merged lists, keyed on list and version owners, and module misses for the merge TTL
  • add docs/goproxy/virtual.md and a stock golang:1.25 e2e-docker case

requires unkin/artifactapi#143

Go clients need one GOPROXY for internal and public modules; goproxy has no virtual type, so a local goproxy repo and proxy.golang.org cannot be served together. - union member `@v/list`s; compute `@latest` over the union (highest release, else highest prerelease) - 302 `@latest` and `.info`/`.mod`/`.zip` to the first member with that version, root-relative and `no-store`; probe `.info` for unlisted pseudo-versions - validate case-encoded module paths and versions - fail closed with 502 on a member error, skip members answering 404/410 - cache merged lists, keyed on list and version owners, and module misses for the merge TTL - add `docs/goproxy/virtual.md` and a stock `golang:1.25` e2e-docker case requires unkin/artifactapi#143
Author
Member
  • internal/virtual/goproxy_merger.go:35 — GoDoc.index() returns only Body, and merged() (engine.go:311) keeps the old generation when the body is unchanged, so Owners is never refreshed while the version list stays the same (e.g. a version deleted from the first member but still listed by a later one keeps 302ing to the first member and 404s; a version newly added to the first member keeps being served from the later one) → make index() include the owners (e.g. version owner lines) so an owner change replaces the cached doc; add a test.
  • nit: internal/virtual/engine.go:434 — the shared fetchMemberPath 404/410 → ErrNotFound change has no test → add one covering a ServeRemote/ServeLocalIndex 404 and 410 (goMember is stubbed everywhere, so nothing exercises it).
  • nit: internal/virtual/goproxy_merger.go:157 — ErrNotFound merges are not cached, so every request for a module no member has fans out to all members (including proxy.golang.org) → cache the miss for a short TTL or document it.
- internal/virtual/goproxy_merger.go:35 — `GoDoc.index()` returns only `Body`, and `merged()` (engine.go:311) keeps the old generation when the body is unchanged, so `Owners` is never refreshed while the version list stays the same (e.g. a version deleted from the first member but still listed by a later one keeps 302ing to the first member and 404s; a version newly added to the first member keeps being served from the later one) → make `index()` include the owners (e.g. `version owner` lines) so an owner change replaces the cached doc; add a test. - nit: internal/virtual/engine.go:434 — the shared `fetchMemberPath` 404/410 → `ErrNotFound` change has no test → add one covering a `ServeRemote`/`ServeLocalIndex` 404 and 410 (goMember is stubbed everywhere, so nothing exercises it). - nit: internal/virtual/goproxy_merger.go:157 — `ErrNotFound` merges are not cached, so every request for a module no member has fans out to all members (including proxy.golang.org) → cache the miss for a short TTL or document it.
Author
Member

No findings.

No findings.
benvin changed target branch from benvin/local-go to master 2026-10-19 00:01:54 +11:00
benvin added 6 commits 2026-10-19 00:01:54 +11:00
Add goproxy local repositories for private Go modules
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
a51323c725
merge master
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
8378701d9a
merge master
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
5a2bfdf73a
merge master
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
8e96aabbef
Add goproxy virtual repositories
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
c6f7eb3eb7
Key goproxy merge cache on owners and cache module misses
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ac6e1bf798
unkin-agent added 1 commit 2026-10-19 00:03:49 +11:00
Merge remote-tracking branch 'origin/master' into benvin/virtual-go
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
be7be0bd04
# Conflicts:
#	README.md
#	internal/provider/goproxy/local.go
benvin merged commit 4649878a6d into master 2026-10-19 21:39:50 +11:00
benvin deleted branch benvin/virtual-go 2026-10-19 21:39:50 +11:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/artifactapi#159