[Add] a per-site project type driving clone, status and build (#251) - #255
[Add] a per-site project type driving clone, status and build (#251)#255juanmaguitar wants to merge 2 commits into
Conversation
b571e5d to
716def9
Compare
1c66b4e to
747ac9b
Compare
The toolkit assumed every site was a wordpress-develop checkout — the repo it clones, how it decides a site is "built", and the run/build commands were all hard-wired to WordPress Core. A contributor who wants to work on the block editor (Gutenberg) had no path in, even though the shape of the work is nearly identical. Give each site a project type, chosen once at creation, and let that single choice drive the parts of the flow that differ. This PR covers clone, status and run/build; serving Gutenberg in a real WordPress and the GitHub-issue work item / pull-request flow follow in later PRs. - src/project-type.cjs: one registry describing each target (Core, Gutenberg) — clone URL/branch, PR upstream, built-check path, dev/build scripts, allowed terminal scripts, plus the serve strategy, patch layout and work-item provider the later PRs will read. getProjectType / projectTypeForSite default to Core for any unknown or missing id, so sites created before this field existed need no migration and the Core path is byte-identical. - wordpress:setup resolves the type once and uses it for both the clone and the siteMeta it writes, so the two cannot disagree; site:status returns it. - site:status answers "is it built?" from the type's marker path (Core's wp-includes dist dir vs Gutenberg's build/block-library). - git:update-trunk pulls from the site's own upstream, not always wordpress-develop — updating a Gutenberg checkout from Core's trunk would overwrite it with a different project. - The create-site wizard gains a "Contribute to" choice (default Core), and the dev-server plan and terminal allow-list come from the chosen type. The sidebar button, modal and docs are retitled from "WordPress Core site" to the type-neutral "contributor site"; the create-site and empty-state screenshots are regenerated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
747ac9b to
7182234
Compare
## Why `v1.0.0-beta.1` shipped on 10 August. Twenty changes have landed on `trunk` since — the setup chain, the decoupled build watch, the failed-apply explanation, the ticket's own facts, the toasts. That is the release candidate for 1.0, so the version moves to `1.0.0-rc.1` before the tag is cut. ## What changes `package.json` and `package-lock.json`, and nothing else. Written by `npm version 1.0.0-rc.1 --no-git-tag-version` rather than by hand, so the lockfile's two copies of the string move with it. `git grep 1.0.0-beta` outside the lockfile returns nothing, so no doc, workflow or script carries the version. `electron-builder` derives the artefact names from `package.json`, so the assets become: - `wordpress-contributor-toolkit-1.0.0-rc.1-mac-arm64.dmg` - `wordpress-contributor-toolkit-1.0.0-rc.1-win-x64.exe` - `wordpress-contributor-toolkit-1.0.0-rc.1-linux-x86_64.AppImage` The `rc.1` shape (not `rc1`) keeps the same form as `beta.1`, so the filenames stay in one series. ## Scope The open Gutenberg stack (#255 → #261 → #264 → #269 → #283) is deliberately **not** in this release candidate. An RC stabilises what is there; a feature of that size belongs in the release after it. ## Review No behaviour changes, so the review standard has nothing to grade beyond the diff itself: two version strings, produced by npm, verified against `git grep`. Lint and unit tests run on this branch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cherry-picked from a0fcbc9 onto this stack so no signing build on these branches writes the rotated App Store Connect key back into the package. Buildkite stays archived until every open branch carries it. This branch predates the e2e suite and the test/ -> tests/ move, so the packaged smoke canary and its workflow hook are left out; the unit test comes along and keeps its tests/unit/ path, which is what it resolves the script from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Heads-up on the extra commit here: 53ea586 cherry-picks #390 ( Buildkite is archived right now so that no signing build runs pre-#390 code and writes the rotated App Store Connect key back into the package. Getting the fix onto every open branch is what lets the pipeline be un-archived, so it went in as a cherry-pick rather than waiting for this stack to catch up with trunk — that catch-up is still owed (50 commits, including the Two pieces of #390 were left out because this branch predates the infrastructure they hook into: the packaged smoke canary ( |
|
Closing this stack rather than rebasing it. The branch point is The branch is not deleted, so nothing here is lost. What ports forward intact when this is redone is the new modules and their tests, none of which conflict with anything: #283 stays open — it only needs its own |
Why
The toolkit assumes every site is a
wordpress-developcheckout — the repo it clones, how itdecides a site is "built", and the run/build commands are all hard-wired to WordPress Core. A
contributor who wants to work on the block editor (Gutenberg) has no path in, even though the shape
of the work is nearly identical. Part of #251.
What changes
Each site gets a project type, chosen once at creation, and that single choice drives the parts
of the flow that differ. This PR covers setup/clone, built-status, and run/build; serving
Gutenberg in a real WordPress (PR next) and the GitHub-issue work-item / pull-request flow (PR after)
follow.
src/project-type.cjs— one registry describing each target (Core, Gutenberg): cloneURL/branch, PR upstream, built-check marker path, dev/build scripts, allowed terminal scripts —
plus the serve strategy, patch layout and work-item provider the later PRs will read.
getProjectType/projectTypeForSitedefault to Core for any unknown or missing id, so sitescreated before this field existed need no migration and the Core path stays byte-identical.
wordpress:setupresolves the type once and uses it for both the clone and thesiteMetaitwrites, so the two cannot disagree;
site:statusreturns it.build/wp-includes/js/distvs Gutenberg'sbuild/block-library.git:update-trunkpulls from the site's own upstream — updating a Gutenberg checkout fromCore's trunk would overwrite it with a different project.
npm run devvs Core's
grunt -- _watch) and the terminal allow-list come from the chosen type. The sidebarbutton, modal and docs are retitled to the type-neutral "contributor site"; the create-site and
empty-state screenshots are regenerated.
Deliberately not here: no Gutenberg serve yet (a Gutenberg site can clone/install/build but its
Playground preview comes in the next PR), and the work item is still Trac-only (GitHub issues land
with the PR flow).
How to test this
Platforms: any — no path/spawn/line-ending behavior changes; the marker path is composed with
path.join.Starting state: the app open on the site list.
Contribute to choice, WordPress Core (Trac tickets) selected.
wordpress-develop; install, build, anddev server behave exactly as before.
WordPress/gutenberg; afternpm run buildthe checklist reports it built (markerbuild/block-library); the terminal'snpm run <script>list is Gutenberg's; starting the dev server runsnpm run dev(not Grunt).WordPress/gutenberg, notwordpress-develop.What must not have happened:
projectTypereads as Core everywhere, withno store rewrite on status read.
build/wp-includes/js/distexists — the marker is its own (
test/ipc-wiring.test.cjspins this negative case).grunt -- _watch.Automated:
npm run lintclean;npm test— 797 pass, 0 fail. New/extended coverage intest/project-type.test.cjs,test/dev-server-command.test.cjs(Gutenbergnpm run devbranch),and
test/ipc-wiring.test.cjs(clone URL, built marker incl. the negative, and update-trunk URL pertype; setup persistence + normalization).
Risks and limitations
src/framing (e.g. "Edited files insrc/? Run npm runbuild"); a Gutenberg-aware copy pass rides with the later, user-facing PRs.
Related
Part of #251.
Design decisions and alternatives considered
if (type === …). The Core assumptions were spread across clone,status,
dev-server-command.cjs, and the trunk-update URL. Consolidating them intosrc/project-type.cjsturns each hard-wired constant into a lookup whose Core value reproducestoday's behavior, so the Core diffs read as pure refactors.
siteMetarecords simply lack the field;projectTypeForSite(undefined)yields Core. Nothing is rewritten on disk.into an inert spine + a follow-up; combining them means the wizard never exposes a choice the app
ignores, which removed a self-review finding entirely. Still under the size guideline (~490 lines).
git:update-trunkhad to become type-aware here, not later — a Gutenberg site updating fromCore's trunk is a data-loss bug, so it could not wait for a serve/PR PR.
Review outcome (required — see AGENTS.md)
1 [fix here] · 0 [follow-up]. Ran the review in
.github/instructions/code-review.instructions.mdagainst the branch; judgement pass dispatched toa fresh subagent.
npm run lintclean, 797 tests pass.facts (
serve.strategy,patch.layout,pr.*/workItem) are not yet consumed, so a Gutenbergsite can clone/build but not be served or produce a valid patch/PR. Resolved by merge strategy,
not by code: this PR and the serve + work-item/PR follow-ups merge together (see the banner in
Risks), so the option never reaches a user in the broken state. Deliberately kept the choice live
rather than gating it, because the stack lands atomically.
site:statusmarker/meta ordering, renderer memoization stability, IPC validation, cross-platformpath composition, or test quality (the per-type tests, including the negative built-marker case,
go red if a consumer stops honoring the type).
Screenshots or recording
The create-site modal now offers a Contribute to choice (WordPress Core / Gutenberg), Core
preselected, and the sidebar button + modal are retitled. Regenerated docs screenshots:
docs/public/screenshots/create-site-modal.pngandempty-state.png.