Skip to content

npm: support GitHub Packages SHA tarball URLs - #238

Open
ksivamuthu-cei wants to merge 2 commits into
git-pkgs:mainfrom
ksivamuthu-cei:fix/npm-github-packages-tarballs
Open

npm: support GitHub Packages SHA tarball URLs#238
ksivamuthu-cei wants to merge 2 commits into
git-pkgs:mainfrom
ksivamuthu-cei:fix/npm-github-packages-tarballs

Conversation

@ksivamuthu-cei

@ksivamuthu-cei ksivamuthu-cei commented Aug 8, 2026

Copy link
Copy Markdown

Summary

Support npm registries that publish content-addressed tarball URLs, including GitHub Packages URLs shaped like:

https://npm.pkg.github.com/download/@scope/package/1.0.0/SHA-1

Previously, the proxy used the final URL segment as the filename. Because GitHub's final segment is a SHA-1 rather than {package}-{version}.tgz, downloads failed before cache lookup with could not determine version from filename.

This change:

  • rewrites content-addressed tarballs to a conventional proxy .tgz path with a private git-pkgs-shasum query parameter;
  • resolves that request by reloading trusted upstream metadata and verifying the requested version's dist.shasum;
  • fetches the original upstream dist.tarball URL rather than reconstructing GitHub's content-addressed path; and
  • accepts that tarball URL only when its scheme and host match the configured npm upstream.

Regular npm tarball paths retain their existing rewrite and download behavior.

Tests

  • go test ./internal/handler -run 'TestNPM'
  • go test ./...
  • go vet ./...
  • go build ./cmd/proxy

Added coverage for GitHub Packages metadata rewriting, fetching the original content-addressed tarball, checksum mismatch rejection, and cross-host tarball rejection.

@ksivamuthu-cei
ksivamuthu-cei force-pushed the fix/npm-github-packages-tarballs branch from 6b0110f to f4a64d3 Compare August 8, 2026 02:30
@andrew
andrew requested a lite review from Copilot August 8, 2026 08:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds support in the npm proxy handler for registries that publish content-addressed tarball URLs (e.g., GitHub Packages), by rewriting metadata tarball URLs to a conventional *.tgz proxy path and resolving downloads via a shasum-backed lookup against upstream metadata.

Changes:

  • Rewrites content-addressed tarball URLs to {name}-{version}.tgz plus a git-pkgs-shasum query parameter.
  • Resolves shasum-based download requests by re-fetching upstream metadata, verifying dist.shasum, and using dist.tarball (with upstream-origin validation).
  • Adds tests covering GitHub Packages-style rewriting, successful fetch, checksum mismatch rejection, and cross-host tarball rejection.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
internal/handler/npm.go Adds shasum-aware tarball rewrite + download resolution/validation for content-addressed tarball URLs.
internal/handler/npm_test.go Adds test coverage for GitHub Packages tarball rewriting and shasum-based download validation paths.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/handler/npm.go

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for this — GitHub Packages as an npm upstream is currently broken exactly as you describe, and it's worth fixing.

I'd like to avoid the git-pkgs-shasum query parameter though. At download time the handler already has packageName and version from the request path, so it can look up versions[version].dist.tarball from cached metadata directly without the client carrying a hint back. A couple of specific concerns with the current shape:

  • The shasum comparison doesn't verify anything: both the client-supplied value and dist.shasum come from the same upstream packument (one via the rewritten metadata, one via the re-fetch), so it only confirms the metadata agrees with itself.
  • npm records resolved verbatim in package-lock.json, so ?git-pkgs-shasum=... ends up committed in users' lockfiles, baking a proxy-internal detail into files the proxy doesn't control.

A simpler approach that covers GitHub Packages and any other registry with non-standard tarball paths:

  • In rewriteTarballURLs, when the upstream filename doesn't parse as <shortName>-<version>.tgz, synthesize that filename (as you already do) but with no query string.
  • In handleDownload, resolve the upstream URL by reading versions[version].dist.tarball from FetchOrCacheMetadata, keeping your host/scheme/base-path check in validateUpstreamTarballURL. Fall back to the current fmt.Sprintf construction only if metadata is unavailable.

This will also need a rebase onto main: #241 removed npmAbbreviatedCT (which tarballURLForShasum references, so it won't compile as-is) and #240 added a cooldown check in handleDownload right where this PR changes the downloadURL assignment.

@ksivamuthu-cei
ksivamuthu-cei force-pushed the fix/npm-github-packages-tarballs branch from b0ec489 to 8266cbf Compare August 10, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants