mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-17 16:47:05 +00:00
4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
04045fe532
|
Roll Node.js floor back to >= 24 (Active LTS) — closes #7779 (#7781)
* Roll Node.js floor back to >= 24 (Active LTS) Closes #7779. #7779 originally proposed bumping past the Node 25 stop-gap to Node 26. After re-checking the release schedule, the cleaner LTS target is actually Node 24: - Node 24 (Krypton) is currently in Active LTS, supported until ~May 2028. - Node 25 hit end-of-life on April 10 2026 — the floor merged in #7752 / #7749 / #7754 a day ago ships an already-EOL major. - Node 26 was released May 5 2026 and does not enter Active LTS until October 2026. So this PR reverts the Node 25 ratchet from those three PRs and lands on Node 24 — Etherpad's runtime floor stays on a supported LTS for the next ~2 years. Runtime / infra - `package.json` + `src/package.json`: `engines.node` `>=25.0.0` -> `>=24.0.0` - `bin/functions.sh`, `bin/installer.sh`, `bin/installer.ps1`: `REQUIRED_NODE_MAJOR` 25 -> 24 - `Dockerfile`: `node:25-alpine` -> `node:24-alpine` (both stages). Corepack-via-npm workaround is intentionally kept: it works on Node 24 (which still ships corepack) and on Node 25+ (which doesn't), so the same recipe survives the next LTS bump without churn. Comments reworded accordingly. - `snap/snapcraft.yaml`: pinned `NODE_VERSION` 25.9.0 -> 24.15.0; design notes + corepack comment adjusted - `packaging/nfpm.yaml`: `nodejs (>= 25)` -> `nodejs (>= 24)` in top-level depends + deb/rpm overrides - `packaging/bin/etherpad`: comment matches the new pin - `packaging/README.md`: build prereqs + apt install snippet point at `node_24.x`; the long-stale "engines.node floor is 20" line is fixed while we're here - `.github/workflows/*.yml`: setup-node `node-version` 25 -> 24 across every workflow; backend / frontend-admin / upgrade matrices `[25]` -> `[24]` - `.github/workflows/deb-package.yml`: `NODE_MAJOR=25` + `node_25.x` smoke-test installer -> 24 - `bin/plugins/lib/npmpublish.yml`: 25 -> 24 (template propagates to the ~80 ether/* plugins via update-plugins workflow) Docs - `README.md`: install one-liner + Requirements -> Node.js >= 24 - `doc/npm-trusted-publishing.md`: runner requirement -> Node 24 - `doc/plugins.md` / `doc/plugins.adoc`: plugin metadata example `engines.node` -> `">=24.0.0"` @types/node is left at ^25.8.0 — newer type definitions cover Node 24 runtime fine and avoid an unnecessary lockfile churn. Companion homepage one-liner change to follow on ether/ether.github.com. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(plugins): example engines.node = ">=22.0.0", not core's floor Plugin code is overwhelmingly ace-hook glue and rarely uses Node-version- specific APIs, so plugin engines.node should reflect the plugin's own requirements, not track core. Showing core's 24-floor in the example encouraged plugin authors to blindly copy a tighter pin than necessary and locked plugins out of being installable on older Etherpad/Node deployments. Use the most-recent Node LTS that has actually reached EOL (20 -> EOL April 2026) as the example floor, i.e. >=22. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
7d537f3deb
|
Require Node.js >= 25 (engines, installers, Dockerfile, snap, CI, docs) (#7749)
* docs: bump documented Node.js minimum to 25 Etherpad is moving its supported Node.js floor to >= 25 (CI matrix is already pinned to 25 across all workflows on the node25-corepack-pnpm11 work). Sync the user-facing documentation so the install instructions, requirements section, and plugin metadata example all reflect the new minimum instead of Node 22 / 12.17. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: require Node.js >= 25 (engines, installers, Dockerfile, snap, CI) #7747 added Node 25 *support* but left the floor at Node 22. This commit completes the cutover so the runtime requirement matches the documentation bumped in the previous commit. - package.json: engines.node ">=22.13.0" → ">=25.0.0" - bin/functions.sh, bin/installer.sh, bin/installer.ps1: REQUIRED_NODE bumped to 25 (controls the error message users see when they invoke the installer or pnpm scripts on an older Node) - Dockerfile: base image node:22-alpine → node:25-alpine (×2). Corepack comment updated: Node 25 no longer ships corepack at all, so we install it from npm rather than refreshing a stale signing-key list - snap/snapcraft.yaml: pinned NODE_VERSION 22.22.2 → 25.9.0 and the surrounding design notes rewritten to reflect Node 25 instead of 22 - .github/workflows/*.yml: matrix dropped from [22, 24, 25] to just [25] (anything older now fails engines anyway). Stale comments in build-and-deploy-docs.yml referencing vite 8's 22.12 floor cleaned up - bin/plugins/lib/npmpublish.yml: setup-node 22 → 25 so the plugin template propagated to every ether/* plugin matches the new minimum Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(docker): install pnpm directly on Node 25 (no corepack) node:25-alpine doesn't ship corepack but does pre-install yarn at /usr/local/bin/yarn, so `npm install -g corepack@latest` fails with EEXIST trying to register its yarn shim. Per #7747, end-users install pnpm via plain `npm install -g pnpm` on Node 25 — use the same flow in the Dockerfile (and remove the unused yarn binary so it doesn't sit on PATH inside the image). Drops COREPACK_HOME and the related issue-7687 cache-sharing tweak since there's no corepack shim to share. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
958590d1c8
|
chore(docker): clear most CVEs in published image (npm/pnpm/uuid + drop curl) (#7674)
* chore(docker): clear most CVEs in published image — npm/pnpm/uuid + drop curl Cuts published-image vulnerabilities from 18 (4H/13M/1L) across 8 packages to 12 (2H/9M/1L) across 3 packages. The remaining three (curl/libcurl, git, busybox) are all upstream Alpine 3.23 packages with "not fixed" status — libcurl is pulled in transitively by git and cannot be removed independently. Changes: - Provision pnpm via corepack instead of `npm install -g pnpm`, then remove the bundled npm. The base image's npm@10.9.7 ships old transitives (picomatch 4.0.3 → CVE-2026-33671/33672, brace-expansion 2.0.2 → CVE-2026-33750) that we don't otherwise need at runtime; corepack handles pnpm directly without npm. Fixes 1H + 1M. - Bump PnpmVersion 10.28.2 → 10.33.2 to align with the rest of the workflow and pull in pnpm's patched bundled brace-expansion (5.0.5 vs 5.0.4). Fixes 1M. - Add `uuid@<14.0.0` → `>=14.0.0` to pnpm.overrides (GHSA-w5hq-g745-h8pq). Fixes 1M. - Drop `curl` from the runtime apk add list and switch HEALTHCHECK to wget (busybox built-in). curl was only invoked by the healthcheck and by dev/CI scripts that don't run in the container. Removes the curl CLI binary; libcurl remains as a git transitive dep, so the `apk/alpine/curl` advisories scout reports against libcurl persist but aren't reachable from any code we ship. As a side-effect this also clears nghttp2 (CVE-2026-27135) which was a curl-CLI dep. - Switch HEALTHCHECK URL from `localhost` to `127.0.0.1` — alpine/musl resolves localhost to ::1 first and Etherpad only binds IPv4. Verified locally: docker build → docker run → healthy → docker scout cves shows 12 CVEs / 3 packages. * fix(docker): refresh corepack before preparing pnpm (Qodo) Node 22's bundled corepack ships a stale signing-key list and can reject newer pnpm releases (nodejs/corepack#612), which would fail the image build at `corepack prepare`. Mirror the snap/snapcraft.yaml workaround: `npm install -g corepack@latest` before activating pnpm, in both adminbuild and build stages. npm is still removed afterwards. * docs(changelog): note docker image dropping curl/npm/npx (Qodo) Address Qodo's "backwards-incompatible change without mitigation" rule violations by documenting the removal in the 2.7.3 breaking-changes section. Operators who exec into the container can apk add curl on demand or use the busybox wget / pnpm already present. * chore: pnpm * chore: pnpm * chore: pnpm * chore: pnpm * chore: pnpm * chore: pnpm * chore: pnpm * chore: pnpm * chore: pnpm --------- Co-authored-by: SamTV12345 <40429738+samtv12345@users.noreply.github.com> |
||
|
|
02e37e0112
|
feat(packaging): publish Etherpad as a Snap (#7558)
* feat(packaging): publish Etherpad as a Snap Adds first-class Snap packaging so Ubuntu / snapd users can install via `sudo snap install etherpad-lite`. - snap/snapcraft.yaml — core24, strict confinement, builds with pnpm against a pinned Node.js 22 runtime. Version is auto-derived from src/package.json so `snap info` tracks upstream release numbering. - snap/local/bin/etherpad-service — launch wrapper that seeds $SNAP_COMMON/etc/settings.json on first run (rewriting the default dirty-DB path to a writable $SNAP_COMMON location) and execs Etherpad via `node --import tsx/esm`. - snap/local/bin/etherpad-healthcheck-wrapper — HTTP probe for external supervisors, falling back to Node if curl isn't staged. - snap/local/bin/etherpad-cli — thin passthrough to Etherpad's bin/ scripts (importSqlFile, checkPad, etc.). - snap/hooks/configure — exposes `snap set etherpad-lite port=<n>` and `ip=<addr>` with validation, restarts the service when running. - snap/README.md — build / install / configure / publish instructions. - .github/workflows/snap-publish.yml — builds on every v* tag, uploads a short-lived artifact, publishes to `edge`, and then promotes to `stable` through a manually-approved GitHub Environment. Requires a one-time `snapcraft register etherpad-lite` plus provisioning of the `SNAPCRAFT_STORE_CREDENTIALS` repo secret (instructions inline). Pad data (dirty DB, logs) lives in /var/snap/etherpad-lite/common/ and survives snap refreshes. The read-only $SNAP squashfs is never written to at runtime. Refs #7529 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(snap): pass --settings flag, env-subst ip/port, 2-space indent Addresses Qodo review feedback on #7558: 1. Settings file ignored: Etherpad's Settings loader reads `argv.settings`, not the `EP_SETTINGS` env var. Without `--settings`, the launcher's seeded $SNAP_COMMON/etc/settings.json is never loaded; Etherpad falls back to <install-root>/settings.json, which lives on the read-only squashfs — so the default dirty-DB path ends up unwritable and the daemon fails to persist pads. Fix: pass `--settings "${SETTINGS}"` to node; drop the EP_SETTINGS export. 2. `snap set` overrides were no-ops: the seeded settings.json carries the template's literal `"ip": "0.0.0.0"` / `"port": 9001` values, which override the env-based defaults Etherpad exposes via ${…} substitution. Users following the README saw the listener stay put after `snap set etherpad-lite port=…`. Fix: after copying the template on first run, rewrite the top-level `ip` and `port` lines to `"${IP:0.0.0.0}"` / `"${PORT:9001}"`. Use `0,/…/` anchors so the `dbSettings.port` entry further down stays literal. 3. Indentation: reflow the new shell scripts from 4-space to 2-space to match the repo style rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(snap): default seeded settings to sqlite, not dirty settings.json.template's own comment says dirty is for testing only. A Snap install is the "not testing" case — shipping it by default means every `sudo snap install etherpad-lite` starts on a DB the project explicitly recommends against. Rewrite the postinstall sed to switch dbType: "dirty" → "sqlite" and point filename at $SNAP_COMMON/var/etherpad.db. sqlite is already shipped in-tree via ueberdb2 → rusty-store-kv (prebuilt napi-rs binary, no build deps), so this works under strict confinement with zero snap.yaml changes. Only affects first-run seeding; existing $SNAP_COMMON/etc/settings.json is never touched on refresh. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(snap): rename to "etherpad", glob tag filter, harden cli - Snap is registered as `etherpad` (the project's only name) — drops the legacy `etherpad-lite` from the name, app, paths, install dir, configure hook, README and workflow artifact. The daemon app shares the snap name, so `snap install etherpad` exposes a bare `etherpad` command; the bin/ passthrough is now `etherpad.cli`. - snap-publish.yml: GitHub Actions tag filters use globs, not regex. The prior `v?[0-9]+.[0-9]+.[0-9]+` pattern would never match a real release tag (Qodo review). Replace with two glob entries covering `vX.Y.Z` and `X.Y.Z`. - etherpad-cli: reject path-traversal in the `<bin-script>` arg (anything containing `/`, `..`, or empty) and add a default `*)` case so files with unsupported extensions fail loud instead of silently exiting 0 (Qodo review). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(snap): unbreak build — refresh corepack, drop pnpm prune Two issues hit on the first real `snapcraft pack` of this recipe: - `corepack prepare pnpm@10.33.0 --activate` failed with `Cannot find matching keyid` because Node 22.12's bundled corepack ships a stale signing-key list and rejects newer pnpm releases (nodejs/corepack#612). Refresh corepack itself via npm before preparing pnpm. - `pnpm prune --prod` is interactive on workspace projects: it asks "The modules directories will be removed and reinstalled from scratch. Proceed? (Y/n)" and deadlocks on stdin under sudo + tee. Replace it with the explicit "wipe node_modules + prod reinstall" pattern, which is non-interactive, faster (pnpm resolves the prod graph from its CAS cache), and byte-identical in result. Verified locally: `snapcraft pack --destructive-mode` produces `etherpad_2.6.1_amd64.snap` end-to-end in ~3 min. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(snap): unbreak runtime — tsx resolution, var/ writability, env Three runtime crashes surfaced when actually installing the built snap under strict confinement. Fixed each, plus a smoke-test script. - `tsx` is in the `src` workspace's node_modules under pnpm hoisting, not at the snap install root. The wrapper now `cd "${APP_DIR}/src"` and uses bare `--import tsx` (matching `bin/cleanRun.sh`); the prior `--import tsx/esm` triggered ERR_REQUIRE_CYCLE on Etherpad's mixed CJS/ESM source tree. - Etherpad's plugin installer writes `var/installed_plugins.json` via __dirname-relative paths, which resolve to absolute paths inside the read-only snap squashfs (EROFS). snap layouts can't intercept paths inside `$SNAP`, so replace the shipped `var/` dir with a symlink to `/var/snap/etherpad/common/etherpad-app-var/` (auto-created by the wrapper on first run). Persistent state survives `snap refresh`. - Drop the unused `EP_SETTINGS` and `EP_DATA_DIR` env vars from the app's `environment:` block. Etherpad's settings loader doesn't read them — it reads `argv.settings`, which the wrapper already passes via `--settings`. They were producing `[WARN] settings - Unknown Setting` noise on every start. Add `snap/tests/smoke.sh`: rebuild + install + configure test port 9003 + assert listener + curl /health + tail logs. Local verified output: HTTP 200, body {"status":"pass","releaseId":"2.6.1"}, server logs `Etherpad is running` on `http://0.0.0.0:9003/`. .gitignore now excludes destructive-mode build outputs (parts/, stage/, prime/, .craft/, *.snap). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(snap): wrapper unit tests, PR CI build, expanded docs Coverage in snap/tests/ (47 assertions, ~5s, no snapd/sudo/network): - test-snapcraft-yaml.sh: required keys, name validity, daemon-app matches snap name, no etherpad-lite regression, env-var whitelist. - test-cli.sh: path-traversal rejection, .ts/.sh dispatch, default-case rejection, no-args usage. - test-configure.sh: port (1-65535) and ip (v4/v6) validation via mocked snapctl. - test-service-bootstrap.sh: first-run seeding from settings.json.template, sed rewrite of dbType/filename/ip/port, writable-dir creation, snapctl override propagation to node env, idempotency on second run, default fallbacks. - run-all.sh: bash -n syntax check on every wrapper + hook, then sources each test file and reports totals. All assertions use port 9003 (project test convention). CI in .github/workflows/snap-build.yml: - Triggers on PR / push-to-develop touching snap/, settings.json.template, or the workflow itself. - Job 1 wrapper-tests: runs run-all.sh. - Job 2 snap-pack: snapcraft pack --destructive-mode, uploads .snap as PR artifact for sideload. - Stays separate from snap-publish.yml (tag-triggered, store-bound). snap/README.md fully rewritten: - User-facing usage, install, configure - Architecture: file layout, var/-symlink rationale, settings.json rewrite rationale, double-pnpm-install rationale, daemon-name-shares- snap-name rationale - Three test layers with exactly when/why to run each - Dev workflow loop - Publishing maintainer setup - Troubleshooting for every failure mode hit during this PR (EROFS, tsx not found, ERR_REQUIRE_CYCLE, snap-store-down, pnpm prune hang) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(snap): replace dead snapcraft.io/docs/releasing-to-the-snap-store link That URL now 404s. Point at the canonical documentation.ubuntu.com locations instead, broken out into the specific pages a maintainer actually needs: - Register a snap (to claim the name) - snapcraft export-login (to generate the SNAPCRAFT_STORE_CREDENTIALS secret) - Publishing how-to index (root index for everything else) Same fix in the snap-publish.yml header comment. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |