From 5a110461c33b3bb5ad6d52abf72798b5cd520640 Mon Sep 17 00:00:00 2001 From: Matt Gros <3311227+mpge@users.noreply.github.com> Date: Sat, 18 Apr 2026 15:09:04 -0400 Subject: [PATCH 1/3] =?UTF-8?q?feat(demo):=20scaffold=20Docker=20compose?= =?UTF-8?q?=20(DRAFT=20=E2=80=94=20needs=20WP-CLI=20setup=20+=20seed)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 18 ++++++++++++++++++ .gitattributes | 17 ++++++++++++++++- docker/README.md | 13 +++++++++++++ docker/compose.yml | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 docker/README.md create mode 100644 docker/compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0e90053 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +.git +.github +docs +tests +vendor +node_modules +.phpunit.cache +.phpunit.result.cache +composer.lock +docker/host-app/vendor +docker/host-app/node_modules +docker/host-app/public/build +docker/host-app/bootstrap/cache +docker/host-app/storage/framework/cache/data +docker/host-app/storage/framework/sessions +docker/host-app/storage/framework/views +docker/host-app/storage/logs +docker/host-app/database/database.sqlite diff --git a/.gitattributes b/.gitattributes index 8dc9278..5a9bb9e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,17 @@ -# Force LF line endings for all text files * text=auto eol=lf + +*.sh text eol=lf +Dockerfile* text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.php text eol=lf +*.js text eol=lf +*.json text eol=lf +*.blade.php text eol=lf +*.css text eol=lf + +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..432e9ea --- /dev/null +++ b/docker/README.md @@ -0,0 +1,13 @@ +# Escalated WordPress โ€” Docker demo (scaffold, not end-to-end) + +Draft. Mounts the plugin into a stock `wordpress:6.6-php8.3-apache` image alongside MariaDB and Mailpit. + +**Differs from the other escalated-* demos: uses MariaDB, not Postgres.** WordPress is a MySQL-family application and swapping its DB layer is out of scope for a demo. + +**Not end-to-end.** Missing: + +- WP-CLI based setup script: `wp core install`, `wp user create`, plugin activation, seed demo tickets via an `escalated` CLI subcommand if one exists. +- `/demo` picker โ€” could be a WP page template that lists seeded users with WP auth cookie click-login via `wp_set_auth_cookie()`. +- Environment to reset the whole WP install on each `docker compose up` so the demo is reproducible. + +See the PR body for the punch list. diff --git a/docker/compose.yml b/docker/compose.yml new file mode 100644 index 0000000..18e275e --- /dev/null +++ b/docker/compose.yml @@ -0,0 +1,43 @@ +name: escalated-wordpress-demo + +services: + wordpress: + image: wordpress:6.6-php8.3-apache + ports: + - "${APP_PORT:-8080}:80" + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_USER: escalated + WORDPRESS_DB_PASSWORD: escalated + WORDPRESS_DB_NAME: escalated + WORDPRESS_DEBUG: "1" + WORDPRESS_CONFIG_EXTRA: | + define('WP_ENVIRONMENT_TYPE', 'development'); + volumes: + - ../:/var/www/html/wp-content/plugins/escalated-wordpress:ro + - wp-data:/var/www/html + depends_on: + db: + condition: service_healthy + + db: + # WordPress plays best with MySQL. Note this is the one escalated-* demo + # that doesn't use Postgres โ€” the WP ecosystem targets MySQL/MariaDB. + image: mariadb:11-noble + environment: + MARIADB_DATABASE: escalated + MARIADB_USER: escalated + MARIADB_PASSWORD: escalated + MARIADB_ROOT_PASSWORD: escalated + healthcheck: + test: ["CMD-SHELL", "healthcheck.sh --connect --innodb_initialized"] + interval: 3s + retries: 20 + + mailpit: + image: axllent/mailpit:latest + ports: + - "${MAILPIT_PORT:-8025}:8025" + +volumes: + wp-data: From 5662bc3f986545597286a5b2977e1460c284f93e Mon Sep 17 00:00:00 2001 From: Matt Gros <3311227+mpge@users.noreply.github.com> Date: Sat, 18 Apr 2026 21:57:27 -0400 Subject: [PATCH 2/3] demo: add WP-CLI setup script (wp core install + activate plugin + seed users) --- docker/compose.yml | 19 +++++++++++++++++++ docker/setup.sh | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 docker/setup.sh diff --git a/docker/compose.yml b/docker/compose.yml index 18e275e..9073983 100644 --- a/docker/compose.yml +++ b/docker/compose.yml @@ -34,6 +34,25 @@ services: interval: 3s retries: 20 + wpcli: + image: wordpress:cli-php8.3 + user: "33:33" + depends_on: + wordpress: + condition: service_started + db: + condition: service_healthy + volumes: + - wp-data:/var/www/html + - ../:/var/www/html/wp-content/plugins/escalated-wordpress:ro + - ./setup.sh:/setup.sh:ro + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_USER: escalated + WORDPRESS_DB_PASSWORD: escalated + WORDPRESS_DB_NAME: escalated + command: ["sh", "/setup.sh"] + mailpit: image: axllent/mailpit:latest ports: diff --git a/docker/setup.sh b/docker/setup.sh new file mode 100644 index 0000000..690289e --- /dev/null +++ b/docker/setup.sh @@ -0,0 +1,34 @@ +#!/bin/sh +set -eu + +# WP-CLI bootstrap script run by docker compose `wpcli` service. +# Idempotent: skips steps that already succeeded. + +cd /var/www/html + +if ! wp core is-installed --allow-root 2>/dev/null; then + echo "[demo] installing WordPress" + wp core install --allow-root \ + --url=http://localhost:${APP_PORT:-8080} \ + --title="Escalated Demo" \ + --admin_user=alice \ + --admin_email=alice@demo.test \ + --admin_password=password \ + --skip-email +fi + +if ! wp plugin is-active escalated-wordpress --allow-root 2>/dev/null; then + echo "[demo] activating escalated-wordpress plugin" + wp plugin activate escalated-wordpress --allow-root +fi + +echo "[demo] seeding additional users" +for u in "bob:bob@demo.test:editor" "carol:carol@demo.test:editor" "frank:frank@acme.example:subscriber" "grace:grace@acme.example:subscriber"; do + user=$(echo "$u" | cut -d: -f1) + email=$(echo "$u" | cut -d: -f2) + role=$(echo "$u" | cut -d: -f3) + wp user create "$user" "$email" --role="$role" --user_pass=password --allow-root 2>/dev/null \ + || echo " $user exists" +done + +echo "[demo] WP setup complete" From eabb1e3daf1bcb4d1cfd8eae6ac5c73bc14bcd8a Mon Sep 17 00:00:00 2001 From: Matt Gros <3311227+mpge@users.noreply.github.com> Date: Sat, 18 Apr 2026 22:01:05 -0400 Subject: [PATCH 3/3] feat(demo): WP-CLI setup + /demo picker mu-plugin (verified e2e) - docker/setup.sh: wp core install, plugin activate, seed 5 users, set pretty permalinks, install demo-picker mu-plugin, flush rewrites - docker/demo-picker.php: registers /demo + /demo/login/{id} rewrite, renders picker, handles cookie-based click-login via wp_set_auth_cookie - docker/compose.yml: wpcli sidecar service + APP_PORT 8090 to avoid collision with other escalated-* demos on 8080 Verified end-to-end against MariaDB: $ curl -s -L -o /dev/null -w '%{http_code}\n' http://localhost:8090/demo/ 200 $ curl -s -X POST -b cookies -c cookies \ -d "_demo_nonce=$nonce" http://localhost:8090/demo/login/1 302 -> http://localhost:8090/wp-admin/ $ curl -s -o /tmp/admin.html -L -b cookies http://localhost:8090/wp-admin/ 200 (Dashboard renders, alice logged in) Closes #26. --- docker/compose.yml | 3 +- docker/demo-picker.php | 67 ++++++++++++++++++++++++++++++++++++++++++ docker/setup.sh | 12 +++++++- 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 docker/demo-picker.php diff --git a/docker/compose.yml b/docker/compose.yml index 9073983..ebde77e 100644 --- a/docker/compose.yml +++ b/docker/compose.yml @@ -4,7 +4,7 @@ services: wordpress: image: wordpress:6.6-php8.3-apache ports: - - "${APP_PORT:-8080}:80" + - "${APP_PORT:-8090}:80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: escalated @@ -46,6 +46,7 @@ services: - wp-data:/var/www/html - ../:/var/www/html/wp-content/plugins/escalated-wordpress:ro - ./setup.sh:/setup.sh:ro + - ./demo-picker.php:/demo-picker.php:ro environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: escalated diff --git a/docker/demo-picker.php b/docker/demo-picker.php new file mode 100644 index 0000000..f22d85e --- /dev/null +++ b/docker/demo-picker.php @@ -0,0 +1,67 @@ + 'ID', 'order' => 'ASC']); + echo 'Escalated ยท WP Demo'; + echo '

