This project uses a lightweight release flow:
- Run a reproducible local check script.
- Run optional failure-path checks.
- Tag the release.
- Deploy and run post-deploy smoke checks.
Run from repo root:
./tests/integration/release-check.shWhat it does:
- Verifies required local tools (
git,php). - Fails on dirty working tree by default.
- Runs local tiny unit test:
php tests/unit/padfile-pathnormalizer-test.php
- Runs PHPUnit unit suite when available:
vendor/bin/phpunit --testsuite unit- If
vendor/bin/phpunitis missing, install once with:composer install --no-interaction
- If Nextcloud test credentials are present, runs core E2E checks:
- pad flow
- protected cookie contract (session cookie attrs + no
HttpOnlyfor current Etherpad runtime compatibility) - lifecycle state guards
- public folder share flow
- public single-file share flow
- external URL security checks
Frontend checks are separate and should be run before release/deploy whenever
src/, package.json, or Vite/Vitest config changed:
npm test
npm run buildThe Vite build writes runtime assets to js/; those built files must be present
in the deployed app.
Browser-level end-to-end checks live in a separate Playwright suite that drives
a real Nextcloud instance (NewFileMenu create, viewer mount, share + revoke,
trash/restore, recovery, legacy migration, …). It is target-agnostic and
credential-driven via tests/e2e/.env.e2e:
npm run test:e2eSetup, the required env vars, and the per-spec coverage are documented in tests/e2e/README.md. This suite is not yet wired into CI (a reproducible Docker target is tracked in #112), so run it manually against a test instance before a release when frontend flows changed.
Environment variables for E2E:
NC_BASE_URLNC_USERNC_APP_PASSWORD
Optional first argument:
- path prefix used by E2E scripts, for example:
./tests/integration/release-check.sh "/release-candidate"These checks intentionally expect errors and usually require an Etherpad outage/misconfiguration phase:
RUN_FAILURE_PATHS=1 FAILURE_PATHS_PREPARED=1 NC_BASE_URL=... NC_USER=... NC_APP_PASSWORD=... ./tests/integration/release-check.sh "/release-failure"Included:
- sync failure path
- trash deferred-delete failure path
- restore failure path
Optional debug-only lifecycle fault-injection checks:
RUN_DEBUG_FAULT_PATHS=1 NC_BASE_URL=... NC_USER=... NC_APP_PASSWORD=... ./tests/integration/release-check.sh "/release-debug-faults"Notes:
release-check.shwill only run failure-path tests when both flags are set:RUN_FAILURE_PATHS=1FAILURE_PATHS_PREPARED=1
- This prevents false failures on healthy environments where outage conditions were not prepared.
- Requires admin credentials.
- Requires Nextcloud
debugmode enabled.
After checks pass:
git tag -a vX.Y.Z -m "Etherpad Integration for Nextcloud vX.Y.Z"
git push origin HEAD
git push origin vX.Y.ZRe-run required checks against target environment:
NC_BASE_URL=... NC_USER=... NC_APP_PASSWORD=... ./tests/integration/release-check.sh "/release-post-deploy"Optional deploy helper (rsync with production-safe excludes):
DEPLOY_SSH_TARGET="user@host" \
DEPLOY_APP_PATH="/var/www/virtual/user/html/apps/etherpad_nextcloud" \
./scripts/deploy-rsync.shNotes:
- Excludes by default:
.git/,node_modules/,vendor/,tests/,docs/,.phpunit.cache/,_copy_probe/,.DS_Store. node_modules/should not be deployed, but the builtjs/directory should be.- Set
RSYNC_DELETE=1only when you explicitly want remote cleanup.
After deploy, verify that the historical query-budget warning is not present anymore:
ssh <server> 'grep -n "PadCreateController::create executed" /path/to/nextcloud.log | tail -n 20'
ssh <server> 'grep -nE "executed [0-9]+ queries" /path/to/nextcloud.log | tail -n 20'Expected result: no new warnings for PadCreateController::create above the Nextcloud warning threshold.
- Protected pad open responses intentionally attach one explicit
Set-Cookieheader for Etherpad session bootstrapping. - We use explicit cookie attributes (
Domain,Secure,SameSite=None) for cross-subdomain iframe sessions. - Current contract: this app writes one Etherpad session cookie on these responses; no additional custom cookies are added by this app on the same response.
- If future features require multiple custom cookies on the same response, cookie handling must be extended deliberately and covered by dedicated tests.