diff --git a/CHANGELOG.md b/CHANGELOG.md index a496c1900..682ca72b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Default Ruby version is now 3.3.7 (https://github.com/heroku/heroku-buildpack-ruby/pull/1534) +- Default bundler version (when no version present in the `Gemfile.lock`) is now bundler `2.3.x` which is currently `2.3.25` (https://github.com/heroku/heroku-buildpack-ruby/pull/1534) ## [v288] - 2025-01-06 diff --git a/Gemfile b/Gemfile index c887ccc55..8aa727aa0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '>= 3.1', '< 3.3' +ruby "3.3.7" group :development, :test do gem "toml-rb" diff --git a/Gemfile.lock b/Gemfile.lock index 4def54426..c4490f416 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,7 +73,7 @@ DEPENDENCIES toml-rb RUBY VERSION - ruby 3.1.6p260 + ruby 3.3.7p260 BUNDLED WITH 2.5.11 diff --git a/buildpack.toml b/buildpack.toml index 253627574..0a19ee586 100644 --- a/buildpack.toml +++ b/buildpack.toml @@ -1,6 +1,6 @@ [buildpack] name = "Ruby" -ruby_version = "3.1.6" +ruby_version = "3.3.7" [publish.Ignore] files = [ diff --git a/changelogs/unreleased/bundler_default.md b/changelogs/unreleased/bundler_default.md new file mode 100644 index 000000000..03f692719 --- /dev/null +++ b/changelogs/unreleased/bundler_default.md @@ -0,0 +1,13 @@ +## Ruby applications with no specified bundler versions now receive Bundler 2.x + +Previously applications with no `BUNDLED WITH` in their `Gemfile.lock` would receive bundler `1.x`. They will now receive the new [default bundler version](https://devcenter.heroku.com/articles/ruby-support-reference#default-bundler-version) `2.3.x`. + +It is strongly recommended that you have both a `RUBY VERSION` and `BUNDLED WITH` version listed in your `Gemfile.lock`. If you do not have those values, you can generate them and commit them to git: + +``` +$ bundle update --ruby +$ git add Gemfile.lock +$ git commit -m "Update Gemfile.lock" +``` + +Applications without these values specified in the `Gemfile.lock` may break unexpectedly when the defaults change. diff --git a/changelogs/unreleased/default_ruby.md b/changelogs/unreleased/default_ruby.md new file mode 100644 index 000000000..9aaf2a5fc --- /dev/null +++ b/changelogs/unreleased/default_ruby.md @@ -0,0 +1,3 @@ +## Default Ruby version for new apps is now 3.3.7 + +The [default Ruby version for new Ruby applications is 3.3.7](https://devcenter.heroku.com/articles/ruby-support#default-ruby-version-for-new-apps). You’ll only get the default if the application does not specify a ruby version. diff --git a/hatchet.json b/hatchet.json index 6968997e6..9f60b5ee9 100644 --- a/hatchet.json +++ b/hatchet.json @@ -4,44 +4,31 @@ "sharpstone/asset_precompile_pass", "sharpstone/asset_precompile_not_found", "sharpstone/no_rakefile", - "sharpstone/bad_rakefile", - "sharpstone/default_with_rakefile" + "sharpstone/bad_rakefile" ], "bundler": [ - "sharpstone/problem_gemfile_version", "sharpstone/git_gemspec", "sharpstone/no_lockfile", - "sharpstone/sqlite3_gemfile", - "sharpstone/nokogiri_160" + "sharpstone/sqlite3_gemfile" ], "ruby": [ "sharpstone/ruby_version_does_not_exist", - "sharpstone/ruby_193_jruby_17161_jdk7", - "sharpstone/ruby_25", "sharpstone/jruby-minimal", "sharpstone/empty-procfile", - "sharpstone/bad_ruby_version", - "sharpstone/activerecord41_scaffold", - "sharpstone/libpq_connection_error" - ], - "jruby": [ - "sharpstone/jruby_naether" + "sharpstone/bad_ruby_version" ], "rack": [ - "sharpstone/default_ruby", - "sharpstone/mri_187_nokogiri", - "sharpstone/mri_192" + "sharpstone/default_ruby" ], "rails_versions": [ "sharpstone/rails_lts_23_default_ruby", "sharpstone/rails3_default_ruby", "sharpstone/rails4_windows_mri193", "sharpstone/rails42_default_ruby", - "sharpstone/active_storage_non_local", - "sharpstone/active_storage_local", - "sharpstone/sprockets_asset_compile_true", "sharpstone/rails61", - "sharpstone/rails-jsbundling" + "sharpstone/rails-jsbundling", + "sharpstone/rails_8_ruby_schema", + "sharpstone/rails_8_sql_schema" ], "heroku": [ "heroku/ruby-getting-started" @@ -50,10 +37,7 @@ "sharpstone/minimal_webpacker" ], "ci": [ - "sharpstone/rails5_ruby_schema_format", "sharpstone/heroku-ci-json-example", - "sharpstone/rails5_sql_schema_format", - "sharpstone/ruby_no_rails_test", - "sharpstone/activerecord_rake_tasks_does_not_exist" + "sharpstone/ruby_no_rails_test" ] } diff --git a/hatchet.lock b/hatchet.lock index b1fa5cbc5..cf21facff 100644 --- a/hatchet.lock +++ b/hatchet.lock @@ -3,52 +3,34 @@ - 7755e19caf122e1373bce73ffe9b333e9411d732 - - "./repos/bundler/no_lockfile" - 1947ce9a9c276d5df1c323b2ad78d1d85c7ab4c0 -- - "./repos/bundler/nokogiri_160" - - d9a761776be43e1c685f98ef13c6ef1ee0292267 -- - "./repos/bundler/problem_gemfile_version" - - abc25a7b582a720b99148a1c8753d0d7452254bb - - "./repos/bundler/sqlite3_gemfile" - 116db685f54dae18f703b3beb90e64fdbddb048d -- - "./repos/ci/activerecord_rake_tasks_does_not_exist" - - a6b711be6921cf7a0aa4e31269c37965799ea110 - - "./repos/ci/heroku-ci-json-example" - - 4e5410a7381f486ba3df7739e02e52f32fdd4dda -- - "./repos/ci/rails5_ruby_schema_format" - - 8b8a3a7850bdba29bdefc70c0f80f35a9e6c96ae -- - "./repos/ci/rails5_sql_schema_format" - - ee81b300a1019b47bbcaec0a512932df7dc23bc0 + - 728cc99c8e80290cc07441d61a8bcd4596e696fb - - "./repos/ci/ruby_no_rails_test" - - 3916137106d59b008b67d738abe6a1438f8fbde6 + - c5925ab061f65433ec5dcbc890975f580e74c5ce - - "./repos/heroku/ruby-getting-started" - main -- - "./repos/jruby/jruby_naether" - - 4a11f8af5a3cca21f3659394e5bbac3cca9b6a2c - - "./repos/node/minimal_webpacker" - - 9152fec98df59a0bf8a5478ed428841ee135acbb + - d659577a612b12ddb44ce34e28124c025ecb22f3 - - "./repos/rack/default_ruby" - master -- - "./repos/rack/mri_187_nokogiri" - - 3fcce9c85bf560dba285cc385ae9845729195826 -- - "./repos/rack/mri_192" - - ef6b5ccf8aa2a8f5e3745934e3580dc0bd2d6d4b -- - "./repos/rails_versions/active_storage_local" - - 18853ba7dda61745995740b4ca6f5f90bbd8afba -- - "./repos/rails_versions/active_storage_non_local" - - 86dddf0127043abba1cb2890590a1d38f111edbd - - "./repos/rails_versions/rails-jsbundling" - - c58178e061d9846386ca34ea31c99f6e6bb8dbf7 + - 50e9fdf7c3a37623c676989ddebac4ee5349734b - - "./repos/rails_versions/rails3_default_ruby" - - a6b44db674c0d3538633989295e2cfd5e8e1ba0d + - 984b6d02353519251c2d1e885bf8914a2584f26a - - "./repos/rails_versions/rails42_default_ruby" - - dfa0f0133dafa62064968ea2efb6432f54350138 + - fbdaf031823f09d1514ec1d55dcb04ca2f4264ca - - "./repos/rails_versions/rails4_windows_mri193" - f4c7b6209835050468bbb87827acf652b8f4d8ce - - "./repos/rails_versions/rails61" - - e896f51e679eaf2204aa4fab6d038103fc622aed + - 47828a3e8c79b7869ca0d9a3afa4be065fa46e96 +- - "./repos/rails_versions/rails_8_ruby_schema" + - a993a3f00c8e09f733bc3b783f7e37148d0af1d4 +- - "./repos/rails_versions/rails_8_sql_schema" + - d5089812196931e858a97119de1640a86825a272 - - "./repos/rails_versions/rails_lts_23_default_ruby" - - 7178b2f97d3b2b3170b390d997dcb212dd52cd30 -- - "./repos/rails_versions/sprockets_asset_compile_true" - - 6f3aa208046a5c79e84fc272f52f5ebb7b775755 + - f3597fd6f0887763eb65ec2f83a5e9a5155d5625 - - "./repos/rake/asset_precompile_fail" - 16f7834331d6bb3fc5c284130b14eb1ff74d99d5 - - "./repos/rake/asset_precompile_not_found" @@ -57,23 +39,13 @@ - ce976c727d9f477957c499f39f4cf9603c378103 - - "./repos/rake/bad_rakefile" - 3cb9c7bf6494c59bd25fa74c2aa4531119e12a46 -- - "./repos/rake/default_with_rakefile" - - c6e0c4db8dcccb47e11d496e17adbc2dafc80dd8 - - "./repos/rake/no_rakefile" - d2ec2084b825218418dac54bd6276ac896b31cdd -- - "./repos/ruby/activerecord41_scaffold" - - 6e4662c44b49e2c3c9429f00e7e7f4708142b03f - - "./repos/ruby/bad_ruby_version" - 7bf3470265a87ea6361640aa4bfce6ce3b743520 - - "./repos/ruby/empty-procfile" - 7cae0aae424c2028b81b5d37ee24d42db8e545b9 - - "./repos/ruby/jruby-minimal" - f79860bc2866449fe065484f1542aaadd3f7cfd2 -- - "./repos/ruby/libpq_connection_error" - - c211c245f09d8335a520cd7a0b5360897d4988eb -- - "./repos/ruby/ruby_193_jruby_17161_jdk7" - - c1b632f8a96cf9b902f5cdcd7a190d46544a8144 -- - "./repos/ruby/ruby_25" - - 0cb3df80d55b61e9417f2ac00adb06e15ae37982 - - "./repos/ruby/ruby_version_does_not_exist" - 9b6ad8e3b4fa7850393a5f232bb40ff3cd414d8b diff --git a/lib/language_pack/base.rb b/lib/language_pack/base.rb index c57ae0324..c0fdea319 100644 --- a/lib/language_pack/base.rb +++ b/lib/language_pack/base.rb @@ -112,7 +112,7 @@ def build_release def write_release_yaml release = build_release - FileUtils.mkdir("tmp") unless File.exists?("tmp") + FileUtils.mkdir("tmp") unless File.exist?("tmp") File.open("tmp/heroku-buildpack-release-step.yml", 'w') do |f| f.write(release.to_yaml) end diff --git a/lib/language_pack/cache.rb b/lib/language_pack/cache.rb index 9862e22ac..18754a408 100644 --- a/lib/language_pack/cache.rb +++ b/lib/language_pack/cache.rb @@ -87,6 +87,6 @@ def cache_copy(from,to) def exists?(path) return unless @cache_base - File.exists?(@cache_base + path) + File.exist?(@cache_base + path) end end diff --git a/lib/language_pack/fetcher.rb b/lib/language_pack/fetcher.rb index d2a79c2e5..4f1edd891 100644 --- a/lib/language_pack/fetcher.rb +++ b/lib/language_pack/fetcher.rb @@ -28,7 +28,7 @@ def fetch(path) def fetch_untar(path, files_to_extract = nil, strip_components: 0) curl = curl_command("#{@host_url.join(path)} -s -o") - tar_cmd = ["tar zxf - #{files_to_extract}", "--strip #{strip_components}"] + tar_cmd = ["tar", "--strip-components=#{strip_components}", "-xzf", "- #{files_to_extract}"] run! "#{curl} - | #{tar_cmd.join(" ")}", error_class: FetchError, max_attempts: 3 diff --git a/lib/language_pack/helpers/bundler_wrapper.rb b/lib/language_pack/helpers/bundler_wrapper.rb index 64d030cfe..47ee08d84 100644 --- a/lib/language_pack/helpers/bundler_wrapper.rb +++ b/lib/language_pack/helpers/bundler_wrapper.rb @@ -42,6 +42,10 @@ class LanguagePack::Helpers::BundlerWrapper BLESSED_BUNDLER_VERSIONS["2.4"] = "2.4.22" BLESSED_BUNDLER_VERSIONS["2.5"] = "2.5.23" BLESSED_BUNDLER_VERSIONS["2.6"] = "2.6.2" + + DEFAULT_VERSION = BLESSED_BUNDLER_VERSIONS["2.3"] + + # Convert arbitrary `..x` versions BLESSED_BUNDLER_VERSIONS.default_proc = Proc.new do |hash, key| if Gem::Version.new(key).segments.first == 1 hash["1"] @@ -65,7 +69,7 @@ def self.detect_bundler_version(contents: ) minor = version_match[:minor] BLESSED_BUNDLER_VERSIONS["#{major}.#{minor}"] else - BLESSED_BUNDLER_VERSIONS["1"] + DEFAULT_VERSION end end @@ -91,7 +95,7 @@ def initialize(version_hash, major_minor) msg << "\n" msg << "```\n" msg << "BUNDLED WITH\n" - msg << " #{version_hash["1"]}\n" + msg << " #{DEFAULT_VERSION}\n" msg << "```\n" super msg end @@ -239,7 +243,7 @@ def bundler_version_escape_valve! private def fetch_bundler - return true if Dir.exists?(bundler_path) + return true if Dir.exist?(bundler_path) topic("Installing bundler #{@version}") bundler_version_escape_valve! diff --git a/lib/language_pack/metadata.rb b/lib/language_pack/metadata.rb index 56ab27e53..85388b05d 100644 --- a/lib/language_pack/metadata.rb +++ b/lib/language_pack/metadata.rb @@ -26,7 +26,7 @@ def read(key) def exists?(key) full_key = "#{FOLDER}/#{key}" - File.exists?(full_key) && !Dir.exists?(full_key) + File.exist?(full_key) && !Dir.exist?(full_key) end alias_method :include?, :exists? diff --git a/lib/language_pack/no_lockfile.rb b/lib/language_pack/no_lockfile.rb index 0bee9accb..552c6fb9d 100644 --- a/lib/language_pack/no_lockfile.rb +++ b/lib/language_pack/no_lockfile.rb @@ -3,7 +3,7 @@ class LanguagePack::NoLockfile < LanguagePack::Ruby def self.use? - !File.exists?("Gemfile.lock") + !File.exist?("Gemfile.lock") end def name diff --git a/lib/language_pack/rails3.rb b/lib/language_pack/rails3.rb index 33d02c1d3..7d6d1641e 100644 --- a/lib/language_pack/rails3.rb +++ b/lib/language_pack/rails3.rb @@ -169,7 +169,7 @@ def install_plugins # runs the tasks for the Rails 3.1 asset pipeline def run_assets_precompile_rake_task log("assets_precompile") do - if File.exists?("public/assets/manifest.yml") + if File.exist?("public/assets/manifest.yml") puts "Detected manifest.yml, assuming assets were compiled locally" return true end diff --git a/lib/language_pack/ruby.rb b/lib/language_pack/ruby.rb index bdb72bdb6..08d963ccb 100644 --- a/lib/language_pack/ruby.rb +++ b/lib/language_pack/ruby.rb @@ -629,7 +629,7 @@ def uninstall_binary(path) # users should be using `bundle pack` instead. # https://github.com/heroku/heroku-buildpack-ruby/issues/21 def remove_vendor_bundle - if File.exists?("vendor/bundle") + if File.exist?("vendor/bundle") warn(<<-WARNING) Removing `vendor/bundle`. Checking in `vendor/bundle` is not supported. Please remove this directory @@ -1130,7 +1130,7 @@ def valid_bundler_cache?(path, metadata) end # fix bug from v37 deploy - if File.exists?("#{path}/vendor/ruby_version") + if File.exist?("#{path}/vendor/ruby_version") puts "Broken cache detected. Purging build cache." cache.clear("vendor") FileUtils.rm_rf("#{path}/vendor/ruby_version") @@ -1148,7 +1148,7 @@ def valid_bundler_cache?(path, metadata) end # fix git gemspec bug from Bundler 1.3.0+ upgrade - if File.exists?(bundler_cache) && !metadata.include?(:bundler_version) && !run("find #{path}/vendor/bundle/*/*/bundler/gems/*/ -name *.gemspec").include?("No such file or directory") + if File.exist?(bundler_cache) && !metadata.include?(:bundler_version) && !run("find #{path}/vendor/bundle/*/*/bundler/gems/*/ -name *.gemspec").include?("No such file or directory") return [false, "Old bundler cache detected. Clearing bundler cache."] end @@ -1220,7 +1220,7 @@ def load_bundler_cache end # fix bug from v37 deploy - if File.exists?("vendor/ruby_version") + if File.exist?("vendor/ruby_version") puts "Broken cache detected. Purging build cache." cache.clear("vendor") FileUtils.rm_rf("vendor/ruby_version") @@ -1237,7 +1237,7 @@ def load_bundler_cache end # fix git gemspec bug from Bundler 1.3.0+ upgrade - if File.exists?(bundler_cache) && !@metadata.exists?(bundler_version_cache) && !run("find vendor/bundle/*/*/bundler/gems/*/ -name *.gemspec").include?("No such file or directory") + if File.exist?(bundler_cache) && !@metadata.exists?(bundler_version_cache) && !run("find vendor/bundle/*/*/bundler/gems/*/ -name *.gemspec").include?("No such file or directory") puts "Old bundler cache detected. Clearing bundler cache." purge_bundler_cache end diff --git a/lib/language_pack/ruby_version.rb b/lib/language_pack/ruby_version.rb index 70ba0886e..1628b6cc3 100644 --- a/lib/language_pack/ruby_version.rb +++ b/lib/language_pack/ruby_version.rb @@ -12,8 +12,8 @@ def initialize(output = "") end end - BOOTSTRAP_VERSION_NUMBER = "3.1.6".freeze - DEFAULT_VERSION_NUMBER = "3.1.6".freeze + BOOTSTRAP_VERSION_NUMBER = "3.3.7".freeze + DEFAULT_VERSION_NUMBER = "3.3.7".freeze DEFAULT_VERSION = "ruby-#{DEFAULT_VERSION_NUMBER}".freeze LEGACY_VERSION_NUMBER = "1.9.2".freeze LEGACY_VERSION = "ruby-#{LEGACY_VERSION_NUMBER}".freeze diff --git a/lib/language_pack/shell_helpers.rb b/lib/language_pack/shell_helpers.rb index 54d11d67f..0b1e380dc 100644 --- a/lib/language_pack/shell_helpers.rb +++ b/lib/language_pack/shell_helpers.rb @@ -255,7 +255,7 @@ def puts(message) end $stdout.flush - rescue ArgumentError => e + rescue ArgumentError, Encoding::CompatibilityError => e error_message = e.message raise e if error_message !~ /invalid byte sequence/ diff --git a/lib/language_pack/test/rails7.rb b/lib/language_pack/test/rails7.rb index 3af3c5010..97fd20ea8 100644 --- a/lib/language_pack/test/rails7.rb +++ b/lib/language_pack/test/rails7.rb @@ -4,6 +4,6 @@ class LanguagePack::Rails7 # Rails removed the db:schema:load_if_ruby and `db:structure:load_if_sql` tasks # they've been replaced by `db:schema:load` instead def db_prepare_test_rake_tasks - ["db:schema:load", "db:migrate"].map {|name| rake.task(name) } + ["db:schema:load", "db:migrate"].map { |name| rake.task(name) } end end diff --git a/spec/hatchet/bundler_spec.rb b/spec/hatchet/bundler_spec.rb index e343e1ed6..8d8a122ae 100644 --- a/spec/hatchet/bundler_spec.rb +++ b/spec/hatchet/bundler_spec.rb @@ -9,29 +9,4 @@ end end end - - it "deploys with version 1.x" do - abi_version = LanguagePack::RubyVersion::DEFAULT_VERSION_NUMBER.dup - abi_version[-1] = "0" # turn 2.6.6 into 2.6.0 - pending("Must enable HATCHET_EXPENSIVE_MODE") unless ENV["HATCHET_EXPENSIVE_MODE"] - - Hatchet::Runner.new("default_ruby").tap do |app| - app.before_deploy do - run!(%Q{printf "\nBUNDLED WITH\n 1.0.1\n" >> Gemfile.lock}) - end - app.deploy do - expect(app.output).to match("Installing dependencies using bundler 1.") - expect(app.output).to match("BUNDLE_GLOBAL_PATH_APPENDS_RUBY_SCOPE=1") - - # app.run_multi("ls vendor/bundle/ruby/#{abi_version}/gems") do |ls_output| - # expect(ls_output).to match("rake-") - # end - - app.run("which -a rake") do |which_rake| - expect(which_rake).to include("/app/vendor/bundle/bin/rake") - expect(which_rake).to include("/app/vendor/bundle/ruby/#{abi_version}/bin/rake") - end - end - end - end end diff --git a/spec/hatchet/ci_spec.rb b/spec/hatchet/ci_spec.rb index d2330e8fd..599fe372f 100644 --- a/spec/hatchet/ci_spec.rb +++ b/spec/hatchet/ci_spec.rb @@ -10,24 +10,46 @@ end end - it "Works with Rails 5 ruby schema apps" do - Hatchet::Runner.new("rails5_ruby_schema_format", stack: "heroku-20").tap do |app| + it "Works with Rails: ruby schema apps" do + Hatchet::Runner.new("rails_8_ruby_schema", stack: "heroku-24").tap do |app| app.before_deploy do - Pathname("Gemfile").write("ruby '2.7.5'", mode: "a") + Pathname("app.json").write(<<~EOF) + { + "environments": { + "test": { + "addons":[ + "heroku-postgresql:in-dyno" + ] + } + } + } + EOF end + app.run_ci do |test_run| - expect(test_run.output).to match("db:schema:load_if_ruby completed") + expect(test_run.output).to match("db:schema:load completed") end end end - it "Works with Rails 5 SQL schema apps" do - Hatchet::Runner.new("rails5_sql_schema_format", stack: "heroku-20").tap do |app| + it "Works with Rails: SQL schema apps" do + Hatchet::Runner.new("rails_8_sql_schema", stack: "heroku-24").tap do |app| app.before_deploy do - Pathname("Gemfile").write("ruby '2.7.5'", mode: "a") + Pathname("app.json").write(<<~EOF) + { + "environments": { + "test": { + "addons":[ + "heroku-postgresql:in-dyno" + ] + } + } + } + EOF end + app.run_ci do |test_run| - expect(test_run.output).to match("db:structure:load_if_sql completed") + expect(test_run.output).to match("db:schema:load completed") end end end @@ -43,12 +65,12 @@ it "Uses the cache" do runner = Hatchet::Runner.new("ruby_no_rails_test") runner.run_ci do |test_run| - expect(test_run.output).to match("Fetching rake") + fetching_rake = "Fetching rake" + expect(test_run.output).to match(fetching_rake) test_run.run_again - expect(test_run.output).to match("Using rake") - expect(test_run.output).to_not match("Fetching rake") + expect(test_run.output).to_not match(fetching_rake) end end end diff --git a/spec/hatchet/rails23_spec.rb b/spec/hatchet/rails23_spec.rb index a605642ed..87e5eee51 100644 --- a/spec/hatchet/rails23_spec.rb +++ b/spec/hatchet/rails23_spec.rb @@ -5,10 +5,6 @@ skip("Need RAILS_LTS_CREDS env var set") unless ENV["RAILS_LTS_CREDS"] Hatchet::Runner.new('rails_lts_23_default_ruby', config: rails_lts_config, stack: rails_lts_stack).tap do |app| - app.before_deploy do - Pathname("Gemfile").write("ruby '2.7.2'", mode: "a") - end - app.deploy do # assert deploy is successful end diff --git a/spec/hatchet/rails3_spec.rb b/spec/hatchet/rails3_spec.rb index 7593169dc..3450d9a79 100644 --- a/spec/hatchet/rails3_spec.rb +++ b/spec/hatchet/rails3_spec.rb @@ -6,7 +6,8 @@ Hatchet::Runner.new("rails3_default_ruby", config: rails_lts_config, stack: rails_lts_stack).tap do |app| app.before_deploy do - Pathname("Gemfile").write("ruby '2.7.2'", mode: "a") + set_lts_ruby_version + set_bundler_version(version: :default) end app.deploy do diff --git a/spec/hatchet/rails4_spec.rb b/spec/hatchet/rails4_spec.rb index e7b851028..d29633cb1 100644 --- a/spec/hatchet/rails4_spec.rb +++ b/spec/hatchet/rails4_spec.rb @@ -6,7 +6,8 @@ Hatchet::Runner.new("rails42_default_ruby", config: rails_lts_config, stack: rails_lts_stack).tap do |app| app.before_deploy do - Pathname("Gemfile").write("ruby '2.7.2'", mode: "a") + set_lts_ruby_version + set_bundler_version(version: :default) end app.deploy do # it Don't over-write database.yml @@ -24,7 +25,8 @@ Hatchet::Runner.new("rails42_default_ruby", config: rails_lts_config, stack: rails_lts_stack).tap do |app| app.before_deploy do - Pathname("Gemfile").write("ruby '2.7.2'", mode: "a") + set_lts_ruby_version + set_bundler_version(version: :default) Pathname("public/assets/manifest-ccf61eade4793995271564a4767ce6b6.json").tap {|p| p.dirname.mkpath; FileUtils.touch(p) } end @@ -39,7 +41,8 @@ Hatchet::Runner.new("rails42_default_ruby", config: rails_lts_config, stack: rails_lts_stack).tap do |app| app.before_deploy do - Pathname("Gemfile").write("ruby '2.7.2'", mode: "a") + set_lts_ruby_version + set_bundler_version(version: :default) Pathname("public/assets/.sprockets-manifest-040763ccc5036260c52c6adcf77d73f7.json").tap {|p| p.dirname.mkpath; FileUtils.touch(p) } end diff --git a/spec/hatchet/rails6_spec.rb b/spec/hatchet/rails6_spec.rb index b25a1ef1c..9373d1fa8 100644 --- a/spec/hatchet/rails6_spec.rb +++ b/spec/hatchet/rails6_spec.rb @@ -17,7 +17,7 @@ run! %Q{echo 'task "assets:precompile" do ; end' > Rakefile} end - Hatchet::Runner.new('rails61', before_deploy: before_deploy).deploy do |app| + Hatchet::Runner.new('rails61', before_deploy: before_deploy, config: rails_lts_config, stack: rails_lts_stack).deploy do |app| expect(app.output).to match("Fetching railties 6") expect(app.output).to match("rake assets:precompile") diff --git a/spec/hatchet/rubies_spec.rb b/spec/hatchet/rubies_spec.rb index 55e7c23b0..402ee4ef2 100644 --- a/spec/hatchet/rubies_spec.rb +++ b/spec/hatchet/rubies_spec.rb @@ -1,17 +1,5 @@ require_relative '../spec_helper' -describe "Ruby Versions on cedar-14" do - it "should deploy jruby 1.7.16.1 (jdk 7) properly on cedar-14 with sys props file" do - pending("Port this to a more recent stack") - - app = Hatchet::Runner.new("ruby_193_jruby_17161_jdk7", stack: "cedar-14") - app.deploy do |app| - expect(app.output).to match("Installing JVM: openjdk-7") - expect(app.output).not_to include("OpenJDK 64-Bit Server VM warning") - end - end -end - describe "Ruby versions" do it "should deploy jdk on heroku-24" do Hatchet::Runner.new("default_ruby", stack: "heroku-24").tap do |app| @@ -62,17 +50,20 @@ describe "Upgrading ruby apps" do it "works when changing versions" do + version = "3.3.1" + expect(version).to_not eq(LanguagePack::RubyVersion::DEFAULT_VERSION_NUMBER) app = Hatchet::Runner.new("default_ruby", stack: DEFAULT_STACK) app.deploy do |app| + # default version expect(app.run("env | grep MALLOC_ARENA_MAX")).to match("MALLOC_ARENA_MAX=2") expect(app.run("env | grep DISABLE_SPRING")).to match("DISABLE_SPRING=1") # Deploy again - run!(%Q{echo "ruby '2.7.5'" >> Gemfile}) + run!(%Q{echo "ruby '#{version}'" >> Gemfile}) run!("git add -A; git commit -m update-ruby") app.push! - expect(app.output).to match("2.7.5") - expect(app.run("ruby -v")).to match("2.7.5") + expect(app.output).to match(version) + expect(app.run("ruby -v")).to match(version) expect(app.output).to match("Ruby version change detected") end end diff --git a/spec/hatchet/ruby_spec.rb b/spec/hatchet/ruby_spec.rb index e221c4205..580219577 100644 --- a/spec/hatchet/ruby_spec.rb +++ b/spec/hatchet/ruby_spec.rb @@ -155,8 +155,6 @@ Pathname("Gemfile").write(<<~'EOF') source "https://rubygems.org" - ruby "~> 3.0.0" - gem "rake" EOF @@ -174,10 +172,7 @@ rake RUBY VERSION - ruby 3.0.3p157 - - BUNDLED WITH - 2.3.7 + ruby 3.3.1p0 EOF Pathname("Rakefile").write(<<~'EOF') @@ -197,7 +192,9 @@ end app.deploy do |app| - expect(app.output).to match("cd version ruby 3.0.3") + expected = "3.3.1" + expect(expected).to_not eq(LanguagePack::RubyVersion::DEFAULT_VERSION_NUMBER) + expect(app.output).to match("cd version ruby #{expected}") expect(app.run("which ruby").strip).to eq("/app/bin/ruby") end @@ -207,12 +204,15 @@ describe "bundler ruby version matcher" do it "installs a version even when not present in the Gemfile.lock" do + version = "3.3.1" + expect(version).to_not eq(LanguagePack::RubyVersion::DEFAULT_VERSION_NUMBER) + Hatchet::Runner.new('default_ruby', stack: DEFAULT_STACK).tap do |app| app.before_deploy do - Pathname("Gemfile").write(<<~'EOF') + Pathname("Gemfile").write(<<~EOF) source "https://rubygems.org" - ruby "~> 3.0.0" + ruby "#{version}" gem "sinatra" EOF @@ -240,27 +240,14 @@ DEPENDENCIES sinatra - - BUNDLED WITH - 2.3.7 EOF end app.deploy do |app| # Intentionally different than the default ruby version - expect(app.output).to match("3.0.0") - expect(app.run("ruby -v")).to match("3.0.0") - end - end - end - end - - describe "Rake detection" do - context "Ruby 1.9+" do - it "runs a rake task if the gem exists" do - Hatchet::Runner.new('default_with_rakefile').deploy do |app, heroku| - expect(app.output).to include("foo") + expect(app.output).to match("#{version}") + expect(app.run("ruby -v")).to match("#{version}") end end end @@ -279,8 +266,10 @@ context "active record 4.1+" do it "doesn't write a heroku specific database.yml" do - Hatchet::Runner.new("activerecord41_scaffold").deploy do |app, heroku| - expect(app.output).not_to include("Writing config/database.yml to read from DATABASE_URL") + Hatchet::Runner.new("rails61", config: rails_lts_config, stack: rails_lts_stack).tap do |app| + app.deploy do + expect(app.output).not_to include("Writing config/database.yml to read from DATABASE_URL") + end end end end diff --git a/spec/helpers/bundler_wrapper_spec.rb b/spec/helpers/bundler_wrapper_spec.rb index 3a7fdca33..df357ad84 100644 --- a/spec/helpers/bundler_wrapper_spec.rb +++ b/spec/helpers/bundler_wrapper_spec.rb @@ -112,6 +112,7 @@ def wrapper.topic(*args); end # Silence output in tests it "detects windows gemfiles" do Hatchet::App.new("rails4_windows_mri193").in_directory_fork do |dir| + require "bundler" Bundler.with_unbundled_env do expect(@bundler.install.windows_gemfile_lock?).to be_truthy end @@ -119,21 +120,9 @@ def wrapper.topic(*args); end # Silence output in tests end describe "when executing bundler" do - it "handles apps with ruby versions locked in Gemfile.lock" do - Hatchet::App.new("problem_gemfile_version").in_directory_fork do |dir| - Bundler.with_unbundled_env do - @bundler.install - - expect(@bundler.ruby_version).to include("ruby-2.5.1") - - ruby_version = LanguagePack::RubyVersion.new(@bundler.ruby_version, is_new: true) - expect(ruby_version.version_for_download).to include("ruby-2.5.1") - end - end - end - it "handles JRuby pre gemfiles" do Hatchet::App.new("jruby-minimal").in_directory_fork do |dir| + require "bundler" Bundler.with_unbundled_env do @bundler.install diff --git a/spec/helpers/fetcher_spec.rb b/spec/helpers/fetcher_spec.rb index 17d9b1368..c1a432e86 100644 --- a/spec/helpers/fetcher_spec.rb +++ b/spec/helpers/fetcher_spec.rb @@ -1,14 +1,19 @@ require 'spec_helper' describe "Fetches" do - it "bundler" do - Dir.mktmpdir do |dir| - Dir.chdir(dir) do - FileUtils.touch("Gemfile.lock") + LanguagePack::Helpers::BundlerWrapper::BLESSED_BUNDLER_VERSIONS.each do |_, version| + it "bundler #{version}" do + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + lockfile = Pathname("Gemfile.lock") + FileUtils.touch(lockfile) + lockfile.write("BUNDLED WITH\n #{version}") - fetcher = LanguagePack::Fetcher.new(LanguagePack::Base::VENDOR_URL) - fetcher.fetch_untar("#{LanguagePack::Helpers::BundlerWrapper.new.dir_name}.tgz") - expect(`ls bin`).to match("bundle") + fetcher = LanguagePack::Fetcher.new(LanguagePack::Base::VENDOR_URL) + fetcher.fetch_untar("bundler/#{LanguagePack::Helpers::BundlerWrapper.new.dir_name}.tgz") + + expect(run!("ls bin")).to match("bundle") + end end end end diff --git a/spec/helpers/outdated_ruby_version_spec.rb b/spec/helpers/outdated_ruby_version_spec.rb index 410fd1ff3..6aa49fe6e 100644 --- a/spec/helpers/outdated_ruby_version_spec.rb +++ b/spec/helpers/outdated_ruby_version_spec.rb @@ -23,7 +23,7 @@ end it "handles arm 💪 architecture on heroku-24" do - ruby_version = LanguagePack::RubyVersion.new("ruby-3.1.0") + ruby_version = LanguagePack::RubyVersion.new("ruby-3.3.0") fetcher = LanguagePack::Fetcher.new( LanguagePack::Base::VENDOR_URL, stack: "heroku-24", @@ -35,7 +35,7 @@ ) outdated.call - expect(outdated.suggested_ruby_minor_version).to eq("3.1.6") + expect(outdated.suggested_ruby_minor_version).to eq("3.3.7") end it "finds the latest version on a stack" do diff --git a/spec/helpers/rails_runner_spec.rb b/spec/helpers/rails_runner_spec.rb index 8646c232a..1488c8677 100644 --- a/spec/helpers/rails_runner_spec.rb +++ b/spec/helpers/rails_runner_spec.rb @@ -29,7 +29,7 @@ it "calls run through child object" do rails_runner = LanguagePack::Helpers::RailsRunner.new - def rails_runner.call; @called ||= 0 ; @called += 1; end + def rails_runner.call; @called ||= 0 ; @called += 1; "" end def rails_runner.called; @called; end local_storage = rails_runner.detect("active_storage.service") diff --git a/spec/helpers/ruby_version_spec.rb b/spec/helpers/ruby_version_spec.rb index ffad5a5f6..70b1f27bd 100644 --- a/spec/helpers/ruby_version_spec.rb +++ b/spec/helpers/ruby_version_spec.rb @@ -62,6 +62,7 @@ it "correctly sets default ruby versions" do Hatchet::App.new("default_ruby").in_directory_fork do |dir| + require 'bundler' Bundler.with_unbundled_env do ruby_version = LanguagePack::RubyVersion.new(@bundler.install.ruby_version, is_new: true) version_number = LanguagePack::RubyVersion::DEFAULT_VERSION_NUMBER @@ -77,6 +78,7 @@ it "detects Ruby from Gemfile.lock" do Hatchet::App.new("default_ruby").in_directory_fork do |_| + require 'bundler' dir = Pathname(Dir.pwd) Bundler.with_unbundled_env do dir.join("Gemfile").write(<<~EOF) @@ -118,6 +120,7 @@ it "detects non mri engines" do Hatchet::App.new("default_ruby").in_directory_fork do |_| + require 'bundler' dir = Pathname(Dir.pwd) Bundler.with_unbundled_env do dir.join("Gemfile").write(<<~EOF) diff --git a/spec/helpers/shell_spec.rb b/spec/helpers/shell_spec.rb index 0d4eab188..ef30c836c 100644 --- a/spec/helpers/shell_spec.rb +++ b/spec/helpers/shell_spec.rb @@ -87,7 +87,7 @@ def sh.print(string); string.strip; end def sh.mcount(*args); @error_caught = true; end bad_lines = File.read("spec/fixtures/invalid_encoding.log") - expect { sh.puts(bad_lines) }.to raise_error(ArgumentError) + expect { sh.puts(bad_lines) }.to raise_error(Encoding::CompatibilityError) error_caught = sh.instance_variable_get(:"@error_caught") expect(error_caught).to eq(true) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 115ca3b18..57c63095d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,7 +11,7 @@ ENV['RACK_ENV'] = 'test' -DEFAULT_STACK = 'heroku-20' +DEFAULT_STACK = 'heroku-24' def hatchet_path(path = "") @@ -60,12 +60,28 @@ def fixture_path(path) Pathname.new(__FILE__).join("../fixtures").expand_path.join(path) end +def set_lts_ruby_version + Pathname("Gemfile").write("ruby '3.3.6'", mode: "a") +end + +def set_bundler_version(version: ) + gemfile_lock = Pathname("Gemfile.lock").read + + if version == :default + version = "" + else + version = "BUNDLED WITH\n #{version}" + end + gemfile_lock.gsub!(/^BUNDLED WITH$(\r?\n) (?\d+)\.(?\d+)\.\d+/m, version) + Pathname("Gemfile.lock").write(gemfile_lock) +end + def rails_lts_config { 'BUNDLE_GEMS__RAILSLTS__COM' => ENV["RAILS_LTS_CREDS"] } end def rails_lts_stack - "heroku-20" + "heroku-22" end def hatchet_path(path = "")