From ecd68268f4b941b3a2c2d32c82cb5a3c033611bc Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 13 Aug 2026 17:38:47 -0500 Subject: [PATCH] feat: add Node 25 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Node 25 (up to 25.9) that was skipped when #128 jumped 24 → 26. Includes examples/25 Leia coverage and docs/changelog updates. --- .github/workflows/pr-node-tests.yml | 1 + CHANGELOG.md | 1 + builders/node.js | 10 ++++ docs/index.md | 1 + examples/25/.gitignore | 3 + examples/25/.lando.yml | 39 +++++++++++++ examples/25/README.md | 86 +++++++++++++++++++++++++++++ examples/25/package.json | 27 +++++++++ examples/25/src/app-custom.js | 28 ++++++++++ examples/25/src/app-http.js | 21 +++++++ examples/25/src/app-https.js | 28 ++++++++++ 11 files changed, 245 insertions(+) create mode 100644 examples/25/.gitignore create mode 100644 examples/25/.lando.yml create mode 100644 examples/25/README.md create mode 100644 examples/25/package.json create mode 100644 examples/25/src/app-custom.js create mode 100644 examples/25/src/app-http.js create mode 100644 examples/25/src/app-https.js diff --git a/.github/workflows/pr-node-tests.yml b/.github/workflows/pr-node-tests.yml index 55b4cef..1c3dc92 100644 --- a/.github/workflows/pr-node-tests.yml +++ b/.github/workflows/pr-node-tests.yml @@ -22,6 +22,7 @@ jobs: - examples/22 - examples/23 - examples/24 + - examples/25 - examples/26 lando-version: - 3-edge diff --git a/CHANGELOG.md b/CHANGELOG.md index 67b54b6..ea0f586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Removed Node 19 test example (EOL, deps like `minimatch` no longer support it) * Fixed Node 21 test example by pinning `minimatch` to `^9.0.0` for compatibility * Added support for Node `26` (up to `26.7`) +* Added support for Node `25` (up to `25.9`) * Updated Node LTS support to include the latest minor versions for `24` (up to `24.19`), `22` (up to `22.23`), and `20` (up to `20.20`) * Restored Yarn on Node `26+` images, which no longer bundle Yarn v1 diff --git a/builders/node.js b/builders/node.js index 8bcafdb..570dc1f 100644 --- a/builders/node.js +++ b/builders/node.js @@ -14,6 +14,16 @@ const supportedVersions = [ '26.3', '26.2', '26.1', + '25', + '25.9', + '25.8', + '25.7', + '25.6', + '25.5', + '25.4', + '25.3', + '25.2', + '25.1', '24', '24.19', '24.18', diff --git a/docs/index.md b/docs/index.md index 49bf395..943b4ec 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,6 +19,7 @@ services: ## Supported versions * [26](https://hub.docker.com/_/node) +* [25](https://hub.docker.com/_/node) * [24](https://hub.docker.com/_/node) * [23](https://hub.docker.com/_/node) * [22](https://hub.docker.com/_/node) diff --git a/examples/25/.gitignore b/examples/25/.gitignore new file mode 100644 index 0000000..740a0a4 --- /dev/null +++ b/examples/25/.gitignore @@ -0,0 +1,3 @@ +node_modules +*.log +package-lock.json diff --git a/examples/25/.lando.yml b/examples/25/.lando.yml new file mode 100644 index 0000000..de7da46 --- /dev/null +++ b/examples/25/.lando.yml @@ -0,0 +1,39 @@ +name: lando-node-25 +services: + defaults: + type: node:25 + build: + - yarn + command: /app/node_modules/.bin/nodemon src/app-http.js --watch src --ignore *.test.js + cli: + type: node + compass: + type: node:25 + globals: + grunt-cli: latest + custom: + type: node:25 + ssl: true + globals: + gulp-cli: latest + port: 3000 + build: + - yarn + command: /app/node_modules/.bin/nodemon src/app-https.js --watch src --ignore *.test.js + custom2: + type: node:25.9.0 + ssl: 4444 + port: 3000 + build: + - yarn + command: /app/node_modules/.bin/nodemon src/app-custom.js --watch src --ignore *.test.js +tooling: + grunt: + service: compass + npx: + service: cli + +# This is important because it lets lando know to test against the plugin in this repo +# DO NOT REMOVE THIS! +plugins: + "@lando/node": ../.. diff --git a/examples/25/README.md b/examples/25/README.md new file mode 100644 index 0000000..e54c08d --- /dev/null +++ b/examples/25/README.md @@ -0,0 +1,86 @@ +# Node 25 Example + +This example exists primarily to test the following documentation: + +* [Node 14-25 Service](https://docs.devwithlando.io/tutorials/node.html) +* [Installing compass in your node service](https://docs.lando.dev/guides/using-compass-on-a-lando-node-service.html) + +## Start up tests + +Run the following commands to get up and running with this example. + +```bash +# Should start up successfully +lando poweroff +lando start +``` + +## Verification commands + +Run the following commands to validate things are rolling as they should. + +```bash +# Should use 25.x as the default version +lando exec defaults -- "env | grep NODE_VERSION=25." + +# Should use a user specified version if given +lando exec custom -- "env | grep NODE_VERSION=25." + +# Should use a user specified patch version if given +lando exec custom2 -- "env | grep NODE_VERSION=25.9.0" + +# Should serve over port 80 by default +lando exec defaults -- "curl http://localhost | grep tune" + +# Should set NODE_EXTRA_CA_CERTS with lando domain CA +lando exec defaults -- "env" | grep NODE_EXTRA_CA_CERTS | grep "$LANDO_CA_CERT" + +# Should only serve over http by default +lando exec defaults -- "curl https://localhost" || echo $? | grep 7 + +# Should serve over specified ports if given +lando exec custom -- "curl http://localhost:3000 | grep tune" + +# Should serve over https is ssl is set by user +lando exec custom -- "curl https://localhost | grep tune" + +# Should serve over a custom https port if ssl is set to a specific port +lando exec custom2 -- "curl https://localhost:4444 | grep DANCING" + +# Should run as root if using ports below 1024 +lando exec defaults -- pgrep -c -u root -f "node src/app-http.js" | grep 1 +lando exec custom -- pgrep -c -u root -f "node src/app-https.js" | grep 1 + +# Should run as node if using ports 1024 and above +lando exec custom2 -- pgrep -c -u node -f "node src/app-custom.js" | grep 1 + +# Should install global dependencies if specified by user and have them available in PATH +lando exec custom -- "gulp -v" +lando exec custom -- "which gulp | grep /var/www/.npm-global" + +# Should PATH prefer node dependency binaries installed in /app/node_modules over global ones +lando exec custom -- "npm install gulp-cli --no-save" +lando exec custom -- "gulp -v" +lando exec custom -- "which gulp | grep /app/node_modules/.bin" +lando exec custom -- "npm uninstall gulp-cli" +lando exec custom -- "which gulp | grep /var/www/.npm-global" + +# Should not serve port for cli +lando exec cli -- "curl http://localhost" || echo $? | grep 7 + +# Should install gruntcli +lando grunt -V + +# Should execute npx scripts +lando npx cowsay "Hello World" +``` + +## Destroy tests + +Run the following commands to trash this app like nothing ever happened. + +```bash +# Should be destroyed with success +lando destroy -y +lando poweroff +``` diff --git a/examples/25/package.json b/examples/25/package.json new file mode 100644 index 0000000..7f9f428 --- /dev/null +++ b/examples/25/package.json @@ -0,0 +1,27 @@ +{ + "name": "node-lando", + "version": "1.0.0", + "description": "Node example for Lando", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/lando/lando/tree/master/examples/node" + }, + "keywords": [ + "node", + "docker", + "localdev" + ], + "author": "Mike Pirog", + "license": "MIT", + "dependencies": { + "express": "^4.19.2" + }, + "devDependencies": { + "grunt-contrib-compass": "^1.1.1", + "nodemon": "^3.0.1" + } +} diff --git a/examples/25/src/app-custom.js b/examples/25/src/app-custom.js new file mode 100644 index 0000000..b47fc14 --- /dev/null +++ b/examples/25/src/app-custom.js @@ -0,0 +1,28 @@ +/** + * Lando node express example + * + * @name taylorswift + */ + +'use strict'; + +// Load modules +const fs = require('fs'); +const http = require('http'); +const https = require('https'); +const express = require('express'); +const app = express(); + +// Create our HTTPS server options +const key = fs.readFileSync('/certs/cert.key'); +const cert = fs.readFileSync('/certs/cert.crt'); + +// Create our servers +https.createServer({key, cert}, app).listen(4444); +http.createServer(app).listen(3000); + +// Basic HTTP response +app.get('/', (req, res) => { + res.header('Content-type', 'text/html'); + return res.end('

DANCING DANCING STARLIGHT

'); +}); diff --git a/examples/25/src/app-http.js b/examples/25/src/app-http.js new file mode 100644 index 0000000..fe682e2 --- /dev/null +++ b/examples/25/src/app-http.js @@ -0,0 +1,21 @@ +/** + * Lando node express example + * + * @name taylorswift + */ + +'use strict'; + +// Load modules +const http = require('http'); +const express = require('express'); +const app = express(); + +// Create our server +http.createServer(app).listen(80); + +// Basic HTTP response +app.get('/', (req, res) => { + res.header('Content-type', 'text/html'); + return res.end('

I said "Oh my!" What a marvelous tune!!!

'); +}); diff --git a/examples/25/src/app-https.js b/examples/25/src/app-https.js new file mode 100644 index 0000000..84c81bf --- /dev/null +++ b/examples/25/src/app-https.js @@ -0,0 +1,28 @@ +/** + * Lando node express example + * + * @name taylorswift + */ + +'use strict'; + +// Load modules +const fs = require('fs'); +const http = require('http'); +const https = require('https'); +const express = require('express'); +const app = express(); + +// Create our HTTPS server options +const key = fs.readFileSync('/certs/cert.key'); +const cert = fs.readFileSync('/certs/cert.crt'); + +// Create our servers +https.createServer({key, cert}, app).listen(443); +http.createServer(app).listen(3000); + +// Basic HTTP response +app.get('/', (req, res) => { + res.header('Content-type', 'text/html'); + return res.end('

I said "Oh my!" What a marvelous tune!!!

'); +});