Push MD: reliable fresh-site seeding (resolve by slug) + export path-collision hardening#66
Draft
robertsreberski wants to merge 4 commits into
Draft
Push MD: reliable fresh-site seeding (resolve by slug) + export path-collision hardening#66robertsreberski wants to merge 4 commits into
robertsreberski wants to merge 4 commits into
Conversation
When two WordPress entities map to the same Push MD file path, fail the export instead of papering over it with synthetic --wp-<id> filenames. The fail-closed behavior is surfaced to both consumers: - Agents cloning/fetching get an actionable Git error naming the conflicting post IDs (or, before the initial import finishes, the seeder failure message via not_ready_message()). - Site admins see a "Path collisions" panel on Tools -> Push MD listing the conflicting posts with edit links and how to resolve them. Details: - export_wordpress_content() throw now names both post IDs plus a fix hint; add detect_export_path_collisions() as the shared detection helper used by the seeder and admin surfaces. - Seeder initialize() detects collisions and fails loudly through the existing record_failure() path instead of silently overwriting the losing post during the initial import. - Admin status route and page render a live-refreshing collision panel (briefly cached detection, JS renderCollisions(), warning styling). - Tests cover the actionable throw and detection (group, unique-path, unbuildable-path skip); readme FAQ + version bumped to 0.6.6.
… parsing
- allow_create_on_missing_id (option/filter, default off): when set, an unknown
front-matter id resolves by slug (update-or-create) instead of rejecting, and
missing parent pages are tolerated with ancestor pages applied before children.
Production keeps rejecting unknown ids (guard intact).
- seed_markdown_file(): public wrapper over upsert_post_from_markdown so non-git
transports (e.g. a WordPress Playground runPHP step) can seed a single file.
- Fix parse_frontmatter_scalar: anchor the YAML sequence/mapping detection regex
so quoted titles/descriptions containing "{" or "- " are not mis-parsed as
empty arrays.
When push_md_allow_create_on_missing_id is enabled (local one-way seeding onto a fresh site), resolve posts and pages purely by slug/path and ignore the Markdown front-matter id. Production ids in the seed content can collide with unrelated local auto-increment post ids; previously such a collision hard- rejected the whole (atomic) push with "references a different WordPress post type", "multiple Markdown files reference the same WordPress post ID", or the path/id conflict error. Gate the two id-resolver branches in find_post_id_by_path_metadata() on ! allow_create_on_missing_id(). Production pushes leave the option off and keep strict id-based resolution unchanged. Bump to 0.6.7; add four e2e regression tests plus a CI-only REST toggle for the option.
robertsreberski
force-pushed
the
push-md-duplicate-path-hardening
branch
from
June 18, 2026 16:18
e1c832e to
ce38fe9
Compare
robertsreberski
marked this pull request as draft
June 18, 2026 16:23
Author
|
Heads-up after rebasing onto trunk: this branch's scoped build currently fatals on push-md's Markdown import (seeding). Trunk's The resolve-by-slug change in this PR is independent and ready; the scoped build just can't import Markdown until #68 is fixed. jetpack-com is pinned to the pre-scoping build as an interim. |
…th-hardening # Conflicts: # plugins/push-md/class-push-md-admin.php
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.
Summary
Makes Push MD reliable when seeding production content onto a fresh WordPress site (the
push_md_allow_create_on_missing_idflow used by local Studio setup), and hardens export path-collision handling. This branch is a small stack:34daeddc) — when multiple WordPress items map to the same Markdown file path, fail the export with a clear Git error and report the collisions on Tools → Push MD.c92c6b65) —push_md_allow_create_on_missing_idlets a push create posts whose front-matter id doesn't exist locally (plus a front-matter scalar parsing fix).e1c832e4) — the fix below.The seeding bug this fixes
Push MD treats the Markdown front-matter
idas the local WordPress post ID (get_post($frontmatter_id)), which is correct for round-trip on one site but wrong when seeding production content onto a fresh site: those production IDs don't exist locally, so created posts get fresh sequential auto-increment IDs.push_md_allow_create_on_missing_idonly rescued the missing-id case. When a production front-matter ID happened to collide with an unrelated local post's auto-ID, the (atomic) push was hard-rejected:One collision blocked the entire push (e.g. ~1,224 objects for jetpack.com).
Change
In
find_post_id_by_path_metadata(), gate the two id-resolver branches on! self::allow_create_on_missing_id(). When the option is on, resolution falls through to the existing slug/path resolvers and the front-matter id is ignored entirely, so the type/duplicate/path-conflict rejects can't fire. Production pushes leave the option off and keep strict id-based resolution unchanged. Bumped to0.6.7.Test plan
Tests/EndToEndTest.php(run by.github/workflows/push-md-e2e.yml):push_md_allow_create_on_missing_idadded toTests/ci-mu-test-helper.php(the test process has no wp-cli).phpcsclean; the Push MD suite is green locally (E2E skips withoutPUSH_MD_E2E_*).