diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml index 3b28040c33adfb..1a84cfe390616f 100644 --- a/.github/workflows/annocheck.yml +++ b/.github/workflows/annocheck.yml @@ -73,7 +73,7 @@ jobs: builddir: build makeup: true - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/auto_review_pr.yml b/.github/workflows/auto_review_pr.yml index 5a27e76b6434cf..6308b392ad7462 100644 --- a/.github/workflows/auto_review_pr.yml +++ b/.github/workflows/auto_review_pr.yml @@ -29,7 +29,7 @@ jobs: with: persist-credentials: false - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.4' bundler: none diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index 7f0613487e5fd5..23fa7aae3f2732 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -48,7 +48,7 @@ jobs: - ruby-3.3 steps: - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml index 6119bd5b58784e..fa5e0441c6182a 100644 --- a/.github/workflows/bundled_gems.yml +++ b/.github/workflows/bundled_gems.yml @@ -38,7 +38,7 @@ jobs: with: token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: 4.0 diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index 93fc2abe4d2e55..0d41a7ed981a70 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -42,7 +42,7 @@ jobs: - uses: ./.github/actions/setup/directories - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml index bc7e36467cf2e9..29333088133d0e 100644 --- a/.github/workflows/check_misc.yml +++ b/.github/workflows/check_misc.yml @@ -23,7 +23,7 @@ jobs: token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} persist-credentials: false - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: head diff --git a/.github/workflows/check_sast.yml b/.github/workflows/check_sast.yml index 9bd011e0d8b3fa..7939a831e51848 100644 --- a/.github/workflows/check_sast.yml +++ b/.github/workflows/check_sast.yml @@ -78,14 +78,14 @@ jobs: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 + uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: languages: ${{ matrix.language }} build-mode: none config-file: .github/codeql/codeql-config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 + uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: category: '/language:${{ matrix.language }}' upload: False @@ -126,7 +126,7 @@ jobs: continue-on-error: true - name: Upload SARIF - uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: sarif_file: sarif-results/${{ matrix.language }}.sarif continue-on-error: true diff --git a/.github/workflows/modgc.yml b/.github/workflows/modgc.yml index 577369dc7628dc..a274b1727ecee3 100644 --- a/.github/workflows/modgc.yml +++ b/.github/workflows/modgc.yml @@ -62,7 +62,7 @@ jobs: uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/parse_y.yml b/.github/workflows/parse_y.yml index 333a7a5ef9daa8..2dbbf4146687b0 100644 --- a/.github/workflows/parse_y.yml +++ b/.github/workflows/parse_y.yml @@ -59,7 +59,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d2de7420e84977..9a8a05038762a9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -22,7 +22,7 @@ jobs: with: persist-credentials: false - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: 3.3.4 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index cab229c8ef82f9..fb6d140e77f023 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -73,6 +73,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: sarif_file: results.sarif diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index fde3ffe7632240..7ddf5e02ac67dc 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -49,7 +49,7 @@ jobs: with: persist-credentials: false - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index 7bc3dff11a0eaa..72b77b6a42f642 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -39,7 +39,7 @@ jobs: with: token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.4' bundler: none diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index f87fcfb2592838..9bed54562d2d1b 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -70,7 +70,7 @@ jobs: with: arch: ${{ matrix.arch }} - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 82a272f6e08038..a54e93693e84b9 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -99,7 +99,7 @@ jobs: run: | echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 7017af7b1fd0a0..88ee91c518a3e6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -59,7 +59,7 @@ jobs: - run: md build working-directory: - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: # windows-11-arm has only 3.4.1, 3.4.2, 3.4.3, head ruby-version: ${{ !endsWith(matrix.os, 'arm') && '3.1' || '3.4' }} diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index 1908eccbb308fa..04a009dd6fa89f 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -133,7 +133,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index e64de62c052815..f6ed57353a7f0a 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -93,7 +93,7 @@ jobs: rustup install ${{ matrix.rust_version }} --profile minimal rustup default ${{ matrix.rust_version }} - - uses: taiki-e/install-action@eea29cff9a2b68892c0845ae3e4f45fc47ee9354 # v2.75.13 + - uses: taiki-e/install-action@5939f3337e40968c39aa70f5ecb1417a92fb25a0 # v2.75.15 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index dd486677ef49e7..4ad98b514b6937 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -114,12 +114,12 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + - uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 with: ruby-version: '3.1' bundler: none - - uses: taiki-e/install-action@eea29cff9a2b68892c0845ae3e4f45fc47ee9354 # v2.75.13 + - uses: taiki-e/install-action@5939f3337e40968c39aa70f5ecb1417a92fb25a0 # v2.75.15 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/NEWS.md b/NEWS.md index ad755e2e54592b..0c1efe7c969a54 100644 --- a/NEWS.md +++ b/NEWS.md @@ -70,6 +70,7 @@ releases. * RubyGems 4.1.0.dev * bundler 4.1.0.dev * erb 6.0.3 + * 6.0.1 to [v6.0.2][erb-v6.0.2], [v6.0.3][erb-v6.0.3] * json 2.19.3 * 2.18.0 to [v2.18.1][json-v2.18.1], [v2.19.0][json-v2.19.0], [v2.19.1][json-v2.19.1], [v2.19.2][json-v2.19.2], [v2.19.3][json-v2.19.3] * openssl 4.0.1 @@ -175,6 +176,8 @@ A lot of work has gone into making Ractors more stable, performant, and usable. [prism-v1.8.1]: https://github.com/ruby/prism/releases/tag/v1.8.1 [zlib-v3.2.3]: https://github.com/ruby/zlib/releases/tag/v3.2.3 [pstore-v0.2.1]: https://github.com/ruby/pstore/releases/tag/v0.2.1 +[erb-v6.0.2]: https://github.com/ruby/erb/releases/tag/v6.0.2 +[erb-v6.0.3]: https://github.com/ruby/erb/releases/tag/v6.0.3 [json-v2.18.1]: https://github.com/ruby/json/releases/tag/v2.18.1 [json-v2.19.0]: https://github.com/ruby/json/releases/tag/v2.19.0 [json-v2.19.1]: https://github.com/ruby/json/releases/tag/v2.19.1 diff --git a/doc/syntax/calling_methods.rdoc b/doc/syntax/calling_methods.rdoc index 76babcc3dcd969..a24c5fbf1f5ad9 100644 --- a/doc/syntax/calling_methods.rdoc +++ b/doc/syntax/calling_methods.rdoc @@ -425,7 +425,7 @@ as keyword arguments: name = Name.new('Jane Doe') p(**name) - # Prints: {name: "Jane", last: "Doe"} + # Prints: {first: "Jane", last: "Doe"} Unlike * operator, ** raises an error when used on an object that doesn't respond to #to_hash. The one exception is diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index c705f9eac0c712..fabb308043c9c4 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -22,6 +22,12 @@ Gem::Specification.new do |spec| spec.metadata["changelog_uri"] = "<%= config[:changelog_uri] %>" <%- end -%> + # Uncomment the line below to require MFA for gem pushes. + # This helps protect your gem from supply chain attacks by ensuring + # no one can publish a new version without multi-factor authentication. + # See: https://guides.rubygems.org/mfa-requirement-opt-in/ + # spec.metadata["rubygems_mfa_required"] = "true" + # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. gemspec = File.basename(__FILE__) diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb index 5df3b58202791c..f00aa276c463d2 100644 --- a/spec/bundler/commands/newgem_spec.rb +++ b/spec/bundler/commands/newgem_spec.rb @@ -650,6 +650,15 @@ def create_temporary_dir(dir) to match(/example\.com/) end + it "includes a commented-out rubygems_mfa_required metadata hint" do + bundle "gem #{gem_name}" + + gemspec_contents = bundled_app("#{gem_name}/#{gem_name}.gemspec").read + + expect(gemspec_contents).to include('# spec.metadata["rubygems_mfa_required"] = "true"') + expect(gemspec_contents).to include("https://guides.rubygems.org/mfa-requirement-opt-in/") + end + it "sets a minimum ruby version" do bundle "gem #{gem_name}" diff --git a/test/json/json_ryu_fallback_test.rb b/test/json/json_ryu_fallback_test.rb index 2262a6f5947540..152de7e360dc6e 100644 --- a/test/json/json_ryu_fallback_test.rb +++ b/test/json/json_ryu_fallback_test.rb @@ -174,10 +174,10 @@ def test_large_exponent_numbers assert_equal Float::INFINITY, JSON.parse("1e4294967295") assert_equal Float::INFINITY, JSON.parse("1e4294967297") - assert_equal -Float::INFINITY, JSON.parse("-1e4294967296") - assert_equal -0.0, JSON.parse("-1e-4294967296") - assert_equal -0.0, JSON.parse("-99999999999999999e-4294967296") - assert_equal -Float::INFINITY, JSON.parse("-1e4294967295") - assert_equal -Float::INFINITY, JSON.parse("-1e4294967297") + assert_equal(-Float::INFINITY, JSON.parse("-1e4294967296")) + assert_equal(-0.0, JSON.parse("-1e-4294967296")) + assert_equal(-0.0, JSON.parse("-99999999999999999e-4294967296")) + assert_equal(-Float::INFINITY, JSON.parse("-1e4294967295")) + assert_equal(-Float::INFINITY, JSON.parse("-1e4294967297")) end end diff --git a/tool/auto_review_pr.rb b/tool/auto_review_pr.rb index a8f64fab9d1f79..38adf9fdb7fe42 100755 --- a/tool/auto_review_pr.rb +++ b/tool/auto_review_pr.rb @@ -38,6 +38,9 @@ class AutoReviewPR UPSTREAM_COMMENT_PREFIX = 'The following files are maintained in the following upstream repositories:' UPSTREAM_COMMENT_SUFFIX = 'Please file a pull request to the above instead. Thank you!' + REDMINE_TICKET_PATTERN = /\[(Bug|Feature|Misc)\s*#(\d+)\]/ + REDMINE_COMMENT_PREFIX = 'This pull request references the following Redmine tickets:' + FORK_COMMENT_PREFIX = 'It looks like this pull request was filed from a branch in ruby/ruby.' FORK_COMMENT_BODY = <<~COMMENT #{FORK_COMMENT_PREFIX} @@ -57,8 +60,10 @@ def initialize(client) def review(pr_number) existing_comments = fetch_existing_comments(pr_number) - review_non_fork_branch(pr_number, existing_comments) + pr = @client.get("/repos/#{REPO}/pulls/#{pr_number}") + review_non_fork_branch(pr_number, pr, existing_comments) review_upstream_repos(pr_number, existing_comments) + review_redmine_links(pr_number, pr, existing_comments) end private @@ -78,13 +83,12 @@ def post_comment(pr_number, comment) end # Suggest re-filing from a fork if the PR branch is in ruby/ruby itself - def review_non_fork_branch(pr_number, existing_comments) + def review_non_fork_branch(pr_number, pr, existing_comments) if already_commented?(existing_comments, FORK_COMMENT_PREFIX) puts "Skipped: The PR ##{pr_number} already has a fork branch comment." return end - pr = @client.get("/repos/#{REPO}/pulls/#{pr_number}") head_repo = pr.dig(:head, :repo, :full_name) if head_repo != REPO puts "Skipped: The PR ##{pr_number} is already from a fork (#{head_repo})." @@ -120,6 +124,32 @@ def review_upstream_repos(pr_number, existing_comments) post_comment(pr_number, format_upstream_comment(upstream_repos)) end + def review_redmine_links(pr_number, pr, existing_comments) + if already_commented?(existing_comments, REDMINE_COMMENT_PREFIX) + puts "Skipped: The PR ##{pr_number} already has a Redmine links comment." + return + end + + text = "#{pr[:title]}\n#{pr[:body]}" + + tickets = text.scan(REDMINE_TICKET_PATTERN).uniq + tickets.reject! { |_, number| text.include?("https://bugs.ruby-lang.org/issues/#{number}") } + if tickets.empty? + puts "Skipped: The PR ##{pr_number} doesn't reference any Redmine tickets." + return + end + + post_comment(pr_number, format_redmine_comment(tickets)) + end + + def format_redmine_comment(tickets) + comment = +"#{REDMINE_COMMENT_PREFIX}\n\n" + tickets.each do |type, number| + comment << "* [#{type} ##{number}](https://bugs.ruby-lang.org/issues/#{number})\n" + end + comment + end + def format_upstream_comment(upstream_repos) comment = +'' comment << "#{UPSTREAM_COMMENT_PREFIX}\n\n"