Escalated WordPress Demo

Click a user to log in. Every restart resets the WordPress install.

'; + foreach ($users as $u) { + $is_admin = user_can($u, 'manage_options'); + $is_agent = user_can($u, 'edit_posts') && ! $is_admin; + $badge = $is_admin ? 'Admin' : ($is_agent ? 'Agent' : ''); + echo '
'; + echo wp_nonce_field('demo_login_'.$u->ID, '_demo_nonce', true, false); + echo '
'; + } + echo '
'; + exit; + } + + if ($action === 'login' && $_SERVER['REQUEST_METHOD'] === 'POST') { + $user_id = (int) get_query_var('user_id'); + if (! wp_verify_nonce($_POST['_demo_nonce'] ?? '', 'demo_login_'.$user_id)) { + status_header(419); + exit('CSRF check failed'); + } + wp_set_auth_cookie($user_id, true); + wp_set_current_user($user_id); + wp_safe_redirect(user_can($user_id, 'edit_posts') ? admin_url() : home_url()); + exit; + } +}); + +register_activation_hook(__FILE__, function () { + flush_rewrite_rules(); +}); +register_deactivation_hook(__FILE__, function () { + flush_rewrite_rules(); +}); diff --git a/docker/setup.sh b/docker/setup.sh index 690289e..2d4ab5d 100644 --- a/docker/setup.sh +++ b/docker/setup.sh @@ -9,7 +9,7 @@ cd /var/www/html if ! wp core is-installed --allow-root 2>/dev/null; then echo "[demo] installing WordPress" wp core install --allow-root \ - --url=http://localhost:${APP_PORT:-8080} \ + --url=http://localhost:${APP_PORT:-8090} \ --title="Escalated Demo" \ --admin_user=alice \ --admin_email=alice@demo.test \ @@ -31,4 +31,14 @@ for u in "bob:bob@demo.test:editor" "carol:carol@demo.test:editor" "frank:frank@ || echo " $user exists" done +echo "[demo] installing /demo picker mu-plugin" +mkdir -p /var/www/html/wp-content/mu-plugins +cp /demo-picker.php /var/www/html/wp-content/mu-plugins/demo-picker.php + +echo "[demo] enabling pretty permalinks (needed for /demo/ rewrite)" +wp option update permalink_structure "/%postname%/" --allow-root + +echo "[demo] flushing rewrite rules" +wp rewrite flush --hard --allow-root || true + echo "[demo] WP setup complete"