diff --git a/CHANGELOG.md b/CHANGELOG.md index 610248f02..d787c8bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Main (unreleased) +- Warn when relying on default Node.js or Yarn versions (https://github.com/heroku/heroku-buildpack-ruby/pull/1401) +- Warn when default Node.js or Yarn versions change (https://github.com/heroku/heroku-buildpack-ruby/pull/1401) + ## v261 (2023/11/02) - JRuby 9.4.5.0 is now available diff --git a/lib/language_pack/helpers/nodebin.rb b/lib/language_pack/helpers/nodebin.rb index 0bffcd3aa..1a5c194f9 100644 --- a/lib/language_pack/helpers/nodebin.rb +++ b/lib/language_pack/helpers/nodebin.rb @@ -1,19 +1,20 @@ require 'json' class LanguagePack::Helpers::Nodebin + NODE_VERSION = "20.9.0" + YARN_VERSION = "1.22.19" + def self.hardcoded_node_lts - version = "20.9.0" { - "number" => version, - "url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/node/release/linux-x64/node-v#{version}-linux-x64.tar.gz" + "number" => NODE_VERSION, + "url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/node/release/linux-x64/node-v#{NODE_VERSION}-linux-x64.tar.gz" } end def self.hardcoded_yarn - version = "1.22.19" { - "number" => version, - "url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/yarn/release/yarn-v#{version}.tar.gz" + "number" => YARN_VERSION, + "url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/yarn/release/yarn-v#{YARN_VERSION}.tar.gz" } end diff --git a/lib/language_pack/ruby.rb b/lib/language_pack/ruby.rb index 81784e273..beb1b0f0d 100644 --- a/lib/language_pack/ruby.rb +++ b/lib/language_pack/ruby.rb @@ -1018,6 +1018,26 @@ def add_node_js_binary if Pathname(build_path).join("package.json").exist? || bundler.has_gem?('execjs') || bundler.has_gem?('webpacker') + + version = @node_installer.version + old_version = @metadata.fetch("default_node_version") { version } + + if version != version + warn(<<~WARNING, inline: true) + Default version of Node.js changed (#{old_version} to #{version}) + WARNING + end + + warn(<<~WARNING, inline: true) + Installing a default version (#{version}) of Node.js. + This version is not pinned and can change over time, causing unexpected failures. + + Heroku recommends placing the `heroku/nodejs` buildpack in front of + `heroku/ruby` to install a specific version of node: + + https://devcenter.heroku.com/articles/ruby-support#node-js-support + WARNING + [@node_installer.binary_path] else [] @@ -1028,6 +1048,26 @@ def add_yarn_binary return [] if yarn_preinstalled? if Pathname(build_path).join("yarn.lock").exist? || bundler.has_gem?('webpacker') + + version = @yarn_installer.version + old_version = @metadata.fetch("default_yarn_version") { version } + + if version != version + warn(<<~WARNING, inline: true) + Default version of Yarn changed (#{old_version} to #{version}) + WARNING + end + + warn(<<~WARNING, inline: true) + Installing a default version (#{version}) of Yarn + This version is not pinned and can change over time, causing unexpected failures. + + Heroku recommends placing the `heroku/nodejs` buildpack in front of + `heroku/ruby` to install a specific version of node: + + https://devcenter.heroku.com/articles/ruby-support#node-js-support + WARNING + [@yarn_installer.name] else [] diff --git a/spec/hatchet/node_spec.rb b/spec/hatchet/node_spec.rb index 7d58b22d2..fe816dc27 100644 --- a/spec/hatchet/node_spec.rb +++ b/spec/hatchet/node_spec.rb @@ -16,6 +16,9 @@ expect(app.output).to include("bin/node is the node directory") expect(app.output).to_not include(".heroku/node/bin/node is the node directory") + expect(app.output).to include("Installing a default version (#{LanguagePack::Helpers::Nodebin::YARN_VERSION}) of Yarn") + expect(app.output).to include("Installing a default version (#{LanguagePack::Helpers::Nodebin::NODE_VERSION}) of Node.js") + expect(app.run("which node")).to match("/app/bin/node") # We put node in bin/node expect(app.run("which yarn")).to match("/app/vendor/yarn-") # We put yarn in /app/vendor/yarn- end