Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Node 19 #1046

Merged
merged 4 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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