Skip to content

ci: route npm and gem installs through the download proxy - #7833

Merged
viceice merged 3 commits into
mainfrom
viceice/ci/proxy-npm-gem
Oct 19, 2026
Merged

viceice merged 3 commits into
mainfrom
viceice/ci/proxy-npm-gem

Conversation

@viceice

@viceice viceice commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Changes

  • the download proxy action also sets CONTAINERBASE_CDN_NPM and CONTAINERBASE_CDN_GEM, so npm and gem installs of the container tests go through the proxy
  • nginx.conf:
    • cache key includes the Accept header: npm installs request the abbreviated packument, the CLI's lookups the full one from the same url
    • /<pkg>/-/<file>.tgz (also scoped) goes to registry.npmjs.org: npm rewrites tarball urls with new URL(pathname, registry), which drops the /registry.npmjs.org prefix
  • docker-bake.hcl passes the two new build args; only the test images that install node, ruby or npm/gem tools declare them (distro, latest, node, readonly, ruby)
  • test.sh checks npm packuments (both Accept variants), plain and scoped npm tarballs and gem requests

pip stays out for now (needs PIP_TRUSTED_HOST and link rewriting).

Context

Please select one of the following:

  • This closes an existing Issue, Closes: #
  • This doesn't close an Issue, but I accept the risk that this PR may be closed if maintainers disagree with its opening or implementation

Part of #7827.

AI assistance disclosure

Did you use AI tools to create any part of this pull request?

Please select one option and, if yes, briefly describe how AI was used (e.g., code, tests, docs) and which tool(s) you used.

  • No — I did not use AI for this contribution.
  • Yes — minimal assistance (e.g., IDE autocomplete, small code completions, grammar fixes).
  • Yes — substantive assistance (AI-generated non‑trivial portions of code, tests, or documentation).
  • Yes — other (please describe):

CI and proxy changes written with Claude Code (Claude Opus 5.5).

Use of AI in replying to PR comments

Who answers review comments:

  • @viceice will read and reply directly. Name the account.
  • An agent will draft replies and @username will read them before they are posted. Name the account.
  • An agent will draft replies and reply autonomously. This is heavily discouraged, and we prefer that there are humans in the loop
  • Nobody has explicitly committed to replying.

Documentation (please check one with an [x])

  • I have updated the documentation, or
  • No documentation update is required

How I've tested my work (please select one)

I have verified these changes via:

  • Code inspection only, or
  • Newly added/modified tests

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • The download proxy now supports npm and RubyGems registry requests, including package metadata, tarballs, and gem files.
    • Cached responses are distinguished by request headers to better handle different content types.
  • Tests
    • Added coverage for npm package metadata and downloads, scoped package tarballs, and RubyGems indexes and gem files.

Co-Authored-By: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 31 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: containerbase/coderabbit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a7252103-7d05-4a91-8a20-d41645defe4f
📥 Commits

Reviewing files that changed from the base of the PR and between 50ce0a2 and 36d9429.

📒 Files selected for processing: 2
  • .github/actions/download-proxy/nginx.conf
  • .github/actions/download-proxy/test.sh

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: containerbase/coderabbit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7f48d91b-2d6d-45ca-9039-e28098f87804
📥 Commits

Reviewing files that changed from the base of the PR and between e45e8e5 and 50ce0a2.

📒 Files selected for processing: 12
  • .github/actions/download-proxy/action.yml
  • .github/actions/download-proxy/nginx.conf
  • .github/actions/download-proxy/test.sh
  • docker-bake.hcl
  • test/Dockerfile.distro
  • test/latest/Dockerfile
  • test/latest/Dockerfile.arm64
  • test/node/Dockerfile
  • test/node/Dockerfile.arm64
  • test/readonly/Dockerfile
  • test/ruby/Dockerfile
  • test/ruby/Dockerfile.arm64
📝 Walkthrough

The download proxy now handles npm tarballs and RubyGems requests. Its cache key includes the request URI and Accept header. The action exports npm and gem CDN settings, and Docker build configuration passes those settings to relevant test stages.

