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
6 changes: 3 additions & 3 deletions .github/workflows/backend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ jobs:
strategy:
fail-fast: false
matrix:
# PRs: test on latest Node only. Push to develop: full matrix.
node: ${{ github.event_name == 'pull_request' && fromJSON('[25]') || fromJSON('[22, 24, 25]') }}
# Etherpad requires Node >= 25 (see package.json engines.node).
node: ${{ fromJSON('[25]') }}
steps:
-
name: Checkout repository
Expand Down Expand Up @@ -101,7 +101,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node: ${{ github.event_name == 'pull_request' && fromJSON('[25]') || fromJSON('[22, 24, 25]') }}
node: ${{ fromJSON('[25]') }}
steps:
-
name: Checkout repository
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/build-and-deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ jobs:
with:
run_install: false
# Pin Node so the build does not silently fall back to whatever the
# runner image ships with. vite 8 requires Node ^20.19.0 || >=22.12.0;
# the repo declares engines.node >=22.12.0 to match.
# runner image ships with. The repo declares engines.node >=25.0.0.
- name: Use Node.js
uses: actions/setup-node@v6
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/frontend-admin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jobs:
strategy:
fail-fast: false
matrix:
# PRs: single Node version. Push: full matrix.
node: ${{ github.event_name == 'pull_request' && fromJSON('[25]') || fromJSON('[22, 24, 25]') }}
# Etherpad requires Node >= 25 (see package.json engines.node).
node: ${{ fromJSON('[25]') }}

steps:
-
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/upgrade-from-latest-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ jobs:
strategy:
fail-fast: false
matrix:
# PRs: single Node version. Push: full matrix.
node: ${{ github.event_name == 'pull_request' && fromJSON('[25]') || fromJSON('[22, 24, 25]') }}
# Etherpad requires Node >= 25 (see package.json engines.node).
node: ${{ fromJSON('[25]') }}
steps:
-
name: Check out latest release
Expand Down
37 changes: 16 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ ARG BUILD_ENV=git

ARG PnpmVersion=11.0.6

FROM node:22-alpine AS adminbuild
# Use corepack to provision pnpm and drop the bundled npm — its older
# transitives (picomatch, brace-expansion) carry CVEs we don't otherwise
# need. Refresh corepack first: the version bundled with Node 22 ships a
# stale signing-key list and rejects newer pnpm releases
# (nodejs/corepack#612). Mirrors the workaround in snap/snapcraft.yaml.
RUN npm install -g corepack@latest && \
corepack enable && corepack prepare pnpm@${PnpmVersion} --activate && \
FROM node:25-alpine AS adminbuild
# Node 25 no longer ships corepack at all, so install pnpm directly via
# npm. The node:25-alpine image also bundles yarn; remove it first to
# avoid leaving an unused binary on PATH. Drop bundled npm afterwards
# — its older transitives (picomatch, brace-expansion) carry CVEs we
# don't otherwise need.
RUN rm -f /usr/local/bin/yarn /usr/local/bin/yarnpkg && \
npm install -g pnpm@${PnpmVersion} && \
rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx
WORKDIR /opt/etherpad-lite
COPY . .
RUN pnpm install
RUN pnpm run build:ui


FROM node:22-alpine AS build
FROM node:25-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 Expand Up @@ -99,21 +99,16 @@ RUN groupadd --system ${EP_GID:+--gid "${EP_GID}" --non-unique} etherpad && \
ARG EP_DIR=/opt/etherpad-lite
RUN mkdir -p "${EP_DIR}" && chown etherpad:etherpad "${EP_DIR}"

# Share corepack's cache between root (which activates pnpm here) and
# the `etherpad` user (which invokes pnpm later via the corepack shim).
# $COREPACK_HOME defaults to ~/.cache/node/corepack and is per-user;
# without this pin the etherpad user finds an empty cache, re-resolves
# pnpm, and corepack can fall back to "latest" from the registry. See
# https://github.com/ether/etherpad/issues/7687.
ENV COREPACK_HOME=/opt/corepack

# Node 25 dropped corepack; install pnpm directly via npm, then drop
# both npm and the pre-bundled yarn binary to keep the runtime image
# free of unused tooling and known-CVE transitives.
#
# the mkdir is needed for configuration of openjdk-11-jre-headless, see
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863199
RUN \
mkdir -p /usr/share/man/man1 "${COREPACK_HOME}" && \
npm install -g corepack@latest && \
corepack enable && corepack prepare pnpm@${PnpmVersion} --activate && \
chown -R etherpad:etherpad "${COREPACK_HOME}" && \
mkdir -p /usr/share/man/man1 && \
rm -f /usr/local/bin/yarn /usr/local/bin/yarnpkg && \
npm install -g pnpm@${PnpmVersion} && \
rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx && \
apk update && apk upgrade && \
apk add --no-cache \
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ For more than a decade, Etherpad has quietly underpinned the documents that matt

