[Blueprints] Export and import all site files except Playground runtime files - #4141
Merged
Merged
Conversation
This was referenced Jul 21, 2026
adamziel
added a commit
that referenced
this pull request
Jul 21, 2026
Playground ZIP exports now contain every file under `wp-content`, plus `wp-config.php`. The manifest records `formatVersion: 2` so the importer work in #4130 can distinguish these archives from pre-versioned partial exports. This removes the `selfContained` option from the public `zipWpContent()` API. Every caller now receives a complete archive. ## Testing Export a Playground with a custom file inside a default theme. Inspect the ZIP and confirm it contains that file, `wp-config.php`, and a `playground-export.json` manifest with `formatVersion: 2`. ## Stack 1. [#4139 — Export complete versioned Playground ZIP snapshots](#4139) 2. [#4141 — Separate runtime-managed paths from legacy ZIP omissions](#4141) 3. [#4130 — Import versioned ZIP content while retaining legacy defaults](#4130) 4. [#4131 — Import ZIP contents before initial browser persistence](#4131) 5. [#4132 — Keep ZIP preparation visible until the imported site is ready](#4132) 6. [#4121 — Accept ZIP drops across the page](#4121)
Base automatically changed from
adamziel/complete-versioned-zip-exports
to
trunk
July 21, 2026 10:59
adamziel
force-pushed
the
adamziel/separate-runtime-wp-content-paths
branch
3 times, most recently
from
July 21, 2026 12:20
4b71fa1 to
4235938
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR separates legacy ZIP export omissions from runtime-managed wp-content artifacts so that GitHub exports/imports only exclude/override Playground-managed paths while ZIP importer compatibility remains supported for older archives.
Changes:
- Replace the old public exclusion list with runtime-path detection (
getLegacyPlaygroundRuntimeWpContentPaths) for GitHub export/import and ZIP snapshot creation. - Introduce a legacy omission list for pre-v2 ZIP compatibility (
legacyUserWpContentPathsExcludedFromExport) and apply it during ZIP imports. - Regenerate blueprint schema artifacts and adjust relevant tests/mocks.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/playground/website/src/github/import-from-github.ts | Updates GitHub import to preserve current runtime-managed paths and remove legacy runtime artifacts from imported content. |
| packages/playground/website/src/github/github-export-form/form.tsx | Updates GitHub export to dynamically exclude only runtime-managed wp-content paths. |
| packages/playground/website/src/github/github-export-form/form.spec.tsx | Updates mocks to reflect the new runtime-path API. |
| packages/playground/blueprints/src/tests/steps/import-wordpress-files.spec.ts | Adds coverage for omitting legacy runtime artifacts and preserving custom db.php, plus precedence rules on import. |
| packages/playground/blueprints/src/lib/utils/wp-content-files-excluded-from-exports.ts | Removes the old combined exclusion list. |
| packages/playground/blueprints/src/lib/utils/legacy-wp-content-paths-excluded-from-exports.ts | Adds legacy omission list for restoring paths missing from old ZIP archives. |
| packages/playground/blueprints/src/lib/utils/legacy-playground-runtime-wp-content-paths.ts | Adds detection of legacy runtime artifacts (including marker-based db.php). |
| packages/playground/blueprints/src/lib/steps/zip-wp-content.ts | Excludes legacy runtime-managed artifacts when generating ZIP snapshots. |
| packages/playground/blueprints/src/lib/steps/index.ts | Removes re-export of the old exclusion list and minor type formatting update. |
| packages/playground/blueprints/src/lib/steps/import-wordpress-files.ts | Updates ZIP import logic to drop archived runtime artifacts and retain runtime/current legacy user paths. |
| packages/playground/blueprints/src/index.ts | Updates public exports to expose the new runtime-path helper instead of the old exclusion list. |
| packages/playground/blueprints/public/blueprint-v2-schema-validator.js | Regenerated schema validator output. |
| packages/playground/blueprints/public/blueprint-schema.json | Regenerated schema JSON output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
adamziel
force-pushed
the
adamziel/separate-runtime-wp-content-paths
branch
from
July 21, 2026 12:28
4235938 to
f1277cf
Compare
adamziel
force-pushed
the
adamziel/separate-runtime-wp-content-paths
branch
from
July 21, 2026 12:50
8c47bf3 to
274fb50
Compare
adamziel
added a commit
that referenced
this pull request
Jul 21, 2026
… defaults (#4130) A version-2 Playground ZIP now defines user-owned `wp-content`: archived files replace the boot defaults, and a missing user file means it was deleted. Legacy runtime artifacts remain owned by the importing Playground through #4141. Pre-versioned exports remain partial. When one omits a stock plugin, theme, or database directory, import retains the fresh installation's copy. An archived copy still wins when present. This preserves customized default themes such as BrewCommerce's purple Twenty Twenty-Five background through export, import, and reload without treating stock themes as runtime files. ## Testing Browser coverage imports a pre-versioned partial export, then separately customizes Twenty Twenty-Five, exports it, imports it into a new Playground, reloads, and checks both the theme file and rendered background. The full stack passes 488 Blueprint tests, 347 website tests, both packages' lint and typecheck, and 10 Chromium ZIP-import scenarios. ## Stack 1. [#4139 — Export complete versioned Playground ZIP snapshots](#4139) 2. [#4141 — Exclude legacy runtime artifacts from site snapshots](#4141) 3. [#4130 — Import versioned ZIP user content while retaining legacy defaults](#4130) 4. [#4131 — Import ZIP contents before initial browser persistence](#4131) 5. [#4132 — Keep ZIP preparation visible until the imported site is ready](#4132) 6. [#4121 — Accept ZIP drops across the page](#4121)
… defaults (#4130) A version-2 Playground ZIP now defines user-owned `wp-content`: archived files replace the boot defaults, and a missing user file means it was deleted. Legacy runtime artifacts remain owned by the importing Playground through #4141. Pre-versioned exports remain partial. When one omits a stock plugin, theme, or database directory, import retains the fresh installation's copy. An archived copy still wins when present. This preserves customized default themes such as BrewCommerce's purple Twenty Twenty-Five background through export, import, and reload without treating stock themes as runtime files. ## Testing Browser coverage imports a pre-versioned partial export, then separately customizes Twenty Twenty-Five, exports it, imports it into a new Playground, reloads, and checks both the theme file and rendered background. The full stack passes 488 Blueprint tests, 347 website tests, both packages' lint and typecheck, and 10 Chromium ZIP-import scenarios. ## Stack 1. [#4139 — Export complete versioned Playground ZIP snapshots](#4139) 2. [#4141 — Exclude legacy runtime artifacts from site snapshots](#4141) 3. [#4130 — Import versioned ZIP user content while retaining legacy defaults](#4130) 4. [#4131 — Import ZIP contents before initial browser persistence](#4131) 5. [#4132 — Keep ZIP preparation visible until the imported site is ready](#4132) 6. [#4121 — Accept ZIP drops across the page](#4121)
adamziel
force-pushed
the
adamziel/separate-runtime-wp-content-paths
branch
from
July 21, 2026 19:13
04e635b to
aad47fb
Compare
adamziel
added a commit
that referenced
this pull request
Jul 21, 2026
ZIP imports used to persist a fresh WordPress installation before applying the archive. The archive then rewrote that stored filesystem: 1. Boot fresh WordPress in MEMFS. 2. Copy the fresh site to browser storage. 3. Apply the ZIP to the running site. 4. Flush the rewritten site to browser storage again. This PR applies the ZIP during the new site's first boot, before its initial browser-storage copy: 1. Boot fresh WordPress in MEMFS. 2. Apply the ZIP in MEMFS. 3. Copy the finished filesystem to browser storage once. `createNewSiteFromZip()` registers the import as first-boot work. The boot path runs that work before the initial MEMFS-to-OPFS copy, and the call reports success only after that copy finishes. If ZIP initialization or the first OPFS copy fails, the newly created stored site is removed and the previously active Playground is selected again. When OPFS is unavailable, the import uses a fresh temporary Playground. Its new slug forces React to boot a new iframe instead of reusing the previous runtime. The ZIP picker now delegates this lifecycle to `createNewSiteFromZip()` instead of coordinating site creation, client boot, import, and persistence through component effects. This PR does not change which files a ZIP contains or how versioned and legacy ZIP contents are interpreted. Those rules are handled by #4141 and #4130. This PR changes when the imported filesystem is written to browser storage. ## Testing 1. Import a ZIP from both temporary and saved Playgrounds and confirm the new site persists after reload. 2. Import a malformed ZIP and confirm no incomplete stored site remains. 3. Confirm the previously active Playground remains selected after a failed stored-site import. Unit coverage checks that ZIP initialization runs before the initial OPFS copy and that failed-import cleanup selects the requested previous site once. Browser coverage checks that a failed import leaves the stored-site list unchanged, including after reload. ## Stack 1. [#4139 — Export complete versioned Playground ZIP snapshots](#4139) — merged 2. [#4141 — Export and import all site files except Playground runtime files](#4141) — merged 3. [#4130 — Import versioned ZIP user content while retaining legacy defaults](#4130) — merged 4. [#4131 — Import ZIP contents before initial browser persistence](#4131) 5. [#4132 — Keep ZIP preparation visible until the imported site is ready](#4132) 6. [#4121 — Accept ZIP drops across the page](#4121)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make new ZIP exports preserve the site’s plugins, themes, uploads, and database exactly. Make imports remove any pre-bundled Playground's runtime files (such as
0-playground.phpmu-plugin) and lean on their latest versions shipped in the/internaldirectory.Backwards compatibility
Playground's ZIP export format evolved over time. Here's how each version is handled after this PR:
wp-contentthemes/twenty*directories were included only by the self-contained export.database/may be absent.database/. This is a best-effort heuristic. We can't distinguish a deleted theme from a missing theme.formatVersion: 2after this PRdatabase/, and a customdb.phpif the user specifically created one.On every import, archived Playground files are removed. The new Playground supplies them.
Playground runtime files
These four old paths are always treated as Playground-provided runtime files:
mu-plugins/sqlite-database-integrationmu-plugins/playground-includesmu-plugins/0-playground.phpmu-plugins/0-sqlite.phpFrom January 29 through May 8, 2024, the self-contained exporter included
mu-plugins/sqlite-database-integration. It also includedmu-plugins/0-sqlite.phpwhen present. It already omittedmu-plugins/0-playground.phpandmu-plugins/playground-includes; those entries handle stale sites, GitHub trees, and hand-built ZIPs.db.phpneeds a separate rule because it can be a custom WordPress drop-in. During legacy WordPress boot,writeLegacyDbPhp()creates Playground's copy throughgenerateDbPhpContent(). That function writes@playground-managedinto the file header. Only adb.phpwith that marker is treated as a Playground file. An unmarkeddb.phpstays with the site.Before January 29, 2024, SQLite used
plugins/sqlite-database-integration. This PR leaves that path as site content because it is also a valid user-installed plugin path.Breaking change:
wpContentFilesExcludedFromExportis no longer public.getLegacyPlaygroundRuntimeWpContentPaths()exposes the smaller runtime rule.Testing
Tests cover a modified Twenty Twenty-Five theme, a deleted v2 theme, a theme omitted by a pre-v2 ZIP, archived runtime files, marked and custom
db.phpfiles, failed runtime staging, and archives withoutwp-content. The full stack passes 488 Blueprint tests, 347 website tests, package lint and typecheck, and 10 Chromium ZIP-import scenarios.Stack