Skip to content

Commit

Permalink
Warn when using default node or yarn versions (#1401)
Browse files Browse the repository at this point in the history
* Warn when using default node or yarn versions

Many developers don't realize they're using a default version. When it changes, like https://devcenter.heroku.com/changelog-items/2710, they're surprised to find that even a correctly committed `package.json` with a node engine declaration does not install the version they're expecting. This is because the Ruby build pack does not duplicate the Node build pack's version detection logic. 

The Ruby build pack installs a version of node for historical reasons. It pre-dates multi-build packs from when applications simply needed **a** version of node for execjs to function along with the Rails asset pipeline (sprockets). As the ecosystem has matured, our recommendations also change. We recommend not relying on this default behavior.

It's worth noting that the CNB behavior (not yet available on Heroku) defers installing node to the nodes-engine build pack which is the ideal behavior so that there are not two independent paths for node support.

* Add changelog notes

---------

Co-authored-by: Richard Schneeman <[email protected]>
  • Loading branch information
schneems and Richard Schneeman authored Nov 8, 2023
1 parent d81113c commit 77c1ac3
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 7 additions & 6 deletions lib/language_pack/helpers/nodebin.rb
Original file line number Diff line number Diff line change
@@ -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

Expand Down
40 changes: 40 additions & 0 deletions lib/language_pack/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
[]
Expand All @@ -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
[]
Expand Down
3 changes: 3 additions & 0 deletions spec/hatchet/node_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 77c1ac3

Please sign in to comment.