Skip to content

Commit

Permalink
Add support for Node 19 (#1046)
Browse files Browse the repository at this point in the history
* Update metrics plugins for 19.x support

* Enable 19.x and drop 17.x for vX specs

* Add node 19 hatchet tests

* Add changelog entry for Node.js 19.x support
  • Loading branch information
joshwlewis authored Oct 19, 2022
1 parent ef0ed63 commit 75e9081
Show file tree
Hide file tree
Showing 21 changed files with 189 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## main

- Add metrics and tests for Node.js 19.x line ([#1046](https://github.com/heroku/heroku-buildpack-nodejs/pull/1046))
- Update default node version to 18.x for heroku-20 and newer ([#1045](https://github.com/heroku/heroku-buildpack-nodejs/pull/1045))

## v200 (2022-10-19)
Expand Down
14 changes: 7 additions & 7 deletions plugin/download.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ delete_old_plugin() {
rm -f "$dir/heroku-nodejs-plugin-node-14.tar.gz"
rm -f "$dir/heroku-nodejs-plugin-node-16.sha512"
rm -f "$dir/heroku-nodejs-plugin-node-16.tar.gz"
rm -f "$dir/heroku-nodejs-plugin-node-17.sha512"
rm -f "$dir/heroku-nodejs-plugin-node-17.tar.gz"
rm -f "$dir/heroku-nodejs-plugin-node-18.sha512"
rm -f "$dir/heroku-nodejs-plugin-node-18.tar.gz"
rm -f "$dir/heroku-nodejs-plugin-node-19.sha512"
rm -f "$dir/heroku-nodejs-plugin-node-19.tar.gz"
rm -f "$dir/version"
}

Expand All @@ -57,13 +57,13 @@ download_assets_for_release() {
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-16-$tag.sha512" "$dir/heroku-nodejs-plugin-node-16.sha512"
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-16-$tag.tar.gz" "$dir/heroku-nodejs-plugin-node-16.tar.gz"

# Node 17
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-17-$tag.sha512" "$dir/heroku-nodejs-plugin-node-17.sha512"
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-17-$tag.tar.gz" "$dir/heroku-nodejs-plugin-node-17.tar.gz"

# Node 18
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-18-$tag.sha512" "$dir/heroku-nodejs-plugin-node-18.sha512"
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-18-$tag.tar.gz" "$dir/heroku-nodejs-plugin-node-18.tar.gz"

# Node 19
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-19-$tag.sha512" "$dir/heroku-nodejs-plugin-node-19.sha512"
download "https://github.com/heroku/heroku-nodejs-plugin/releases/download/$tag/heroku-nodejs-plugin-node-19-$tag.tar.gz" "$dir/heroku-nodejs-plugin-node-19.tar.gz"
}

test_hash() {
Expand Down Expand Up @@ -98,7 +98,7 @@ echo "Plugins downloaded"

test_hash 14 $PLUGIN_DIR
test_hash 16 $PLUGIN_DIR
test_hash 17 $PLUGIN_DIR
test_hash 18 $PLUGIN_DIR
test_hash 19 $PLUGIN_DIR

echo "Done"
2 changes: 1 addition & 1 deletion plugin/heroku-nodejs-plugin-node-14.sha512
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0ab1dce206a4ccec76372fd87ceb1a6e07caefcaa0837ce9f132faac8b88b839692d79e6c8f8d645ed35cdbcddc7326b62811e40ced48a616492f08be5f6d54b heroku-nodejs-plugin-node-14-v10.tar.gz
3a6171950d27f3b3cc82200089733f39ec962f30b774913d72a55e9e05d3c7d0d5127508b74c1fb48f775471d7550988cc556e52683ea7b0715dabee8a7fcaae heroku-nodejs-plugin-node-14-v11.tar.gz
Binary file modified plugin/heroku-nodejs-plugin-node-14.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion plugin/heroku-nodejs-plugin-node-16.sha512
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9f85ede7e17c908e1c98478fe34faa2f979eba94df5bb2c9cb5fef6fe286abdb397ce91615884ec778622cd296e3ba415e16f16fefcc4bd26e5eca94d0d5eb8f heroku-nodejs-plugin-node-16-v10.tar.gz
f8a70f50b4df42a98f44f606137c1ed0e2f6abc3041719e61259a584a12ee31616125fb7a3479d749594838180dd5abf8036302f4c5cec283ef5ddf9bd1e2cd8 heroku-nodejs-plugin-node-16-v11.tar.gz
Binary file modified plugin/heroku-nodejs-plugin-node-16.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion plugin/heroku-nodejs-plugin-node-18.sha512
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dcf53cf5fce9f35309776be64704d94e669a9d265a33a364837d603a132b2e62f601714a7bd26b49f8e964def3c0d1291761ee1eeedd23e1ba240d169b6b80ba heroku-nodejs-plugin-node-18-v10.tar.gz
573f5567fe049213bbc6764a6bd46b9a625af664e29496cb75fc825788f996e743c25290076745c6173f39fa452534e8cf07db5c83d5fcd5c9fe2fb6945f282c heroku-nodejs-plugin-node-18-v11.tar.gz
Binary file modified plugin/heroku-nodejs-plugin-node-18.tar.gz
Binary file not shown.
1 change: 1 addition & 0 deletions plugin/heroku-nodejs-plugin-node-19.sha512
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e7bd47b0672e4b900714336bc90f1583ea54f6692d2cf0ee1ea954dac270bf5b33930cb413db26fe93b5f28ea8866b4c44d1e83bab8e7d8dc5b07fa595474188 heroku-nodejs-plugin-node-19-v11.tar.gz
Binary file added plugin/heroku-nodejs-plugin-node-19.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion plugin/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v10
v11
25 changes: 25 additions & 0 deletions spec/ci/node_19_metrics_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require_relative '../spec_helper'

describe "Node Metrics for v19.x" do
context "test metrics for Node v19x app" do
let(:app) {
Hatchet::Runner.new(
"spec/fixtures/repos/node-19-metrics",
config: {
"HEROKU_METRICS_URL" => "http://localhost:3000",
"METRICS_INTERVAL_OVERRIDE" => "10000"
}
)
}

it "should deploy" do
app.deploy do |app|
data = successful_json_body(app)
expect(data["gauges"]["node.eventloop.delay.ms.max"]).to be >= 2000
expect(data["counters"]["node.gc.collections"]).to be >= 0
expect(data["counters"]["node.gc.young.collections"]).to be >= 0
expect(data["counters"]["node.gc.old.collections"]).to be >= 0
end
end
end
end
27 changes: 27 additions & 0 deletions spec/ci/node_19_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require_relative '../spec_helper'

describe "Hello World for Node v19.x" do
context "a single-process Node v19.x app" do
let(:app) {
Hatchet::Runner.new("spec/fixtures/repos/node-19")
}

it "should deploy successfully" do
app.deploy do |app|
expect(successful_body(app).strip).to eq("Hello, world!")
end
end
end

context "on an incompatible stack (heroku-18)" do
it "should log a stack compatibility message" do
Hatchet::Runner.new(
"spec/fixtures/repos/node-19",
stack: "heroku-18",
allow_failure: true
).deploy do |app|
expect(app.output).to match("Node.js version is not compatible with the current stack")
end
end
end
end
1 change: 1 addition & 0 deletions spec/fixtures/repos/node-19-metrics/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node index.js
72 changes: 72 additions & 0 deletions spec/fixtures/repos/node-19-metrics/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env node

const http = require('http');
const EventEmitter = require('events');

const PORT = process.env.PORT || 5000;
const Events = new EventEmitter();

// This will block the event loop for ~lengths of time
function blockCpuFor(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`blocking the event loop for ${ms}ms`);
let now = new Date().getTime();
let result = 0
while(true) {
result += Math.random() * Math.random();
if (new Date().getTime() > now + ms)
break;
}
resolve();
}, 100);
});
}

function getNextMetricsEvent() {
return new Promise((resolve, reject) => Events.once('metrics', resolve));
}

const server = http.createServer((req, res) => {
// wait for the next metrics event
getNextMetricsEvent()
.then(blockCpuFor(2000))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
// gather the next metrics data which should include these pauses
.then(getNextMetricsEvent())
.then(data => {
res.setHeader('Content-Type', 'application/json');
res.end(data);
})
.catch(() => {
res.statusCode = 500;
res.end("Something went wrong");
});
});

server.listen(PORT, () => console.log(`Listening on ${PORT}`));

// Create a second server that intercepts the HTTP requests
// sent by the metrics plugin
const metricsListener = http.createServer((req, res) => {
if (req.method == 'POST') {
let body = '';
req.on('data', (data) => body += data);
req.on('end', () => {
res.statusCode = 200;
res.end();
Events.emit('metrics', body)
});
}
});

metricsListener.listen(3000, () => console.log('Listening for metrics on 3000'));
11 changes: 11 additions & 0 deletions spec/fixtures/repos/node-19-metrics/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "node-metrics-test-app",
"version": "1.0.0",
"engines": {
"node": "19.x"
},
"main": "index.js",
"license": "MIT",
"devDependencies": {},
"dependencies": {}
}
1 change: 1 addition & 0 deletions spec/fixtures/repos/node-19/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node index.js
3 changes: 3 additions & 0 deletions spec/fixtures/repos/node-19/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "hello-world"
}
13 changes: 13 additions & 0 deletions spec/fixtures/repos/node-19/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env node