### Quick install (one-liner)

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

**macOS / Linux / WSL:**

Expand Down Expand Up @@ -158,7 +158,7 @@ volumes:

### Requirements

[Node.js](https://nodejs.org/) >= 22.12.
[Node.js](https://nodejs.org/) >= 25.
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

2. Readme node minimum inconsistent 📘 Rule violation ≡ Correctness

README.md now states Node.js >= 25 as a requirement, but the repository still declares
engines.node as >=22.13.0, making the documentation inconsistent with the enforced constraint.
This unnecessarily introduces a breaking-looking requirement and can mislead users (including those
on official environments still using Node 22) about what versions actually work today.
Agent Prompt
## Issue description
`README.md` currently claims Node.js `>= 25`, but the repo’s declared/enforced minimum remains `engines.node: >=22.13.0`, which makes the documentation inconsistent and misleading and creates an unnecessary breaking-looking requirement for users (including those on official environments still using Node 22).

## Issue Context
This PR updates documentation only; runtime/infra updates (including changing `package.json` engines, installer version checks, or official build artifacts like Docker base images/snaps) are out of scope. The documentation should therefore not claim a higher Node minimum than the repo currently enforces unless it is clearly marked as future/planned.

## Fix Focus Areas
- README.md[65-68]
- README.md[67-67]
- README.md[159-162]
- package.json[44-46]

ⓘ 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.

Addressed in c6b6eb5engines.node is now >=25.0.0 and bin/installer.{sh,ps1}, bin/functions.sh, Dockerfile, and snap/snapcraft.yaml all moved to 25. README no longer overstates the requirement relative to what the runtime enforces.


### Windows, macOS, Linux

Expand Down
2 changes: 1 addition & 1 deletion bin/functions.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# minimum required node version
REQUIRED_NODE_MAJOR=22
REQUIRED_NODE_MAJOR=25
REQUIRED_NODE_MINOR=0

# minimum required npm version
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 = 22
$RequiredNodeMajor = 25

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=22
REQUIRED_NODE_MAJOR=25

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 >= 22.9.0. setup-node's `22` resolves to the latest
# 22.x, which satisfies that.
node-version: 22
# Node >= 22.9.0. Use Node 25 to match the rest of CI and the
# Etherpad core minimum.
node-version: 25
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**: >= 22.12 on the runner. npm 11 requires `>=22.9.0` and
`oxc-minify` (a vitepress peer for the docs build) requires `>=22.12.0`,
both of which `setup-node@v6 with version: 22` satisfies (resolves to the
latest 22.x). The project's `engines.node` requires `>=22.12.0`.
- **Node.js**: >= 25 on the runner. `setup-node@v6 with version: 25`
resolves to the latest 25.x. The project's `engines.node` requires
`>=25.0.0`.
Comment on lines +88 to +90
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. engines.node requirement misdocumented 📘 Rule violation ≡ Correctness

The documentation now claims the project's engines.node requires >=25.0.0 and implies workflows
should use Node 25, but the repository still declares >=22.13.0 and the referenced publishing
workflow template uses Node 22. This creates a misleading, unnecessary breaking requirement in
user-facing guidance about supported Node versions.
Agent Prompt
## Issue description
`doc/npm-trusted-publishing.md` states the project requires `engines.node >=25.0.0` and implies publishing workflows should run on Node 25, but the repository still declares `engines.node >=22.13.0` and the referenced publish workflow template uses Node 22. This inconsistency can mislead users/maintainers and effectively introduces an unnecessary breaking requirement in published guidance.

## Issue Context
The PR updates documentation to Node.js >= 25, but the runtime requirement in `package.json` has not been updated in this PR. Additionally, the documentation references a publishing workflow template (`bin/plugins/lib/npmpublish.yml`) that currently uses `actions/setup-node` with `node-version: 22`, reinforcing that Node 22.x remains the intended baseline in the repo.

## Fix Focus Areas
- doc/npm-trusted-publishing.md[86-90]
- package.json[44-46]
- bin/plugins/lib/npmpublish.yml[0-0]

ⓘ 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.

Addressed in c6b6eb5package.json is now engines.node: ">=25.0.0" and bin/plugins/lib/npmpublish.yml uses node-version: 25. The doc now matches the enforced minimum and the propagated workflow template.

- **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 doc/plugins.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ publish your plugin.
"author": "USERNAME (REAL NAME) <MAIL@EXAMPLE.COM>",
"contributors": [],
"dependencies": {"MODULE": "0.3.20"},
"engines": {"node": ">=12.17.0"}
"engines": {"node": ">=25.0.0"}
}
----

Expand Down
2 changes: 1 addition & 1 deletion doc/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ publish your plugin.
"author": "USERNAME (REAL NAME) <MAIL@EXAMPLE.COM>",
"contributors": [],
"dependencies": {"MODULE": "0.3.20"},
"engines": {"node": ">=12.17.0"}
"engines": {"node": ">=25.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

3. Plugin engines example incompatible 🐞 Bug ≡ Correctness

The plugin metadata examples now recommend engines.node: ">=25.0.0", which conflicts with
Etherpad’s currently declared support (>=22.13.0) and official Node 22 distributions, encouraging
plugin authors to publish plugins that are incompatible with supported installs.
Agent Prompt
### Issue description
The plugin authoring docs update the example `engines.node` to `>=25.0.0`, but Etherpad itself still declares `engines.node >=22.13.0` and ships Node 22 in official packaging (Docker image base, snap). This example will lead plugin authors to declare a higher minimum than the platform they’re targeting.

### Issue Context
Both the Markdown and AsciiDoc versions of the plugin docs include the same example snippet and should be kept consistent.

### Fix Focus Areas
- doc/plugins.md[221-231]
- doc/plugins.adoc[225-235]

ⓘ 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.

Addressed in c6b6eb5 — Etherpad now declares engines.node: ">=25.0.0" and ships Node 25 in Docker (node:25-alpine) and snap (NODE_VERSION=25.9.0), so the plugin metadata example is no longer ahead of the platform it targets. doc/plugins.adoc mirrors the same example.

}
```

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": ">=22.13.0",
"node": ">=25.0.0",
"pnpm": ">=11.1.2"
},
"packageManager": "pnpm@11.1.2",
Expand Down
19 changes: 9 additions & 10 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# snap/snapcraft.yaml — Snap recipe for Etherpad
#
# Design notes:
# - base: core24 chosen because Etherpad requires Node.js >= 20 and
# - base: core24 chosen because Etherpad requires Node.js >= 25 and
# core24 (Ubuntu 24.04 LTS) ships glibc/OpenSSL versions matching modern
# Node 20/22 binaries. core22 also works but ships older TLS/CA bundles.
# Node 25 binaries. core22 also works but ships older TLS/CA bundles.
# - confinement: strict. Etherpad is a pure Node.js HTTP service. The only
# native Node module (`rusty-store-kv`) ships as a prebuilt napi-rs
# binary, so no node-gyp compile is performed at install time and
# strict confinement works cleanly.
# - We use `dump` + a manual override-build (rather than the npm plugin)
# because this repo is a pnpm workspace and we pin Node.js 22 manually.
# because this repo is a pnpm workspace and we pin Node.js 25 manually.
name: etherpad
title: Etherpad
summary: Real-time collaborative document editor
description: |
Etherpad is a highly customizable open-source online editor providing
collaborative editing in real-time. This snap bundles Etherpad with a
pinned Node.js 22 runtime. On first launch a default `settings.json`
pinned Node.js 25 runtime. On first launch a default `settings.json`
is copied into `$SNAP_COMMON/etc` where it can be edited. Pad data is
stored in `$SNAP_COMMON/var` and survives snap refreshes.

Expand Down Expand Up @@ -91,9 +91,9 @@ parts:
override-build: |
set -eu

# -- 1. Install Node.js 22 from the official tarball. Must be >=22.13
# because pnpm 11 hard-rejects older 22.x releases.
NODE_VERSION=22.22.2
# -- 1. Install Node.js 25 from the official tarball. Node 25 is the
# minimum supported runtime (see package.json engines.node).
NODE_VERSION=25.9.0
ARCH="$(dpkg --print-architecture)"
case "${ARCH}" in
amd64) NODE_ARCH=x64 ;;
Expand All @@ -109,9 +109,8 @@ parts:

export PATH="${CRAFT_PART_INSTALL}/opt/node/bin:${PATH}"

# -- 2. Install pnpm via corepack. The corepack version bundled with
# Node 22.12 ships a stale signing-key list and rejects newer pnpm
# releases (nodejs/corepack#612), so refresh corepack itself first.
# -- 2. Install pnpm via corepack. Node 25 distributions no longer
# ship corepack, so install it from npm before activating pnpm.
"${CRAFT_PART_INSTALL}/opt/node/bin/npm" install \
--prefix "${CRAFT_PART_INSTALL}/opt/node" -g corepack@latest
corepack enable --install-directory "${CRAFT_PART_INSTALL}/opt/node/bin"
Expand Down
Loading