TL;DR

  • Build a matrix over Nextcloud branches and PHP versions.
  • Checkout Nextcloud server + app sources, then sync the app into the server tree.
  • Run JS unit tests, build assets, install PHP deps, then run PHP unit tests.
  • Spin up a local PHP server and run Playwright smoke tests.

Why this pipeline

I wanted CI that behaves like a real Nextcloud install: same server tree, same app path, same install and enable flow. The goal is to catch breakages across Nextcloud branches early.

Matrix setup

A small setup job renders the matrix and passes it to the test job:

  • matrix-config runs a Node script and exports JSON.
  • server-tests consumes it with fromJSON(...).

This keeps the matrix logic out of the workflow and lets me change targets in code.

Flow overview

  1. Checkout Nextcloud server (by branch).
  2. Checkout app sources into app-src.
  3. Sync app into server/apps/opsdash.
  4. JS install + unit tests + build.
  5. PHP setup + Composer install + PHPUnit.
  6. Install and enable Nextcloud, plus Deck.
  7. Start PHP server, seed data, run Playwright.
  8. Upload Playwright report artifacts.

Key workflow steps

Sync app into the server tree

mkdir -p server/apps/${APP_NAME}
rsync -a --delete app-src/opsdash/ server/apps/${APP_NAME}/
rsync -a app-src/tools/security/ server/apps/${APP_NAME}/tools/security/ 2>/dev/null || true

Install + enable Nextcloud

php occ maintenance:install --database=sqlite --database-name=nextcloud --admin-user admin --admin-pass admin
php occ app:enable $APP_NAME

Playwright smoke tests

npx playwright install --with-deps chromium
npm run test:e2e

Notes and tradeoffs

  • SQLite keeps install fast and reproducible.
  • The app is tested inside the Nextcloud server tree, not standalone.
  • Playwright runs against a real server on 127.0.0.1:8080.
  • CI is slower but closer to production behavior.

What I would improve next

  • Cache node_modules and Composer deps between runs.
  • Split E2E tests into a separate job to avoid blocking unit tests.
  • Add a retry strategy for flaky UI tests.