const http = require('http');

const PORT = process.env.PORT || 5000;

const server = http.createServer((_req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end("Hello, world!");
})

server.listen(PORT, () => console.log(`Listening on ${PORT}`));
21 changes: 21 additions & 0 deletions spec/fixtures/repos/node-19/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "hello-world",
"version": "1.0.0",
"engines": {
"node": "19.x"
},
"scripts": {
"prettify": "prettier --single-quote --trailing-comma all --write 'bin/*' 'src/**/*.js'",
"test": "jest --silent",
"dev": "nodemon --watch . --watch src/* src/index.js",
"build": "echo NODE_OPTIONS: $NODE_OPTIONS"
},
"main": "index.js",
"license": "MIT",
"devDependencies": {
"jest": "^19.0.2",
"nodemon": "^1.19.4",
"prettier": "^0.22.0"
},
"dependencies": {}
}
4 changes: 2 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def resolve_all_supported_node_versions(options = {})
end

def version_supports_metrics(version)
SemVersion.new(version).satisfies?('>= 10.0.0') && SemVersion.new(version).satisfies?('< 19.0.0')
SemVersion.new(version).satisfies?('>= 10.0.0') && SemVersion.new(version).satisfies?('< 20.0.0')
end

def get_test_versions
Expand All @@ -86,7 +86,7 @@ def get_test_versions
elsif ENV['TEST_ALL_NODE_VERSIONS'] == 'true'
versions = resolve_all_supported_node_versions()
else
versions = resolve_node_version(['14.x', '16.x', '17.x', '18.x'])
versions = resolve_node_version(['14.x', '16.x', '18.x', '19.x'])
end
puts("Running tests for Node versions: #{versions.join(', ')}")
versions
Expand Down

0 comments on commit 75e9081

Please sign in to comment.