Skip to content

Commit 77c1ac3

Browse files
schneemsRichard Schneeman
andauthored
Warn when using default node or yarn versions (#1401)
* 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 <rschneeman@rschnee-ltmgmqp.internal.salesforce.com>
1 parent d81113c commit 77c1ac3

File tree

4 files changed

+53
-6
lines changed

4 files changed

+53
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Main (unreleased)
44

5+
- Warn when relying on default Node.js or Yarn versions (https://github.com/heroku/heroku-buildpack-ruby/pull/1401)
6+
- Warn when default Node.js or Yarn versions change (https://github.com/heroku/heroku-buildpack-ruby/pull/1401)
7+
58
## v261 (2023/11/02)
69

710
- JRuby 9.4.5.0 is now available

lib/language_pack/helpers/nodebin.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
require 'json'
22

33
class LanguagePack::Helpers::Nodebin
4+
NODE_VERSION = "20.9.0"
5+
YARN_VERSION = "1.22.19"
6+
47
def self.hardcoded_node_lts
5-
version = "20.9.0"
68
{
7-
"number" => version,
8-
"url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/node/release/linux-x64/node-v#{version}-linux-x64.tar.gz"
9+
"number" => NODE_VERSION,
10+
"url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/node/release/linux-x64/node-v#{NODE_VERSION}-linux-x64.tar.gz"
911
}
1012
end
1113

1214
def self.hardcoded_yarn
13-
version = "1.22.19"
1415
{
15-
"number" => version,
16-
"url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/yarn/release/yarn-v#{version}.tar.gz"
16+
"number" => YARN_VERSION,
17+
"url" => "https://heroku-nodebin.s3.us-east-1.amazonaws.com/yarn/release/yarn-v#{YARN_VERSION}.tar.gz"
1718
}
1819
end
1920

lib/language_pack/ruby.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,26 @@ def add_node_js_binary
10181018
if Pathname(build_path).join("package.json").exist? ||
10191019
bundler.has_gem?('execjs') ||
10201020
bundler.has_gem?('webpacker')
1021+
1022+
version = @node_installer.version
1023+
old_version = @metadata.fetch("default_node_version") { version }
1024+
1025+
if version != version
1026+
warn(<<~WARNING, inline: true)
1027+
Default version of Node.js changed (#{old_version} to #{version})
1028+
WARNING
1029+
end
1030+
1031+
warn(<<~WARNING, inline: true)
1032+
Installing a default version (#{version}) of Node.js.
1033+
This version is not pinned and can change over time, causing unexpected failures.
1034+
1035+
Heroku recommends placing the `heroku/nodejs` buildpack in front of
1036+
`heroku/ruby` to install a specific version of node:
1037+
1038+
https://devcenter.heroku.com/articles/ruby-support#node-js-support
1039+
WARNING
1040+
10211041
[@node_installer.binary_path]
10221042
else
10231043
[]
@@ -1028,6 +1048,26 @@ def add_yarn_binary
10281048
return [] if yarn_preinstalled?
10291049

10301050
if Pathname(build_path).join("yarn.lock").exist? || bundler.has_gem?('webpacker')
1051+
1052+
version = @yarn_installer.version
1053+
old_version = @metadata.fetch("default_yarn_version") { version }
1054+
1055+
if version != version
1056+
warn(<<~WARNING, inline: true)
1057+
Default version of Yarn changed (#{old_version} to #{version})
1058+
WARNING
1059+
end
1060+
1061+
warn(<<~WARNING, inline: true)
1062+
Installing a default version (#{version}) of Yarn
1063+
This version is not pinned and can change over time, causing unexpected failures.
1064+
1065+
Heroku recommends placing the `heroku/nodejs` buildpack in front of
1066+
`heroku/ruby` to install a specific version of node:
1067+
1068+
https://devcenter.heroku.com/articles/ruby-support#node-js-support
1069+
WARNING
1070+
10311071
[@yarn_installer.name]
10321072
else
10331073
[]

spec/hatchet/node_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
expect(app.output).to include("bin/node is the node directory")
1717
expect(app.output).to_not include(".heroku/node/bin/node is the node directory")
1818

19+
expect(app.output).to include("Installing a default version (#{LanguagePack::Helpers::Nodebin::YARN_VERSION}) of Yarn")
20+
expect(app.output).to include("Installing a default version (#{LanguagePack::Helpers::Nodebin::NODE_VERSION}) of Node.js")
21+
1922
expect(app.run("which node")).to match("/app/bin/node") # We put node in bin/node
2023
expect(app.run("which yarn")).to match("/app/vendor/yarn-") # We put yarn in /app/vendor/yarn-
2124
end

0 commit comments

Comments
 (0)