bundler: use replaces_base credential for gemspec-only deps#14348
Merged
jeffwidman merged 2 commits intomainfrom Mar 3, 2026
Merged
bundler: use replaces_base credential for gemspec-only deps#14348jeffwidman merged 2 commits intomainfrom
jeffwidman merged 2 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adjusts Bundler’s RubyGems version-checking logic so that when a rubygems_server credential is configured with replaces-base: true, gemspec-only dependencies no longer fall back to querying rubygems.org, aligning behavior with Gemfile-declared dependencies and existing Bundler MetadataFinder behavior.
Changes:
- Update
LatestVersionFinder::DependencySourceto build the versions API URL using areplaces-baseRubyGems host when present. - Update
PackageDetailsFetcherto prefer areplaces-baseregistry URL when dependency requirements do not specify a source. - Add/extend RSpec coverage for both code paths and the expected fallback/precedence behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| bundler/lib/dependabot/bundler/update_checker/latest_version_finder/dependency_source.rb | Uses replaces-base credential host when constructing the RubyGems versions endpoint URL. |
| bundler/lib/dependabot/bundler/package/package_details_fetcher.rb | Falls back to replaces-base registry URL before rubygems.org when requirements don’t specify a source. |
| bundler/spec/dependabot/bundler/update_checker/latest_version_finder/dependency_source_spec.rb | Adds specs for RubyGems versions URI behavior with/without replaces-base. |
| bundler/spec/dependabot/bundler/package/package_details_fetcher_spec.rb | Adds specs ensuring replaces-base registry is used (and explicit source takes precedence). |
bundler/lib/dependabot/bundler/package/package_details_fetcher.rb
Outdated
Show resolved
Hide resolved
bundler/spec/dependabot/bundler/update_checker/latest_version_finder/dependency_source_spec.rb
Show resolved
Hide resolved
When a replaces_base rubygems_server credential is configured, gems declared only in a gemspec (via add_runtime_dependency) were bypassing the private registry and querying rubygems.org directly during version checks. Gems in the Gemfile correctly used the private registry. This fixes both code paths that determine the registry URL: 1. PackageDetailsFetcher#rubygems_versions - now checks for a replaces_base credential before falling back to rubygems.org 2. LatestVersionFinder::DependencySource#dependency_rubygems_uri - same fix for the version finder's registry URL Both follow the existing pattern already used by MetadataFinder. Fixes #14342
Guard against nil or empty host values in replaces_base credential lookups to avoid constructing invalid URLs like 'https://'.
cb319e7 to
b254a56
Compare
kbukum1
approved these changes
Mar 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a
replaces_baserubygems_server credential is configured, gems declared only in a gemspec (viaadd_runtime_dependency) were bypassing the private registry and queryingrubygems.orgdirectly during version checks. Gems declared in the Gemfile correctly routed through the private registry.Root cause
Two code paths determine the registry URL for version checks, and neither checked for
replaces_base?credentials:PackageDetailsFetcher#rubygems_versions—get_url_from_dependency()returnsnilfor gemspec deps (no:sourcein requirements), falling back tohttps://rubygems.org.LatestVersionFinder::DependencySource#dependency_rubygems_uri— hardcoded tohttps://rubygems.org.Meanwhile,
MetadataFinder#base_urlin the bundler ecosystem already correctly handlesreplaces_base?, and other ecosystems (npm, python, maven) also check it in their version-checking code.Fix
Both code paths now check for a
replaces_base?rubygems_server credential before falling back torubygems.org, using the same pattern asMetadataFinder:Tests are added for both code paths covering:
replaces_basecredential present → uses private registryreplaces_basereplaces_basecredential → falls back to rubygems.orgreplaces_baserubygems_server credential → falls back to rubygems.orgDesign note on duplication
The core credential lookup (
credentials.find { ... replaces_base? }) now appears in 3 places across the bundler ecosystem:MetadataFinder#base_url,PackageDetailsFetcher#replaces_base_registry_url, andDependencySource#replaces_base_host. Each caller shapes the result differently (full URL with trailing slash handling, URL without trailing slash, raw host string), and the 3 classes live in different inheritance hierarchies with no natural shared ancestor. This mirrors how other ecosystems (npm, maven) also inline this pattern rather than sharing it. If more callsites appear in the future, extracting a shared helper returning the raw host string would be a reasonable next step.Fixes #14342