Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
72 changes: 52 additions & 20 deletions .github/workflows/backend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,19 @@ jobs:
run: pnpm build
-
name: Run the backend tests
run: pnpm test
- name: Run the new vitest tests
working-directory: src
run: pnpm run test:vitest
env:
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
run: |
mkdir -p "${{ github.workspace }}/node-report"
pnpm test
- name: Upload Node diagnostic reports on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
path: node-report/
if-no-files-found: ignore
retention-days: 7

withpluginsLinux:
env:
Expand Down Expand Up @@ -136,10 +145,19 @@ jobs:
ep_table_of_contents
-
name: Run the backend tests
run: pnpm test
- name: Run the new vitest tests
working-directory: src
run: pnpm run test:vitest
env:
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
run: |
mkdir -p "${{ github.workspace }}/node-report"
pnpm test
- name: Upload Node diagnostic reports on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
path: node-report/
if-no-files-found: ignore
retention-days: 7

# Windows tests only run on push to develop/master, not on PRs
withoutpluginsWindows:
Expand Down Expand Up @@ -200,12 +218,19 @@ jobs:
name: Run the backend tests
shell: bash
working-directory: src
# --exit makes mocha call process.exit() after the run so a leaked handle
# cannot hang the job on Windows.
run: pnpm test -- --exit
- name: Run the new vitest tests
working-directory: src
run: pnpm run test:vitest
env:
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
run: |
mkdir -p "${{ github.workspace }}/node-report"
pnpm test
- name: Upload Node diagnostic reports on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
path: node-report/
if-no-files-found: ignore
retention-days: 7

withpluginsWindows:
env:
Expand Down Expand Up @@ -294,9 +319,16 @@ jobs:
name: Run the backend tests
shell: bash
working-directory: src
# --exit makes mocha call process.exit() after the run so a leaked handle
# cannot hang the job on Windows.
run: pnpm test -- --exit
- name: Run the new vitest tests
working-directory: src
run: pnpm run test:vitest
env:
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
run: |
mkdir -p "${{ github.workspace }}/node-report"
pnpm test
- name: Upload Node diagnostic reports on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
path: node-report/
if-no-files-found: ignore
retention-days: 7
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ A bundle of defence-in-depth tightening picked up during an internal audit pass

# 3.0.0

3.0 is a feature-heavy release that closes out the self-update programme (Tiers 2 and 3 land alongside Tier 1 from 2.7.3), removes the last identified upstream telemetry vector, and ships a parsed JSONC settings editor, native DOCX export, in-place pad history scrubbing, and an admin UI for GDPR author erasure. It also marks the start of the broader Etherpad app ecosystem (see *Companion apps* below).
3.0 is a feature-heavy release that closes out the self-update programme (Tiers 2 and 3 land alongside Tier 1 from 2.7.3), removes the last identified upstream telemetry vector, and ships a parsed JSONC settings editor, native DOCX export, in-place pad history scrubbing, and an admin UI for GDPR author erasure. It also completes the backend ESM migration and replaces mocha with vitest as the backend test runner, and marks the start of the broader Etherpad app ecosystem (see *Companion apps* below).

### Breaking changes

Expand All @@ -81,6 +81,11 @@ A bundle of defence-in-depth tightening picked up during an internal audit pass
- **`swagger-ui-express` removed.** `/api-docs` now serves a vendored, telemetry-free copy of [Scalar](https://github.com/scalar/scalar) (see the privacy item below). The route, the OpenAPI document, and the rendered output are unchanged for downstream consumers, but anything that introspected `swagger-ui-express` internals will need updating.
- **Debian package depends on `nodejs (>= 24)`.** The signed apt repository at `etherpad.org/apt` is rebuilt against this floor; older Node packages are no longer acceptable as a dependency (#7754).

### Breaking changes for plugin authors

- Migrated the Etherpad backend (everything under `src/node/` and the server-side parts of `src/static/js/pluginfw/`) from CommonJS to ECMAScript modules. **Existing CommonJS plugins continue to load unchanged** — the plugin loader now uses Node's `createRequire` to keep `require()` working synchronously against CJS plugin entry files. ESM plugins are also supported (use `"type": "module"` or `.mjs`, export hooks with `export const`). One contract change: the accessor-property shim that exposed `Settings` top-level fields directly on the `require()` result has been removed (it was dead code under ESM). Plugins reading core settings via `require('ep_etherpad-lite/node/utils/Settings').toolbar` must now use `import settings from '...'` (ESM) or `require('...').default.toolbar` (CJS via the bridge). See `doc/plugins.md` for the full updated contract.
- Replaced mocha with vitest as the backend test runner. `pnpm test` now runs vitest. Plugin authors with backend test suites that ran under the core mocha runner via `../node_modules/ep_*/static/tests/backend/specs/**` should expect to migrate their tests to vitest.

### Companion apps

This release coincides with the launch of two ecosystem projects, both maintained under the [`ether` org](https://github.com/ether) and able to talk to any 3.x Etherpad server over its existing HTTP / WebSocket API:
Expand Down
12 changes: 12 additions & 0 deletions doc/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ name of a function exported by the named module. See
[`module.exports`](https://nodejs.org/docs/latest/api/modules.html#modules_module_exports)
for how to export a function.

> **Note (Etherpad ≥ 2.7.x):** the core was migrated to ECMAScript modules,
> but the plugin loader uses Node's `createRequire` so existing CommonJS
> plugins (the documented format above) continue to load unchanged. ESM
> plugins are also supported — name your hook entry file with a `.mjs`
> extension or set `"type": "module"` in your plugin's `package.json`, and
> export hook functions with `export const`. One contract change: plugins
> that previously read core settings via `require('ep_etherpad-lite/node/utils/Settings').toolbar`
> must now use either `import settings from 'ep_etherpad-lite/node/utils/Settings'`
> (ESM) or `require('ep_etherpad-lite/node/utils/Settings').default.toolbar`
> (CJS via the bridge). The accessor-property shim that exposed top-level
> fields directly on the require() result is gone.

For the module name you can omit the `.js` suffix, and if the file is `index.js`
you can use just the directory name. You can also omit the module name entirely,
in which case it defaults to the plugin name (e.g., `ep_example`).
Expand Down
Loading