Skip to content

Support target-controlled push relay and staged file apply#277

Open
adamziel wants to merge 5 commits into
trunkfrom
fresh-work-20260624-175304
Open

Support target-controlled push relay and staged file apply#277
adamziel wants to merge 5 commits into
trunkfrom
fresh-work-20260624-175304

Conversation

@adamziel

@adamziel adamziel commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a target-controlled relay export transport alongside the existing direct HTTP transport, plus a relay-source worker for outbound-only/local sources.
  • Adds the WordPress plugin-owned push-session API so a remote target can create a session, emit target-authored export requests, accept local source responses, report progress, and abort pending work.
  • Adds filesystem push primitives for the safer apply shape: files-plan, materialize-docroot, and apply-staged-files.
  • Documents the relay/session/staged-apply flow and covers direct relay, plugin relay, planning, materialization, symlink materialization, staged swaps, and interrupted apply resume.

Why

Studio push should be initiated by the local user but still keep the remote target in charge of importer sequencing, cursors, retries, safety checks, and final writes. This PR keeps direct pulls working as-is, adds a relay path for push-style networking, and adds the first target-side filesystem planning/apply commands needed to avoid writing changed PHP code directly into the live tree during transfer.

Issue: #276

How to try

Build the PHAR:

composer build:phar

For the relay transport, start the source worker where the local/source exporter is reachable:

RELAY_DIR=/tmp/reprint-relay
SOURCE_STATE=/tmp/reprint-source-state
php reprint.phar relay-source "http://127.0.0.1:8888/?reprint-api" \
  --secret=TOKEN \
  --relay-dir="$RELAY_DIR" \
  --state-dir="$SOURCE_STATE" \
  --fs-root="$SOURCE_STATE/fs" \
  --relay-allow-path=/absolute/source/path/wp-content/themes/my-theme \
  --relay-idle-timeout=300

Then run the target importer through the same relay directory:

TARGET_STATE=/tmp/reprint-target-state
TARGET_FILES=/tmp/reprint-target-files
php reprint.phar preflight "http://127.0.0.1:8888/?reprint-api" \
  --secret=TOKEN \
  --transport=relay \
  --relay-dir="$RELAY_DIR" \
  --state-dir="$TARGET_STATE" \
  --fs-root="$TARGET_FILES"

php reprint.phar files-pull "http://127.0.0.1:8888/?reprint-api" \
  --secret=TOKEN \
  --transport=relay \
  --relay-dir="$RELAY_DIR" \
  --state-dir="$TARGET_STATE" \
  --fs-root="$TARGET_FILES" \
  --only=/absolute/source/path/wp-content/themes/my-theme

For the staged filesystem apply primitives after preflight + files-index/files-pull:

php reprint.phar files-plan \
  --state-dir="$TARGET_STATE" \
  --fs-root="$TARGET_FILES" \
  --target-root=/srv/htdocs \
  --exclude='wp-admin/**'

php reprint.phar materialize-docroot \
  --state-dir="$TARGET_STATE" \
  --fs-root="$TARGET_FILES" \
  --materialize-to=/tmp/reprint-staged-site

php reprint.phar apply-staged-files \
  --state-dir="$TARGET_STATE" \
  --staged-root=/tmp/reprint-staged-site \
  --target-root=/srv/htdocs \
  --maintenance-file=/srv/htdocs/.maintenance

Notes:

  • files-plan blocks WordPress core files and wp-config.php by default, warns on loose top-level PHP, and reports target writability when --target-root is supplied.
  • Deleted files are shown in the plan but are not selected by default yet because apply-staged-files intentionally does not delete target files.
  • apply-staged-files copies uploads/fonts before maintenance mode, prepares plugin/theme .new trees merged with live unselected files, swaps through .bak, swaps loose top-level PHP, clears the current-operation journal, and invalidates PHP opcache entries when available.

Validation

  • php -n -l packages/reprint-importer/src/import.php
  • php -n vendor/bin/phpunit --configuration tests/phpunit.xml tests/Import/FilesPlanMaterializeApplyTest.php tests/Import/FlatDocrootWpConfigTest.php tests/Import/RelayTransportTest.php tests/SiteExportPushSessionTest.php
  • npm --prefix tests/e2e test -- tests/import-53-plugin-push-relay-api.test.js tests/import-54-push-apply-primitives.test.js
  • composer build:phar
  • npm --prefix tests/e2e test -- tests/import-52-relay-transport.test.js ⚠️ blocked locally because this workspace does not have passwordless sudo for /srv/e2e-sites/basic; the suite passed in GitHub Actions.
  • Full phpunit is not a useful local signal in this workspace because the MySQL-backed producer tests cannot connect to a local MySQL server; the GitHub PHPUnit matrix passed.
  • gh pr checks 277 --watch ✅ all GitHub checks passed after the follow-up e2e PHAR invocation fix.

@adamziel adamziel force-pushed the fresh-work-20260624-175304 branch from f9d8cc5 to d7be100 Compare June 25, 2026 00:10
@adamziel adamziel marked this pull request as ready for review June 25, 2026 00:11
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Pull pipeline performance — large-directory

Site: large-directory · 2,000+ plus targeted file-transfer scenarios files · 10,000 posts · 25,000 postmeta · PHP 8.5.7

Stage PR trunk Δ Status Details
playground-sqlite-db-pull 9.29 s 9.34 s ⚪ -50 ms (-0.5%) condition=db-pull in PHP.wasm
runtime=php.wasm 8.3
wp_mysql_parser=enabled
mode=lexer
native_lexer=verified
native_token_stream=WP_MySQL_Native_Token_Stream
native_token_count=18
native_parser=selected
trunk: condition=db-pull in PHP.wasm
runtime=php.wasm 8.3
wp_mysql_parser=enabled
mode=lexer
native_lexer=verified
native_token_stream=WP_MySQL_Native_Token_Stream
native_token_count=18
native_parser=selected
playground-sqlite-db-apply 3.55 s 3.48 s ⚪ +71 ms (+2.0%) condition=db-apply to SQLite in PHP.wasm
runtime=php.wasm 8.3
wp_mysql_parser=enabled
mode=parser
native_lexer=verified
native_token_stream=WP_MySQL_Native_Token_Stream
native_token_count=18
native_parser=verified
native_ast=WP_MySQL_Native_Parser_Node
sqlite_driver_parser=verified
trunk: condition=db-apply to SQLite in PHP.wasm
runtime=php.wasm 8.3
wp_mysql_parser=enabled
mode=parser
native_lexer=verified
native_token_stream=WP_MySQL_Native_Token_Stream
native_token_count=18
native_parser=verified
native_ast=WP_MySQL_Native_Parser_Node
sqlite_driver_parser=verified
Total 12.84 s 12.82 s ⚪ +21 ms (+0.2%)

Numbers carry runner noise; treat single-run deltas as directional, not authoritative.

📈 Trunk performance history — commit-by-commit timeline.

@adamziel adamziel force-pushed the fresh-work-20260624-175304 branch 11 times, most recently from 657c4a3 to cbee0ff Compare June 25, 2026 10:24
@adamziel adamziel force-pushed the fresh-work-20260624-175304 branch from cbee0ff to be5076e Compare June 25, 2026 11:00
@adamziel adamziel changed the title Support target-controlled relay export transport Support target-controlled push relay and staged file apply Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant