Skip to content

Prepare RubyGems 4.0.13 and Bundler 4.0.13#9590

Open
hsbt wants to merge 19 commits into
4.0from
release/4.0.13
Open

Prepare RubyGems 4.0.13 and Bundler 4.0.13#9590
hsbt wants to merge 19 commits into
4.0from
release/4.0.13

Conversation

@hsbt
Copy link
Copy Markdown
Member

@hsbt hsbt commented Jun 3, 2026

  • Show release date with bundle outdated #9337
  • Fallback to copy symlinks on Windows #9296
  • Close stdin immediately when using popen2e #9540
  • Prevent extraction from escaping destination_dir via pre-existing symlinks #9493
  • Clear gem specification cache after acquiring process lock #9310
  • Do not hard-code permissions for new gem directories during bundle install #9557
  • Vendor compact_index from rubygems.org for the artifice #9574
  • Install compact_index on test_setup #9578
  • Lock compact_index vendoring against parallel races #9579
  • Write vendored compact_index files atomically #9581
  • Fixed flaky tests #9580
  • Add cooldown to delay newly published gem #9576
  • Parse created_at via Time.new instead of Time.iso8601 #9583
  • Apply cooldown to locally installed gem versions #9582
  • Split compact index entries on the first colon on older RubyGems #9585

hsbt and others added 11 commits June 3, 2026 09:57
Show release date with bundle outdated

(cherry picked from commit 99a5b40)
Symlinks are not permitted by default for a Windows user. To use them, a switch called "Development Mode" in the system settings has to be enabled.

## What was the end-user or developer problem that led to this PR?

Ordinary users as well as administrators are unable per default to install gems using symlinks.
One such problematical gem is `haml-rails-3.0.0`.
It uses symlinks for [files and directories](https://github.com/haml/haml-rails/tree/9f4703ddff0644ba52529c5cf41c1624829b16a7/lib/generators/haml/scaffold/templates).
The resulting error message is not very helpful:

```
$ gem inst haml-rails
Fetching haml-rails-3.0.0.gem
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the directory. (Gem::FilePermissionError)
        C:/ruby/lib/ruby/4.0.0/rubygems/installer.rb:308:in 'Gem::Installer#install'
        C:/ruby/lib/ruby/4.0.0/rubygems/resolver/specification.rb:105:in 'Gem::Resolver::Specification#install'
        C:/ruby/lib/ruby/4.0.0/rubygems/request_set.rb:192:in 'block in Gem::RequestSet#install'
        C:/ruby/lib/ruby/4.0.0/rubygems/request_set.rb:183:in 'Array#each'
        C:/ruby/lib/ruby/4.0.0/rubygems/request_set.rb:183:in 'Gem::RequestSet#install'
        C:/ruby/lib/ruby/4.0.0/rubygems/commands/install_command.rb:207:in 'Gem::Commands::InstallCommand#install_gem'
        C:/ruby/lib/ruby/4.0.0/rubygems/commands/install_command.rb:223:in 'block in Gem::Commands::InstallCommand#install_gems'
        C:/ruby/lib/ruby/4.0.0/rubygems/commands/install_command.rb:216:in 'Array#each'
        C:/ruby/lib/ruby/4.0.0/rubygems/commands/install_command.rb:216:in 'Gem::Commands::InstallCommand#install_gems'
        C:/ruby/lib/ruby/4.0.0/rubygems/commands/install_command.rb:162:in 'Gem::Commands::InstallCommand#execute'
        C:/ruby/lib/ruby/4.0.0/rubygems/command.rb:326:in 'Gem::Command#invoke_with_build_args'
        C:/ruby/lib/ruby/4.0.0/rubygems/command_manager.rb:252:in 'Gem::CommandManager#invoke_command'
        C:/ruby/lib/ruby/4.0.0/rubygems/command_manager.rb:193:in 'Gem::CommandManager#process_args'
        C:/ruby/lib/ruby/4.0.0/rubygems/command_manager.rb:151:in 'Gem::CommandManager#run'
        C:/ruby/lib/ruby/4.0.0/rubygems/gem_runner.rb:56:in 'Gem::GemRunner#run'
        C:/ruby/bin/gem.cmd:20:in '<main>'
```

## What is your fix for the problem, implemented in this PR?

Instead of working around the situation in the affected gem or to skip symlinks completely, I think the better solution would be to make copies of the files in question. This would allow Windows users to install and use the gem smoothly.

The switch for the "Developer Mode" is available in the Windows registry under
    `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock`
entry
    `AllowDevelopmentWithoutDevLicense`

(cherry picked from commit ca6c579)
Close stdin immediately when using popen2e

(cherry picked from commit 5869518)
Prevent extraction from escaping destination_dir via pre-existing symlinks

(cherry picked from commit 103ca42)
Clear gem specification cache after acquiring process lock

(cherry picked from commit 8052c40)
Do not hard-code permissions for new gem directories during bundle install

(cherry picked from commit b26074a)
Vendor `compact_index` from rubygems.org for the artifice

(cherry picked from commit 386fb2c)
Install compact_index on `test_setup`

(cherry picked from commit 7343eef)
Lock compact_index vendoring against parallel races

(cherry picked from commit 0365a17)
Write vendored compact_index files atomically

(cherry picked from commit 86b63d5)
Fixed flaky tests

(cherry picked from commit dce4b75)
Copilot AI review requested due to automatic review settings June 3, 2026 01:10
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

Prepares the RubyGems/Bundler 4.0.13 release by bumping versions and integrating a set of recently merged features/fixes (cooldown filtering based on created_at, improved Windows symlink behavior, safer package extraction, cache invalidation after process locks, and updated CLI/docs/specs).

Changes:

  • Bump RubyGems and Bundler versions to 4.0.13 and update associated lockfiles/changelogs.
  • Add Bundler “cooldown” support (CLI/config/Gemfile per-source), propagate created_at metadata, and update resolver/outdated output + docs/tests.
  • Improve Windows and security behavior (symlink fallback/capability detection, prevent extraction escape via pre-existing symlinks, close stdin in Open3.popen2e).

Reviewed changes

Copilot reviewed 64 out of 74 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tool/bundler/vendor_gems.rb.lock Bump bundled-with Bundler version to 4.0.13.
tool/bundler/test_gems.rb.lock Remove compact_index dep and bump bundled-with version.
tool/bundler/test_gems.rb Remove compact_index from test gems list.
tool/bundler/standard_gems.rb.lock Bump bundled-with Bundler version to 4.0.13.
tool/bundler/rubocop_gems.rb.lock Bump bundled-with Bundler version to 4.0.13.
tool/bundler/release_gems.rb.lock Bump bundled-with Bundler version to 4.0.13.
tool/bundler/lint_gems.rb.lock Bump bundled-with Bundler version to 4.0.13.
tool/bundler/dev_gems.rb.lock Bump bundled-with Bundler version to 4.0.13.
test/rubygems/test_gem_package.rb Adjust symlink-related tests; add regression coverage for symlink-escape extraction.
test/rubygems/test_gem_installer.rb Make dangling-symlink expectations conditional on symlink support.
test/rubygems/test_gem_ext_builder.rb Add test asserting stdin is closed when running extension builds.
test/rubygems/test_gem_commands_owner_command.rb Stabilize WebAuthn failure test by checking the intended request.
test/rubygems/installer_test_case.rb Move symlink_supported? helper out of this test case.
test/rubygems/helper.rb Centralize symlink_supported? helper for tests.
lib/rubygems/resolver/api_set/gem_parser.rb Fix compact-index parsing to split on first colon.
lib/rubygems/package.rb Add link-aware extraction boundary check; Windows symlink fallback to copy.
lib/rubygems/ext/builder.rb Close stdin immediately in Open3.popen2e usage.
lib/rubygems.rb Bump RubyGems VERSION to 4.0.13.
CHANGELOG.md Add RubyGems 4.0.13 release notes.
bundler/spec/support/windows_tag_group.rb Adjust Windows tag grouping for new/affected specs.
bundler/spec/support/rubygems_ext.rb Install vendored compact_index into tmp for artifice use; lock against parallel setup races.
bundler/spec/support/command_execution.rb Make output normalization robust to invalid UTF-8 bytes.
bundler/spec/support/artifice/helpers/compact_index.rb Load compact_index from vendored tmp path; refactor gem-version creation.
bundler/spec/support/artifice/helpers/compact_index_cooldown.rb New artifice helper emitting v2 compact-index with created_at.
bundler/spec/support/artifice/compact_index_cooldown.rb New artifice activation entrypoint for cooldown tests.
bundler/spec/realworld/fixtures/warbler/Gemfile.lock Bump bundled-with Bundler version to 4.0.13.
bundler/spec/realworld/fixtures/tapioca/Gemfile.lock Bump bundled-with Bundler version to 4.0.13.
bundler/spec/install/process_lock_spec.rb Add integration spec covering cache refresh after waiting on the process lock.
bundler/spec/install/cooldown_spec.rb New end-to-end install/outdated/update coverage for cooldown behavior.
bundler/spec/commands/platform_spec.rb Update expected outdated table header to include Release Date.
bundler/spec/commands/outdated_spec.rb Update outdated expectations for Release Date column and cooldown annotations.
bundler/spec/commands/newgem_spec.rb Add timeout to cargo test invocation.
bundler/spec/commands/install_spec.rb Add permissions behavior spec for umask+setgid dir creation.
bundler/spec/bundler/source/rubygems/remote_spec.rb Add specs for per-remote cooldown and effective precedence.
bundler/spec/bundler/source/rubygems_spec.rb Add specs for #clear_cache behavior.
bundler/spec/bundler/source_list_spec.rb Add specs for per-remote cooldown recording and source-list cache clearing.
bundler/spec/bundler/settings_spec.rb Ensure settings coercion covers cooldown.
bundler/spec/bundler/rubygems_ext_spec.rb New spec for legacy compact-index colon splitting shim.
bundler/spec/bundler/resolver/cooldown_spec.rb New unit tests for resolver cooldown filtering + hint text.
bundler/spec/bundler/endpoint_specification_spec.rb Add created_at parsing coverage (including legacy shapes).
bundler/spec/bundler/dsl_spec.rb Add DSL validation tests for source ..., cooldown: N.
bundler/spec/bundler/compact_index_client/parser_spec.rb Extend parser expectations to include created_at metadata.
bundler/lib/bundler/version.rb Bump Bundler VERSION to 4.0.13.
bundler/lib/bundler/source/rubygems/remote.rb Add per-remote cooldown and effective precedence logic.
bundler/lib/bundler/source/rubygems.rb Thread cooldown through remotes; snapshot/backfill created_at; add clear_cache.
bundler/lib/bundler/source/git/git_proxy.rb Disable git maintenance to avoid clone/hardlink races.
bundler/lib/bundler/source_list.rb Allow cooldown on global remotes; add cache clearing across sources.
bundler/lib/bundler/settings.rb Treat cooldown as a numeric setting key.
bundler/lib/bundler/rubygems_gem_installer.rb Stop hard-coding directory permissions (respect umask/setgid).
bundler/lib/bundler/rubygems_ext.rb Add legacy shim to split compact-index entries on first colon.
bundler/lib/bundler/resolver.rb Apply cooldown filtering and surface cooldown hint in resolution errors.
bundler/lib/bundler/remote_specification.rb Add created_at attribute to remote specs.
bundler/lib/bundler/man/bundle-update.1.ronn Document --cooldown for update.
bundler/lib/bundler/man/bundle-update.1 Generated manpage update for --cooldown.
bundler/lib/bundler/man/bundle-outdated.1.ronn Document cooldown annotation behavior + Release Date output.
bundler/lib/bundler/man/bundle-outdated.1 Generated manpage update for cooldown + Release Date examples.
bundler/lib/bundler/man/bundle-install.1.ronn Document --cooldown for install.
bundler/lib/bundler/man/bundle-install.1 Generated manpage update for --cooldown.
bundler/lib/bundler/man/bundle-config.1.ronn Document cooldown config key, precedence, and server requirements.
bundler/lib/bundler/man/bundle-config.1 Generated manpage update for cooldown setting.
bundler/lib/bundler/man/bundle-add.1.ronn Document --cooldown for add.
bundler/lib/bundler/man/bundle-add.1 Generated manpage update for --cooldown.
bundler/lib/bundler/installer.rb Clear spec/source caches after acquiring process lock.
bundler/lib/bundler/endpoint_specification.rb Add created_at metadata parsing for v2 compact-index.
bundler/lib/bundler/dsl.rb Validate and propagate cooldown: on source.
bundler/lib/bundler/cli/update.rb Validate and apply --cooldown option.
bundler/lib/bundler/cli/outdated.rb Validate/apply --cooldown; add Release Date column and cooldown annotations.
bundler/lib/bundler/cli/install.rb Validate and apply --cooldown option.
bundler/lib/bundler/cli/common.rb Add shared cooldown validation helper.
bundler/lib/bundler/cli/add.rb Validate and apply --cooldown option.
bundler/lib/bundler/cli.rb Add --cooldown option wiring for install/update/add/outdated.
bundler/CHANGELOG.md Add Bundler 4.0.13 release notes.
bin/windows_run_as_user New helper to run tests as a non-admin Windows user in CI.
.github/workflows/rubygems.yml Add Windows “no symlinks” CI variant and non-admin test execution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +419 to +420
webauthn_verification_request = @stub_fetcher.requests.find {|req| req.path == "/api/v1/webauthn_verification" }
assert_match webauthn_verification_request["Authorization"], Gem.configuration.rubygems_api_key
Comment on lines +96 to +104
require "open-uri"
ref = ENV["COMPACT_INDEX_REF"] || "7c68a7b39761c61a66f9299f85b889ec39afc02c"
files.each do |path|
url = "https://raw.githubusercontent.com/rubygems/rubygems.org/#{ref}/#{path}"
target = target_root.join(path)
FileUtils.mkdir_p(File.dirname(target))
tmp = "#{target}.tmp"
File.write(tmp, URI.parse(url).open(&:read))
File.rename(tmp, target)
hsbt added 8 commits June 3, 2026 10:40
Add `cooldown` to delay newly published gem

(cherry picked from commit 88057ed)
Parse `created_at` via `Time.new` instead of `Time.iso8601`

(cherry picked from commit cc2e37c)
Apply cooldown to locally installed gem versions

(cherry picked from commit 97775a0)
…-colon

Split compact index entries on the first colon on older RubyGems

(cherry picked from commit 6d11166)
@hsbt hsbt force-pushed the release/4.0.13 branch from 4ae16e2 to 003f20f Compare June 3, 2026 01:42
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