Skip to content

Implement import/export in CLI#2963

Open
fredrikekelund wants to merge 17 commits intostu-1354-site-picker-syncfrom
stu-1351-import-export-in-cli
Open

Implement import/export in CLI#2963
fredrikekelund wants to merge 17 commits intostu-1354-site-picker-syncfrom
stu-1351-import-export-in-cli

Conversation

@fredrikekelund
Copy link
Copy Markdown
Contributor

@fredrikekelund fredrikekelund commented Apr 2, 2026

Related issues

How AI was used in this PR

Primarily to review my implementation and help me preemptively fix several issues.

Proposed Changes

Tip

I'm happy to pair review this PR.

This one's a biggie. It adds site import and site export CLI commands. I've copied the core import/export logic from apps/studio and adapted it to CLI conditions (the types are slightly different, we call WP-CLI in different ways, etc).

Moreover, this PR finalizes the sync pull and sync push commands by wiring up the import/export logic there, too.

Testing Instructions

  1. npm run cli:build
  2. Try the node apps/cli/dist/cli/main.mjs site export command. Explore the flags and try different combinations.
  3. Try the node apps/cli/dist/cli/main.mjs site import command. Explore the flags and try different combinations.
  4. Try the node apps/cli/dist/cli/main.mjs sync pull command.
  5. Try the node apps/cli/dist/cli/main.mjs sync push command.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@fredrikekelund fredrikekelund requested review from a team and bcotrim April 2, 2026 13:37
@fredrikekelund fredrikekelund self-assigned this Apr 2, 2026
@fredrikekelund fredrikekelund changed the title Stu 1351 import export in cli Implement import/export in CLI Apr 2, 2026
@fredrikekelund fredrikekelund force-pushed the stu-1351-import-export-in-cli branch from f26f025 to 9ab29a1 Compare April 2, 2026 13:58
Comment on lines -121 to -124
// We configure `trash` as an external module, since it includes a native macOS binary that Vite
// inlines as a base64 string, which produces a runtime error. Since `trash` is also an ESM-only
// module, we need to import it dynamically (since Rollup doesn't get a chance to process it)
const trash = ( await import( 'trash' ) ).default;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to the core changes in this PR, but we output ESM now, and trash is always configured as an external module when Vite bundles, so this is no longer an issue.

break;

case ExportEvents.BACKUP_CREATE_PROGRESS: {
const progressData = data as BackupCreateProgressEventData;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to avoid type assertions for the event payloads, but since this copies the logic we already have in the app, I decided to stick with that for now.

Comment on lines +90 to +95
logger.reportStart(
LoggerAction.INSTALL_SQLITE,
__( 'Setting up SQLite integration, if needed…' )
);
await keepSqliteIntegrationUpdated( siteFolder );
logger.reportSuccess( __( 'SQLite integration configured as needed' ) );
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's important to keep the SQLite integration up to date whenever we work with the site database. Exporting the site is one such example.

const zipUrl = getWordPressVersionUrl( wp );

const [ response, exitPhp ] = await runWpCliCommand( sitePath, phpVersion, [
await using command = await runWpCliCommand( sitePath, phpVersion, [
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're not familiar with the using keyword, I recommend a quick read-up on JavaScript resource management. Playground already uses this internally.

In short, it saves us from having to call a cleanup function (exitPhp) because the JS runtime automatically calls the method identified by Symbol.dispose when exiting the scope. Very nifty.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment in apps/cli/commands/site/set.ts about JavaScript resource management to understand what's going on here.

Comment on lines -30 to +39
"@php-wasm/node": "3.1.15",
"@php-wasm/universal": "3.1.15",
"@php-wasm/util": "3.1.15",
"@php-wasm/node": "3.1.13",
"@php-wasm/universal": "3.1.13",
"@php-wasm/util": "3.1.13",
"@vscode/sudo-prompt": "^9.3.2",
"@wordpress/i18n": "^6.14.0",
"@wp-playground/blueprints": "3.1.15",
"@wp-playground/cli": "3.1.15",
"@wp-playground/common": "3.1.15",
"@wp-playground/storage": "3.1.15",
"@wp-playground/wordpress": "3.1.15",
"@wp-playground/blueprints": "3.1.13",
"@wp-playground/cli": "3.1.13",
"@wp-playground/common": "3.1.13",
"@wp-playground/storage": "3.1.13",
"@wp-playground/wordpress": "3.1.13",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to downgrade these packages because I couldn't get WP-CLI to play ball. See p1775051878031829-slack-C04GESRBWKW

@fredrikekelund fredrikekelund marked this pull request as ready for review April 2, 2026 14:52
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