fix(#7570): bundle DB drivers, add regression CI (#7572)

* docs: design spec for issue #7570 (ueberdb2 driver bundling)

Spec for the upstream ueberDB fix (move 10 drivers back from optional
peer deps to dependencies) plus downstream etherpad-lite safety net
(explicit driver list + build-test-db-drivers CI job covering all 10
via presence check and MySQL+Postgres smoke tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: implementation plan for issue #7570 ueberdb2 driver bundling

Covers upstream ueberDB PR (move drivers from optional peer deps back
to dependencies, publish 5.0.46) and downstream etherpad-lite PR
(bump ueberdb2, defensive driver list, build-test-db-drivers CI job
with presence + MySQL + Postgres stages gating publish).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(#7570): bundle DB drivers, add regression CI

- Bump ueberdb2 to ^5.0.47 (upstream ueberDB PR #939 re-bundles drivers
  as real dependencies instead of optional peer deps, fixing the class
  of Docker-prod "Cannot find module" failures).
- Declare all 10 ueberdb2 DB drivers as direct src dependencies as a
  defensive safety net against a future upstream drift.
- Add build-test-db-drivers CI job that blocks the publish job:
    * all-10-drivers presence check in the built prod image
    * end-to-end MySQL smoke (reproduces the #7570 repro)
    * end-to-end Postgres smoke
  Any stage failure blocks Docker Hub / GHCR publish.

Supersedes #7571.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(ci): run driver presence test from src/ so node_modules resolves

The presence test ran node from the default cwd (/opt/etherpad-lite),
but the drivers are installed under /opt/etherpad-lite/src/node_modules
by the monorepo workspace. Adding `-w /opt/etherpad-lite/src` makes
Node resolve modules from src/node_modules where pnpm places them.

Matches how the production container itself runs: `pnpm run prod` is
invoked from src/ (cross-env + node --require tsx/cjs node/server.ts).

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
John McLear 2026-04-20 18:10:01 +01:00 committed by GitHub
parent f553cdff28
commit 053f6d8343
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 2392 additions and 11 deletions

View file

@ -77,8 +77,130 @@ jobs:
(cd src && gnpm run test-container)
git clean -dxf .
build-test-db-drivers:
runs-on: ubuntu-latest
permissions:
contents: read
services:
mysql:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: etherpad
MYSQL_USER: etherpad
MYSQL_PASSWORD: password
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping -h 127.0.0.1 -uroot -ppassword"
--health-interval=5s
--health-timeout=5s
--health-retries=20
postgres:
image: postgres:16
env:
POSTGRES_DB: etherpad
POSTGRES_USER: etherpad
POSTGRES_PASSWORD: password
ports:
- 5432:5432
options: >-
--health-cmd="pg_isready -U etherpad -d etherpad"
--health-interval=5s
--health-timeout=5s
--health-retries=20
steps:
-
name: Check out
uses: actions/checkout@v6
with:
path: etherpad
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
-
name: Build production image
uses: docker/build-push-action@v7
with:
context: ./etherpad
target: production
load: true
tags: ${{ env.TEST_TAG }}
cache-from: type=gha
cache-to: type=gha,mode=max
-
name: Driver presence test (all 10 ueberdb2 drivers must resolve)
run: |
docker run --rm -w /opt/etherpad-lite/src "$TEST_TAG" node -e "
const mods = [
'@elastic/elasticsearch','cassandra-driver','mongodb','mssql',
'mysql2','nano','pg','redis','rethinkdb','surrealdb'
];
let fail = false;
for (const m of mods) {
try { require(m); console.log('ok', m); }
catch (e) { console.error('MISSING', m, e.message); fail = true; }
}
if (fail) process.exit(1);
"
-
name: MySQL smoke — start Etherpad against mysql service
run: |
docker run --rm -d \
--network host \
-e NODE_ENV=production \
-e ADMIN_PASSWORD=admin \
-e DB_TYPE=mysql \
-e DB_HOST=127.0.0.1 \
-e DB_PORT=3306 \
-e DB_NAME=etherpad \
-e DB_USER=etherpad \
-e DB_PASS=password \
-e DB_CHARSET=utf8mb4 \
-e DEFAULT_PAD_TEXT="Test " \
--name et-mysql "$TEST_TAG"
for i in $(seq 1 60); do
if curl -sf http://127.0.0.1:9001/ >/dev/null; then
echo "mysql smoke: Etherpad is serving /"
docker rm -f et-mysql
exit 0
fi
sleep 2
done
echo "mysql smoke: timed out waiting for Etherpad"
docker logs et-mysql || true
docker rm -f et-mysql || true
exit 1
-
name: Postgres smoke — start Etherpad against postgres service
run: |
docker run --rm -d \
--network host \
-e NODE_ENV=production \
-e ADMIN_PASSWORD=admin \
-e DB_TYPE=postgres \
-e DB_HOST=127.0.0.1 \
-e DB_PORT=5432 \
-e DB_NAME=etherpad \
-e DB_USER=etherpad \
-e DB_PASS=password \
-e DEFAULT_PAD_TEXT="Test " \
--name et-postgres "$TEST_TAG"
for i in $(seq 1 60); do
if curl -sf http://127.0.0.1:9001/ >/dev/null; then
echo "postgres smoke: Etherpad is serving /"
docker rm -f et-postgres
exit 0
fi
sleep 2
done
echo "postgres smoke: timed out waiting for Etherpad"
docker logs et-postgres || true
docker rm -f et-postgres || true
exit 1
publish:
needs: build-test
needs: [build-test, build-test-db-drivers]
if: github.event_name == 'push'
runs-on: ubuntu-latest
permissions: