[Add] Apply Gutenberg pull requests to a Gutenberg site (#251) - #264
Open
juanmaguitar wants to merge 1 commit into
Open
Conversation
juanmaguitar
force-pushed
the
juanmaguitar/gutenberg-work-item-and-pr-flow
branch
from
August 11, 2026 10:57
941aada to
c00c47f
Compare
With a Gutenberg site now cloning, building and serving, the remaining half of "see what a Gutenberg PR does" is reading the PR and applying it. Both were hard-wired to WordPress Core: - Patch paths were always rewritten into wordpress-develop's src/ layout. That rewrite exists because a patch attached to a Trac ticket years ago still names `wp-admin/…`, but a Gutenberg diff is already repo-relative, and a top-level `wp-`-prefixed path in one would be moved under a `src/` directory Gutenberg does not have. parsePatchFiles now takes a `layout`, applyPatchToDir passes it through, and preview, apply and revert all resolve it from the site so they cannot disagree about where a file lives. - Pull requests were always read from WordPress/wordpress-develop. parsePrRef, fetchLinkedPrs and fetchPrDiff now take the site's upstream, so a Gutenberg site lists and fetches WordPress/gutenberg pull requests — and still refuses a PR from the other project, whose diff would not fit its checkout. - "Which PRs belong to this work item" is a different question per provider: a Core PR cites a Trac URL, a Gutenberg PR cites its issue as `#1234`. Added bodyCitesIssue and citesWorkItemFor; the verification stays narrow (`#658` must not match inside `#6580`, and a bare number is not a citation). The linked-PR cache key now includes the repository: Trac ticket #123 and Gutenberg issue #123 are different work items and shared one entry before. Every new parameter defaults to Core's behaviour, so a site with no project type is unchanged and needs no migration. Verified by hand that a `packages/…` diff applies to a Gutenberg-shaped tree under repo-relative, and that the same patch fails under Core's layout — which is the bug this prevents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
juanmaguitar
force-pushed
the
juanmaguitar/gutenberg-work-item-and-pr-flow
branch
from
August 11, 2026 13:49
c00c47f to
3e9c54c
Compare
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.
Why
Part of #251. With a Gutenberg site now cloning, building and serving (#255, #261), the remaining
half of "see what a Gutenberg pull request actually does" is reading that PR and applying it to
the checkout. Both were hard-wired to WordPress Core, in ways that fail silently rather than
loudly on a Gutenberg site.
What changes
src/layout — a rewrite that exists because a patch attached to a Trac ticket years ago stillnames
wp-admin/…. A Gutenberg diff is already repo-relative (packages/…), and a top-levelwp--prefixed path in one would be moved under asrc/directory Gutenberg does not have.parsePatchFilestakes alayout,applyPatchToDirpasses it through, and preview, apply andrevert all resolve it from the site so they cannot disagree about where a file lives.
parsePrRef,fetchLinkedPrsandfetchPrDifftake the repository, so a Gutenberg site lists and fetchesWordPress/gutenbergPRs — and still refuses one from the other project, whose diff would not fit its checkout.
PR cites its issue as
#1234. AddedbodyCitesIssue/citesWorkItemFor, keeping theverification narrow —
#658must not match inside#6580, and a bare number is not a citation.are different work items and shared one entry before.
Every new parameter defaults to Core's behaviour, so a site with no project type is unchanged.
Deliberately not here: the work-item side is still Trac-only (entering a GitHub issue, the
ticket panel copy, the Trac attachments panel) and outbound PR authoring still targets
wordpress-develop. Those are the next PR.
How to test this
Platforms: any.
The mechanism, without a full Gutenberg build — this is the failure the change prevents:
(I ran exactly this, plus a
packages/block-library/src/index.jsdiff applying cleanly to aGutenberg-shaped tree.)
Full flow (a real Gutenberg site, from #255/#261):
https://github.com/WordPress/gutenberg/pull/<n>URL into"apply a PR". → It is accepted, the diff is fetched from
WordPress/gutenberg, and the previewlists
packages/…paths unchanged (nosrc/prefix).wordpress-developPR URL into the same box on that Gutenberg site. → Refused by name.On a Core site (must be unchanged): link a Trac ticket, list its linked PRs, apply one, revert.
Identical to before — same
src/rewrite, same wordpress-develop source.What must not have happened:
src/-rewritten — that writes to paths the contributor wasnever shown, and the preview would disagree with the apply.
wp-admin/…patch still has to land insrc/).Automated:
npm run lintclean; 822 tests pass. New coverage intest/patch-plan.test.cjs(both layouts, incl.
packages/untouched either way and unknown-layout → Core),test/patch-sources.test.cjs(bodyCitesIssueprecision,citesWorkItemFor, per-repoparsePrRef),test/github-prs.test.cjs(repo/provideractually reach the query), andtest/ipc-wiring.test.cjs(preview and apply and revert all pin their layout, per type).Risks and limitations
bodyCitesIssueis looser than its Trac counterpart.bodyCitesTicketrequires a host and/ticket/, so a stray number cannot pass. GitHub's convention has no such anchor, soFollow-up to #1234(a PR number) orotherorg/repo#1234also count as a citation. The blastradius is a false entry in the linked-PR list, which a contributor would then have to click.
Tightening it (requiring a closing keyword, rejecting an
owner/repo#idprefix) is a design callworth its own pass — flagged rather than guessed at here.
ticketPatches:<id>keys are inert after thekey change; nothing reads them. The visible effect is one-time: the first offline/rate-limited
lookup after upgrading has no stale list to fall back on. A one-line sweep could prune them.
Trac attachments"). That is the next PR's scope, and it is the one remaining path that could hand
a Gutenberg site a Core patch — worth knowing while the stack is in flight.
Related
Part of #251. Stacked on #261.
Review outcome (required — see AGENTS.md)
1 [fix here] · 3 [follow-up] — the fix-here is fixed. Ran the review in
.github/instructions/code-review.instructions.md; judgement pass in a fresh subagent. Lint clean,822 tests pass.
layoutbut the apply side didnot, so deleting
layoutfrom eitherapplyPatchToDircall would have shipped green while aGutenberg diff went through Core's rewrite. Added layout assertions to the forward-apply and
revert wiring tests plus a Gutenberg apply case. Also closed the related gap the reviewer noted in
passing:
fetchPrDiffis now injectable andtest/github-prs.test.cjsassertsrepo/providerreach the request and the citation test (previously a typo there shipped green, since the
IPC-wiring tests stub the module out).
bodyCitesIssueprecision (documented in Risks). The escape anddigit-stripping were verified correct; no injection or ReDoS.
deferred to the next PR in the stack (documented in Risks).
parsePatchFiles()across every branch (rename, binary,normal,
/dev/null) with an unknown/undefined layout still taking the Core rewrite; preview/applycannot disagree (
projectTypeis immutable afterwordpress:setup); the changedfetchPrDiffIPC signature has no missed call sites;
repois always a registry constant, never rendererinput.