Make the pull-reprint command work with native PHP#3881
Conversation
This commit includes a static reprint.phar build, because the latest HEAD in the reprint repo includes a fix we need (that hasn't been released yet)
| // For sites imported via `studio pull-reprint`, the pull command | ||
| // persists the computed start options to start-options.json so the | ||
| // daemon doesn't need to recompute them (which would spin up PHP | ||
| // WASM to extract runtime.php constants from the imported site). | ||
| if ( ! config.useExactMountLayout && config.blueprint?.uri ) { | ||
| try { | ||
| const optionsPath = path.join( path.dirname( config.blueprint.uri ), 'start-options.json' ); | ||
| if ( fs.existsSync( optionsPath ) ) { | ||
| const saved = JSON.parse( fs.readFileSync( optionsPath, 'utf-8' ) ); | ||
| if ( saved.useExactMountLayout ) { | ||
| config.mountsBeforeInstall = saved.mountsBeforeInstall; | ||
| config.mounts = saved.mounts; | ||
| config.wordpressInstallMode = saved.wordpressInstallMode ?? config.wordpressInstallMode; | ||
| config.useExactMountLayout = true; | ||
| logToConsole( `Loaded persisted start options from ${ optionsPath } before startup` ); | ||
| } | ||
| } | ||
| } catch { | ||
| // Ignore missing or invalid start options and continue with the provided config. | ||
| } | ||
| } |
There was a problem hiding this comment.
We get this data straight from the config object sent over IPC. No need to re-read start-options.json
| } ); | ||
|
|
||
| const wordpressInstallModeSchema = z.enum( [ | ||
| const wordpressInstallModeSchema: z.ZodType< WordPressInstallMode > = z.enum( [ |
There was a problem hiding this comment.
We cannot derive a schema from the WordPressInstallMode type, but we can ensure that our manually defined schema matches the given type.
There was a problem hiding this comment.
I had to upgrade Reprint to the latest release to make my changes work. This new approach ensures we still ship a fixed Reprint version with every release (i.e. it's not updated on the user's machine), but we also don't have to explicitly change our code to get the latest version. I think that's a good approach
There was a problem hiding this comment.
epeicher
left a comment
There was a problem hiding this comment.
Thanks for solving this @fredrikekelund! This is now required after merging #3786 because the pull-reprint is now failing. With this solution, we would not need #3922.
I have added an early review, and the changes look good to me. I have just left some questions/comments. Please let me know when you resolve the merging conflicts and I can give some testing.
There was a problem hiding this comment.
| } | ||
|
|
||
| reject( new Error( `PHP command failed (code: ${ code })` ) ); | ||
| reject( new Error( `PHP command (${ args.join( ' ' ) }) failed (code: ${ code })` ) ); |
There was a problem hiding this comment.
In case of an error, is the stderr logged somewhere after these changes?
There was a problem hiding this comment.
This change was actually a leftover that I reverted.
What happens to the output of the child process depends on the mode option passed to the runPhpCommand() function
📊 Performance Test ResultsComparing 1100980 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
There was a problem hiding this comment.
The changes in this file are necessary to prevent auto_prepend_file from firing twice for requests that target PHP files directly (like /wp-admin/admin-ajax.php).
If auto_prepend_file fires twice, it could cause classes to be redeclared, for example, which triggers an error.
There was a problem hiding this comment.
Thanks for working on this @fredrikekelund! I have tested, and the pull-reprint works, but when the site is going to start, I'm getting the following error in the logs:
Error: Error establishing a database connection.
I am testing this by running:
node apps/cli/dist/cli/main.mjs pull-reprint --url <site-url>
This happens consistently when pulling a new site and creating a new site in Studio:
| ); | ||
| preflight = await runPreflight( studioMetadata, apiUrl, secret, verbose ); | ||
| preflight = await runPreflight( | ||
| SITE_RUNTIME_NATIVE_PHP, |
There was a problem hiding this comment.
Should we use a dynamic value for this SITE_RUNTIME_NATIVE_PHP? I'm wondering what happens if a user selects the playground runtime in Studio. Not a blocker, just a question for consideration.
There was a problem hiding this comment.
We need to iterate on this in another PR. I'm trying to think of ways that we could tie the pull-reprint state management closer to the regular Studio state management (which is site-based rather than pull-based). That would help address this issue
| const asset = release.assets.find( ( a ) => a.name === 'reprint.phar' ); | ||
| if ( ! asset ) { | ||
| throw new Error( | ||
| `No asset found in latest wp-cli-sqlite-command release ${ release.tag_name }` |
There was a problem hiding this comment.
Wrong message from another Error probably
|
After some investigation, I have created this draft PR in Reprint that seems to fix the issue described here: To test it, what I do is:
Hope that helps |
I could not reproduce this exact error, but the root cause of this was a late change on my part from passing Your PR seems worth considering, but I changed the option back to |
epeicher
left a comment
There was a problem hiding this comment.
Thanks @fredrikekelund for addressing the comments. This is working perfectly now, I have tested a new pull and an incremental pull and everything works as expected. LGTM!
| ); | ||
| preflight = await runPreflight( studioMetadata, apiUrl, secret, verbose ); | ||
| preflight = await runPreflight( | ||
| SITE_RUNTIME_NATIVE_PHP, |
I think that PR is not required eventually, your changes fix the original issue, I have closed it and linked back here for the reasoning. |
Related issues
How AI was used in this PR
I used Claude to help me with the initial implementation. Then I had to slow down to understand the
pull-reprintarchitecture and the changes that Claude made. I went through a few rounds of iterations by hand and with Claude before reaching the final state.Proposed Changes
The
pull-reprintcommand comes with more assumptions about the PHP runtime than most other Studio features do. The prime example is how it uses PHP-WASM-based parsing to extract constants fromruntime.php.Studio now has two PHP runtimes, and native PHP is slated to become the new default shortly. This PR makes the
pull-reprintcommand work with native PHP. This implementation does not cover all bases, but it works when pulling a typical WordPress.com site. We'll keep iterating to refine the experience.Testing Instructions
npm run cli:buildSTUDIO_ENABLE_PULL_REPRINT=1 STUDIO_RUNTIME=native-php node apps/cli/dist/cli/main.mjs pull-reprintPre-merge Checklist