Skip to content
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
8 changes: 4 additions & 4 deletions .github/workflows/backend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
fail-fast: false
matrix:
# PRs: test on latest Node only. Push to develop: full matrix.
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[20, 22, 24]') }}
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[22, 24, 25]') }}
steps:
-
name: Checkout repository
Expand Down Expand Up @@ -85,7 +85,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[20, 22, 24]') }}
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[22, 24, 25]') }}
steps:
-
name: Checkout repository
Expand Down Expand Up @@ -150,7 +150,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [20, 22, 24]
node: [22, 24, 25]
name: Windows without plugins
runs-on: windows-latest
steps:
Expand Down Expand Up @@ -201,7 +201,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [20, 22, 24]
node: [22, 24, 25]
name: Windows with Plugins
runs-on: windows-latest

Expand Down
40 changes: 27 additions & 13 deletions .github/workflows/deb-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ on:
- 'src/node/utils/run_cmd.ts'
- 'src/static/js/pluginfw/**'
- 'settings.json.template'
pull_request:
paths:
- 'packaging/**'
- '.github/workflows/deb-package.yml'
- 'src/package.json'
- 'pnpm-lock.yaml'
- 'src/node/server.ts'
- 'src/node/utils/run_cmd.ts'
- 'src/static/js/pluginfw/**'
- 'settings.json.template'
workflow_dispatch:
inputs:
ref:
Expand Down Expand Up @@ -140,17 +130,41 @@ jobs:
run: |
set -eux
# Ubuntu's default apt nodejs is 18 — too old for our
# `Depends: nodejs (>= 20)`. Add NodeSource's apt repo
# `Depends: nodejs (>= 22)`. Add NodeSource's apt repo
# explicitly (key + sources.list) instead of `curl | sudo bash`
# so we don't execute network-fetched code as root.
NODE_MAJOR=24
# GitHub runner images often ship a NodeSource node_20.x list
# preinstalled (sometimes as a .sources deb822 file). Wipe any
# existing nodesource entries so the only Node candidate apt sees
# is our node_24.x repo. Otherwise `apt-get install -y nodejs`
# picks the higher-version 20.x build that's already cached and
# `dpkg -i` then fails on `Depends: nodejs (>= 22)`.
sudo rm -f /etc/apt/sources.list.d/nodesource.list \
/etc/apt/sources.list.d/nodesource.sources \
/etc/apt/preferences.d/nodesource \
/etc/apt/preferences.d/nodesource.pref
KEYRING=/usr/share/keyrings/nodesource.gpg
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| sudo gpg --dearmor -o "${KEYRING}"
| sudo gpg --dearmor --yes -o "${KEYRING}"
echo "deb [signed-by=${KEYRING}] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \
| sudo tee /etc/apt/sources.list.d/nodesource.list
# Pin nodejs to the 24.x line so neither Ubuntu's noble-updates
# 20.x nor any leftover NodeSource cache can win the resolver.
printf 'Package: nodejs\nPin: version %s.*\nPin-Priority: 1001\n' "${NODE_MAJOR}" \
| sudo tee /etc/apt/preferences.d/nodesource >/dev/null
sudo apt-get update
sudo apt-get install -y nodejs
# Pin the major explicitly on the install line as a belt-and-
# suspenders guard against any preference file being ignored.
sudo apt-get install -y "nodejs=${NODE_MAJOR}.*"
# Sanity check before invoking dpkg so the failure mode is obvious
# if pinning ever regresses again.
installed_major=$(dpkg-query -W -f='${Version}' nodejs | cut -d. -f1)
if [ "${installed_major}" != "${NODE_MAJOR}" ]; then
echo "::error::Expected nodejs major ${NODE_MAJOR}, got ${installed_major}"
apt-cache policy nodejs || true
exit 1
fi
sudo dpkg -i dist/*.deb || sudo apt-get install -f -y
# /etc/etherpad is mode 0750 root:etherpad on purpose (DB creds
# live here) so the runner user can't read into it. Each check
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
cache-dependency-path: etherpad/pnpm-lock.yaml
-
name: Test
working-directory: etherpad
Expand All @@ -74,6 +80,10 @@ jobs:
git clean -dxf .

build-test-db-drivers:
# Spinning up MySQL + Postgres + cross-driver smoke is expensive; only
# run it on pushes to develop (and tagged release pushes), not on every
# feature-branch PR.
if: github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/frontend-admin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
fail-fast: false
matrix:
# PRs: single Node version. Push: full matrix.
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[20, 22, 24]') }}
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[22, 24, 25]') }}

steps:
-
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/frontend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
-
name: Install all dependencies and symlink for ep_etherpad-lite
run: pnpm install --frozen-lockfile
Expand Down Expand Up @@ -108,6 +113,11 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- name: Install all dependencies and symlink for ep_etherpad-lite
run: pnpm install --frozen-lockfile
- name: Create settings.json
Expand Down Expand Up @@ -180,6 +190,11 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- name: Install all dependencies and symlink for ep_etherpad-lite
run: pnpm install --frozen-lockfile
- name: Install Etherpad plugins
Expand Down Expand Up @@ -264,6 +279,11 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- name: Install all dependencies and symlink for ep_etherpad-lite
run: pnpm install --frozen-lockfile
- name: Install Etherpad plugins
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/load-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
-
name: Install all dependencies and symlink for ep_etherpad-lite
run: pnpm install --frozen-lockfile
Expand Down Expand Up @@ -71,6 +76,11 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
-
name: Install etherpad-load-test
run: sudo npm install -g etherpad-load-test
Expand Down Expand Up @@ -130,6 +140,11 @@ jobs:
with:
version: 10.33.2
run_install: false
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
-
name: Install all dependencies and symlink for ep_etherpad-lite
run: pnpm install --frozen-lockfile
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/releaseEtherpad.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ jobs:
- uses: actions/setup-node@v6
with:
# OIDC trusted publishing needs npm >= 11.5.1, which requires
# Node >= 20.17.0. setup-node's `20` resolves to the latest
# 20.x, which satisfies that.
node-version: 20
# Node >= 22.9.0. setup-node's `22` resolves to the latest
# 22.x, which satisfies that.
node-version: 22
registry-url: https://registry.npmjs.org/
- name: Upgrade npm to >=11.5.1 (required for trusted publishing)
run: npm install -g npm@latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/upgrade-from-latest-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
fail-fast: false
matrix:
# PRs: single Node version. Push: full matrix.
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[20, 22, 24]') }}
node: ${{ github.event_name == 'pull_request' && fromJSON('[24]') || fromJSON('[22, 24, 25]') }}
steps:
-
name: Check out latest release
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 2.7.3

### Breaking changes

- **Minimum required Node.js version is now 22.** Node.js 20 is reaching end-of-life (see https://nodejs.org/en/about/previous-releases). The CI matrix now targets Node 22, 24, and 25. Upgrading should be straightforward — install a current Node.js release before updating Etherpad.

# 2.7.2

### Notable enhancements and fixes
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ ARG BUILD_ENV=git

ARG PnpmVersion=10.28.2

FROM node:lts-alpine AS adminbuild
FROM node:22-alpine AS adminbuild
RUN npm install -g pnpm@${PnpmVersion}
WORKDIR /opt/etherpad-lite
COPY . .
RUN pnpm install
RUN pnpm run build:ui


FROM node:lts-alpine AS build
FROM node:22-alpine AS build
LABEL maintainer="Etherpad team, https://github.com/ether/etherpad"

# Set these arguments when building the image from behind a proxy
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ If your organisation runs Etherpad and would be willing to be listed publicly, p

### Quick install (one-liner)

The fastest way to get Etherpad running. Requires `git` and Node.js >= 20.
The fastest way to get Etherpad running. Requires `git` and Node.js >= 22.

**macOS / Linux / WSL:**

Expand Down Expand Up @@ -160,7 +160,7 @@ volumes:
### Requirements
[Node.js](https://nodejs.org/) >= 20.
[Node.js](https://nodejs.org/) >= 22.
### Windows, macOS, Linux
Expand Down
2 changes: 1 addition & 1 deletion bin/buildForWindows.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ try cp settings.json.template settings.json
#try mv node_modules_resolved node_modules

log "download windows node..."
try wget "https://nodejs.org/dist/latest-v20.x/win-x64/node.exe" -O node.exe
try wget "https://nodejs.org/dist/latest-v22.x/win-x64/node.exe" -O node.exe

log "create the zip..."
try zip -9 -r "${OUTPUT}" ./*
Expand Down
4 changes: 2 additions & 2 deletions bin/functions.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# minimum required node version
REQUIRED_NODE_MAJOR=12
REQUIRED_NODE_MINOR=13
REQUIRED_NODE_MAJOR=22
REQUIRED_NODE_MINOR=0

# minimum required npm version
REQUIRED_NPM_MAJOR=5
Expand Down
2 changes: 1 addition & 1 deletion bin/installer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function Test-Cmd([string]$name) {
$EtherpadDir = if ($env:ETHERPAD_DIR) { $env:ETHERPAD_DIR } else { 'etherpad-lite' }
$EtherpadBranch = if ($env:ETHERPAD_BRANCH) { $env:ETHERPAD_BRANCH } else { 'master' }
$EtherpadRepo = if ($env:ETHERPAD_REPO) { $env:ETHERPAD_REPO } else { 'https://github.com/ether/etherpad.git' }
$RequiredNodeMajor = 20
$RequiredNodeMajor = 22

Write-Step 'Etherpad installer'

Expand Down
2 changes: 1 addition & 1 deletion bin/installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ is_cmd() { command -v "$1" >/dev/null 2>&1; }
ETHERPAD_DIR="${ETHERPAD_DIR:-etherpad-lite}"
ETHERPAD_BRANCH="${ETHERPAD_BRANCH:-master}"
ETHERPAD_REPO="${ETHERPAD_REPO:-https://github.com/ether/etherpad.git}"
REQUIRED_NODE_MAJOR=20
REQUIRED_NODE_MAJOR=22

step "Etherpad installer"

Expand Down
6 changes: 3 additions & 3 deletions bin/plugins/lib/npmpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
- uses: actions/setup-node@v6
with:
# OIDC trusted publishing needs npm >= 11.5.1, which requires
# Node >= 20.17.0. setup-node's `20` resolves to the latest
# 20.x, which satisfies that.
node-version: 20
# Node >= 22.9.0. setup-node's `22` resolves to the latest
# 22.x, which satisfies that.
node-version: 22
registry-url: https://registry.npmjs.org/
- name: Upgrade npm to >=11.5.1 (required for trusted publishing)
run: npm install -g npm@latest
Expand Down
7 changes: 3 additions & 4 deletions doc/npm-trusted-publishing.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@ If a package previously had an `NPM_TOKEN` secret in CI:

## Requirements

- **Node.js**: >= 20.17.0 on the runner. npm 11 requires
`^20.17.0 || >=22.9.0`. The npm docs nominally recommend Node 22.14+, but
Node 20.17+ works fine — the project's `engines.node` already requires
`>=20.0.0`, and `setup-node@v6 with version: 20` resolves to the latest 20.x.
- **Node.js**: >= 22 on the runner. npm 11 requires `>=22.9.0`, which
`setup-node@v6 with version: 22` satisfies (resolves to the latest 22.x).
The project's `engines.node` requires `>=22.0.0`.
- **npm CLI**: >= 11.5.1. The publish workflow runs `npm install -g npm@latest`
before publishing so the bundled npm version doesn't matter.
- **Runner**: must be a GitHub-hosted (cloud) runner. Self-hosted runners are
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"ui": "link:ui"
},
"engines": {
"node": ">=20.0.0"
"node": ">=22.0.0"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Node engine bumped to 22 📘 Rule violation ⚙ Maintainability

This PR raises the minimum supported Node.js version from 20 to 22, which is a breaking
compatibility change for existing users who are still on Node 20. The change introduces a hard
requirement with no compatibility/fallback path, violating the backward-compatibility requirement.
Agent Prompt
## Issue description
The PR introduces a breaking increase of the minimum Node.js requirement to 22 (via `engines.node`), which violates the backward-compatibility requirement unless a compatibility/deprecation strategy is provided.

## Issue Context
Users on Node 20 will be unable to install/run after this change. If dropping Node 20 is intended, provide a compatibility plan (e.g., deprecation period, delayed enforcement, or release strategy that preserves compatibility in this line).

## Fix Focus Areas
- package.json[45-45]
- src/package.json[136-136]
- CHANGELOG.md[1-6]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node 20 is end of life. People can update without any problem.

Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
},
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packaging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ sudo systemctl start etherpad
curl http://localhost:9001/health
```

`apt` will pull in `nodejs (>= 20)` (matches Etherpad's `engines.node`).
`apt` will pull in `nodejs (>= 22)` (matches Etherpad's `engines.node`).
Recommended runtime is the current Node.js LTS (24); on distros without a
new enough Node, add NodeSource first:

Expand Down
11 changes: 10 additions & 1 deletion packaging/bin/etherpad
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,19 @@ cd "${APP_DIR}"
export NODE_ENV
export ETHERPAD_PRODUCTION=true

# Resolve `node` explicitly to the apt-installed binary (the .deb declares
# `Depends: nodejs (>= 22)`, which always lands at /usr/bin/node). Relying
# on PATH would let a stray /usr/local/bin/node — e.g. an older nvm or
# toolcache install — shadow the version we actually require, and the
# server would crash on startup with "Node 20.x is not supported".
NODE_BIN=/usr/bin/node
[ -x "${NODE_BIN}" ] || NODE_BIN=$(command -v node) \
|| { echo "etherpad: node not found (install the 'nodejs' package)" >&2; exit 1; }

# Run the server through tsx's CommonJS hook — Etherpad's prod entrypoint
# (src/node/server.ts) uses `exports.start = ...`, which fails under the
# ESM loader. Mirrors the `prod` script in src/package.json.
exec node \
exec "${NODE_BIN}" \
--require "${APP_DIR}/src/node_modules/tsx/dist/cjs/index.cjs" \
"${APP_DIR}/src/node/server.ts" \
"$@"
Loading
Loading