Changes: Registry proxy support

Layer / File(s) Summary
Proxy routing, caching, and validation
.github/actions/download-proxy/action.yml, .github/actions/download-proxy/nginx.conf, .github/actions/download-proxy/test.sh
The action exports npm and gem CDN settings. nginx routes npm tarballs and includes the Accept header in cache keys. Tests cover npm packuments, tarballs, the RubyGems index, and gem files.
CDN build-argument propagation
docker-bake.hcl, test/Dockerfile.distro, test/latest/Dockerfile*, test/node/Dockerfile*, test/readonly/Dockerfile, test/ruby/Dockerfile*
docker-bake.hcl defines and passes the npm and gem CDN build arguments. Test Dockerfiles declare the arguments in relevant stages. The Node testp stage sets CONTAINERBASE_CDN_NPM to an empty value.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant NginxProxy
  participant Registry
  Client->>NginxProxy: Send request with URI and Accept header
  NginxProxy->>NginxProxy: Key cached response by URI and Accept
  NginxProxy->>Registry: Forward registry request
  Registry->>NginxProxy: Return registry response
  NginxProxy->>Client: Return response
Loading
Merge Risk: ⚪ Minimal · up to 50ce0

This change routes CI npm and gem installs through the local caching proxy and keeps abbreviated npm metadata separate from full metadata in the cache. It affects only CI test builds, and the routing concerns raised in review did not hold up. No merge-blocking risk remains.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: routing npm and gem installs through the download proxy in CI.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (11 skipped: 1…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (11 skipped: 11 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Route npm and gem installs through the CI download proxy

✨ Enhancement ⚙️ Configuration changes 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Enable proxy routing for npm and gem installs in CI container tests.
• Pass the new settings through Bake and test Dockerfile stages.
• Handle npm tarball paths and packument variants; test npm and gem requests.
Diagram

graph TD
  Action["CI proxy action"] --> Bake["Bake settings"] --> Docker["Test Dockerfiles"] --> Installs["npm and gem"] --> Proxy["nginx proxy"] --> Cache["Variant cache"] --> Registries["Upstream registries"]
Loading
High-Level Assessment

Use the existing CDN opt-in settings and shared proxy rather than introducing a second package-manager proxy. The targeted npm path rule and Accept-aware cache address the differences in npm requests while preserving the existing allowlist and CI build pipeline. Pip remains outside this change because it needs additional trust and link-rewriting support.

Files changed (45) +208 / -9

Enhancement (1) +10 / -3
nginx.confRoute npm tarballs and separate packument cache variants +10/-3

Route npm tarballs and separate packument cache variants

• Routes plain and scoped npm tarball paths without a host prefix to registry.npmjs.org. Adds the Accept header to the cache key so abbreviated and full packuments do not share an entry.

.github/actions/download-proxy/nginx.conf

Tests (1) +21 / -4
test.shExercise npm and RubyGems proxy requests +21/-4

Exercise npm and RubyGems proxy requests

• Adds optional Accept headers to the request helper and checks separate npm packument cache entries, plain and scoped tarballs, and RubyGems index and gem requests.

.github/actions/download-proxy/test.sh

Other (43) +177 / -2
action.ymlEnable npm and gem proxy settings in CI +6/-2

Enable npm and gem proxy settings in CI

• Exports CONTAINERBASE_CDN_NPM and CONTAINERBASE_CDN_GEM alongside the proxy URL for subsequent CI steps.

.github/actions/download-proxy/action.yml

docker-bake.hclPass npm and gem CDN flags to image builds +10/-0

Pass npm and gem CDN flags to image builds

• Defines both flags with empty defaults and adds them to shared Bake build arguments.

docker-bake.hcl

Dockerfile.baseExpose npm and gem CDN arguments in the base test build +2/-0

Expose npm and gem CDN arguments in the base test build

• Declares both build arguments alongside CONTAINERBASE_CDN before containerbase installation.

test/Dockerfile.base

Dockerfile.distroExpose npm and gem CDN arguments in the distro test build +2/-0

Expose npm and gem CDN arguments in the distro test build

• Declares both build arguments alongside CONTAINERBASE_CDN before containerbase installation.

test/Dockerfile.distro

DockerfilePass CDN package-manager flags through Dart test stages +4/-0

Pass CDN package-manager flags through Dart test stages

• Declares the npm and gem build arguments in both stages that accept CONTAINERBASE_CDN.

test/dart/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Dart stages +4/-0

Pass CDN package-manager flags through ARM64 Dart stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/dart/Dockerfile.arm64

DockerfilePass CDN package-manager flags through .NET test stages +4/-0

Pass CDN package-manager flags through .NET test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/dotnet/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 .NET stages +4/-0

Pass CDN package-manager flags through ARM64 .NET stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/dotnet/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Erlang test stages +4/-0

Pass CDN package-manager flags through Erlang test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/erlang/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Erlang stages +4/-0

Pass CDN package-manager flags through ARM64 Erlang stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/erlang/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Flutter test stages +4/-0

Pass CDN package-manager flags through Flutter test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/flutter/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Flutter stages +4/-0

Pass CDN package-manager flags through ARM64 Flutter stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/flutter/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Flux test stages +4/-0

Pass CDN package-manager flags through Flux test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/flux/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Flux stages +4/-0

Pass CDN package-manager flags through ARM64 Flux stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/flux/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Go test stages +4/-0

Pass CDN package-manager flags through Go test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/golang/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Go stages +4/-0

Pass CDN package-manager flags through ARM64 Go stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/golang/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Haskell test stages +4/-0

Pass CDN package-manager flags through Haskell test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/haskell/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Haskell stages +4/-0

Pass CDN package-manager flags through ARM64 Haskell stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/haskell/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Helm test stages +4/-0

Pass CDN package-manager flags through Helm test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/helm/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Helm stages +4/-0

Pass CDN package-manager flags through ARM64 Helm stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/helm/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Java test stages +4/-0

Pass CDN package-manager flags through Java test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/java/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Java stages +4/-0

Pass CDN package-manager flags through ARM64 Java stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/java/Dockerfile.arm64

DockerfilePass CDN package-manager flags through JB test stages +4/-0

Pass CDN package-manager flags through JB test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/jb/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 JB stages +4/-0

Pass CDN package-manager flags through ARM64 JB stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/jb/Dockerfile.arm64

DockerfilePass CDN package-manager flags through latest-image stages +6/-0

Pass CDN package-manager flags through latest-image stages

• Declares the npm and gem build arguments in all three stages that accept CONTAINERBASE_CDN.

test/latest/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 latest stages +4/-0

Pass CDN package-manager flags through ARM64 latest stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/latest/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Nix test stages +4/-0

Pass CDN package-manager flags through Nix test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/nix/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Nix stages +4/-0

Pass CDN package-manager flags through ARM64 Nix stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/nix/Dockerfile.arm64

DockerfileEnable proxy flags in Node stages while preserving URL-replacement tests +5/-0

Enable proxy flags in Node stages while preserving URL-replacement tests

• Declares the npm and gem build arguments in both CDN-enabled stages. Clears CONTAINERBASE_CDN_NPM in the pnpm/yarn URL-replacement stage alongside CONTAINERBASE_CDN so the proxy does not bypass those replacements.

test/node/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Node stages +4/-0

Pass CDN package-manager flags through ARM64 Node stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/node/Dockerfile.arm64

DockerfilePass CDN package-manager flags through PHP test stages +4/-0

Pass CDN package-manager flags through PHP test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/php/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 PHP stages +4/-0

Pass CDN package-manager flags through ARM64 PHP stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/php/Dockerfile.arm64

DockerfilePass CDN package-manager flags through PowerShell test stages +4/-0

Pass CDN package-manager flags through PowerShell test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/powershell/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 PowerShell stages +4/-0

Pass CDN package-manager flags through ARM64 PowerShell stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/powershell/Dockerfile.arm64

DockerfilePass npm and gem CDN flags through Python test stages +4/-0

Pass npm and gem CDN flags through Python test stages

• Declares the npm and gem build arguments in both CDN-enabled stages; this does not enable pip proxying.

test/python/Dockerfile

Dockerfile.arm64Pass npm and gem CDN flags through ARM64 Python stages +4/-0

Pass npm and gem CDN flags through ARM64 Python stages

• Declares the npm and gem build arguments in both CDN-enabled stages; this does not enable pip proxying.

test/python/Dockerfile.arm64

DockerfileExpose CDN package-manager flags in the read-only test build +2/-0

Expose CDN package-manager flags in the read-only test build

• Declares the npm and gem build arguments alongside CONTAINERBASE_CDN.

test/readonly/Dockerfile

DockerfilePass CDN package-manager flags through Ruby test stages +4/-0

Pass CDN package-manager flags through Ruby test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/ruby/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Ruby stages +4/-0

Pass CDN package-manager flags through ARM64 Ruby stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/ruby/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Rust test stages +4/-0

Pass CDN package-manager flags through Rust test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/rust/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Rust stages +4/-0

Pass CDN package-manager flags through ARM64 Rust stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/rust/Dockerfile.arm64

DockerfilePass CDN package-manager flags through Swift test stages +4/-0

Pass CDN package-manager flags through Swift test stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/swift/Dockerfile

Dockerfile.arm64Pass CDN package-manager flags through ARM64 Swift stages +4/-0

Pass CDN package-manager flags through ARM64 Swift stages

• Declares the npm and gem build arguments in both CDN-enabled stages.

test/swift/Dockerfile.arm64

@qodo-code-review

qodo-code-review Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

Grey Divider

Resolved findings
1. Npm tarballs with queries fail to install ✓ Resolved
Description
The new npm tarball maps match $request_uri only when it ends exactly in .tgz, although that
variable also contains the query string. When a tarball URL includes a query, the fallback treats
the package name as the upstream host and the allowlist rejects the request with 403.
Code

.github/actions/download-proxy/nginx.conf[32]

+    ~^/(@[^/]+/)?[^/]+/-/[^/?]+\.tgz$ registry.npmjs.org;
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The npm tarball routing maps reject tarball URLs with query strings because they match against `$request_uri` and require `.tgz` at its end.
## Fix Focus Areas
- .github/actions/download-proxy/nginx.conf[30-39]
- .github/actions/download-proxy/test.sh[75-78]
## Recommended Fix
Update both npm tarball maps to recognize and preserve an optional query string while routing the tarball to the npm registry. Add a test for a tarball URL containing a query.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can import rules and skills only from the repositories your team follows

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Co-Authored-By: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
@viceice

viceice commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Qodo finding not fixed:

  • "Npm tarballs with queries fail to install": npm builds these tarball urls with new URL(pathname, registry), which keeps only the path, so they never carry a query string.

(Claude, for @viceice)

@qodo-code-review

Copy link
Copy Markdown

Qodo finding not fixed:

  • "Npm tarballs with queries fail to install": npm builds these tarball urls with new URL(pathname, registry), which keeps only the path, so they never carry a query string.

(Claude, for @viceice)

The finding remains technically valid, although it may not affect the current npm client path.

  • In .github/actions/download-proxy/nginx.conf:32 and :38, both tarball regexes are anchored to .tgz at the end of $request_uri.
  • $request_uri includes the query string, so a request such as /is-number/-/is-number-7.0.0.tgz?x=1 misses both npm-specific maps.
  • It then falls through to the generic host extraction at :33, treating is-number as the upstream host and likely returning 403 via the allowlist.

If npm always constructs these URLs without queries, this is not an npm-install regression today; however, the proxy still mishandles query-bearing tarball requests. The finding’s recommended fix and test remain appropriate, or it could be dismissed as out of scope if query-bearing tarball URLs are intentionally unsupported.

Co-Authored-By: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
@viceice
viceice enabled auto-merge October 19, 2026 12:09
@viceice
viceice added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit 0bdde0e Oct 19, 2026
56 checks passed
@viceice
viceice deleted the viceice/ci/proxy-npm-gem branch October 19, 2026 12:28
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 14.44.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

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.

1 participant