Skip to content

v13.32.0-beta.7

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 24 Sep 13:33
· 223 commits to main since this release

Fixed

  • pollora:make:block refuses a theme or plugin that cannot build a block, and says why. A plugin made without assets has neither package.json nor vite.config.js: the block was written anyway, could not be built, and the npm install the command advised walked up to the site's own package.json and installed there. It now stops before writing anything and names the missing files
  • pollora:make:plugin --asset includes the asset files. The option takes a value, so the bare flag read as null, which the defaults applied without a terminal turned into false: --asset alone left the assets out. --asset=false still leaves them out, and the other options keep their defaults
  • A block title holding a quote (--title="Owner's Hero") no longer breaks the JavaScript pollora:make:block writes. render.blade.php escaped it; edit.jsx and save.jsx printed it raw inside a single-quoted string, so the block failed to build
  • A block's editor script depends on every WordPress script its code imports. BlockRegistrar gave each editor script a fixed list — wp-blocks, wp-element, wp-block-editor, wp-i18n — while @roots/vite-plugin turns every @wordpress/* import into a global and records the matching handles in editor.deps.json. A block importing @wordpress/components or @wordpress/server-side-render worked only when something else happened to load that script. The handles in the build's editor.deps.json are now added to the defaults; in dev mode, which has no build, the defaults stand
  • Blocks shipped by themes, plugins and modules exist in the block editor, on the page and in the REST API. They were registered by a BlocksServiceProvider of the module's own, and over HTTP no shape of that provider works: WordPress is loaded, and init has fired, before theme and plugin providers boot, so the provider pollora:make:block wrote — hooking init from boot() — was never called, and a REST request is answered before those providers boot at all. Blocks existed in WP-CLI only, which is where they had been checked. Measured on a fresh install: theme-default's hero and call-to-action were missing from the editor and from /wp/v2/block-types. The framework now registers every module's resources/views/blocks (and the former resources/blocks) itself on init, from a hook set while it boots — before WordPress loads — and creates the asset container of a Laravel module that ships blocks. pollora:make:block no longer writes a provider. A BlocksServiceProvider kept from an earlier release is harmless: a block WordPress already holds is skipped. Covered by browser tests that insert each block in the editor, reload it, and find it on the published page
  • Themes and plugins keep working on a site whose autoloader was dumped with --classmap-authoritative. Their namespaces (Theme\…, Plugin\…) were added at runtime to Composer's root loader, and an authoritative loader answers from its classmap alone: it never looked at them, so every front-end page answered 404 (Class "Theme\Apiary\Walkers\MenuPrimary" not found) while wp-login.php still worked. Module namespaces now live in a class loader of their own, registered after Composer's, and shared by the theme and plugin autoloaders under the ModuleAutoloader::CLASS_LOADER container key. It has no vendor directory, so it stays out of ClassLoader::getRegisteredLoaders() and cannot move Application::inferBasePath(). Measured on a live site in both modes: pages, the PHPUnit and HTTP suites, and the theme sweep all pass. The root loader is no longer bound to Composer\Autoload\ClassLoader in the container as a side effect
  • php artisan test, and anything else that asks Laravel for its base path, no longer resolves it to a plugin's directory. ModuleAutoloader::register() registered the root Composer loader again although it was already active, and Composer answers that by moving it to the end of ClassLoader::getRegisteredLoaders() — behind the loader of any plugin shipping its own vendor/, such as Query Monitor. Application::inferBasePath() reads the first entry of that list, so on such a site 38 of 40 of its PHPUnit tests failed opening plugins/query-monitor/bootstrap/app.php. Composer's InstalledVersions::getRootPackage() read the same list and reported the plugin as the root package, over HTTP, in artisan and in WP-CLI. Namespaces added with addPsr4() take effect on an active loader, so the loader is now only registered when it is not already. The bug dates back to June 2025 and shipped in v13.4.4
  • patches/mockery-php84-nullable.patch is back on main, byte for byte as v13.4.4 shipped it. The v13.4.x line declares that patch by the URL refs/heads/main/patches/mockery-php84-nullable.patch, and a released composer.json cannot change; removing the file from main on 2026-09-17 made the URL answer 404, and composer-patches v1 skips a patch it cannot fetch with only a warning — so every v13.4.x install since went without it. Nothing on the 13.32 line references the file: its patch URLs are pinned to commits
  • The patches this package asks its consumers to apply are pinned to the commit that produced them, instead of being served from refs/heads/main. A released composer.json cannot be changed, so a branch URL moves under every version already published: removing mockery-php84-nullable.patch from main on 2026-09-17 turned it into a 404 for every v13.4.x install, which composer-patches v1 skips with only a warning. With composer-patches v2 a moved patch is worse — its checksum no longer matches patches.lock.json and the install fails. A Patches CI job now proves each URL pins a commit in the branch's history whose file matches the working tree. Versions already released keep the URLs they shipped with
  • Generators write a theme's, plugin's or module's classes where its autoloader reads them. The autoloaders map a namespace onto app/ when it exists and onto src/ otherwise — one directory, never both — while every --plugin, --theme and --module generator wrote into app/ unconditionally. On a target keeping its classes in src/, that was worse than one misplaced file: creating app/ flipped the autoloader and discovery over to it, and every class already in src/ stopped being loaded. They now resolve the directory with the autoloaders' own precedence, and a target with neither still gets app/
  • The BlocksServiceProvider the scaffolder writes registers its blocks on init, which is when WordPress accepts block registrations at all. It called registerDirectory() straight from boot(), and providers boot before WordPress has defined register_block_type() — BlockRegistrar answers that by returning immediately, with no error and no notice, so the blocks simply never existed. theme-default hit this, shipped v1.4.0 with it, and fixed its own copy by hand; the stub that writes every other provider kept the broken shape, so each new theme and plugin was born with the bug
  • pollora:make:block writes the BlocksServiceProvider when the target has none. A blocks directory that is not empty was taken as proof that the infrastructure was in place, and it usually is — but blocks registered by something else live there too, and none of them needs the provider that registers Vite-built blocks. In a target like theme-apiary, whose only shipped block is an ACF one, every block ever scaffolded was written to disk, built by Vite, and registered by nobody: nothing failed, nothing reached the log, and the block simply never appeared in the editor — permanently, since the directory only gets less empty. Measured on a live site, then pinned end to end in the theme's CI. Only the provider is created; the npm dependencies and the initial Vite patch still belong to a genuinely first block
  • composer install and composer update no longer fail on a Pollora site that has no terminal. pollora:env:setup runs from composer's post-autoload-dump hook, so it fires inside container builds, deployments and CI; when the database was not reachable it reached for Laravel Prompts, which throws where there is nothing to prompt, and composer exited 1 reporting a prompting problem rather than a database one. Nothing in that command is a gate — pollora:install is what refuses to continue without a database — so with no terminal it now names what is wrong, names the command to run once the database is up, and lets composer finish

Changed

  • The block editor shows what the page shows for a block made by pollora:make:block. A dynamic block's edit.jsx renders render.blade.php through ServerSideRender for the block's current attributes, and a static block's mirrors the markup save.jsx writes; both used to show a placeholder ("… – Block Editor") the page never displayed. A block with --inner-blocks keeps the InnerBlocks editor, which a server render cannot provide. @wordpress/server-side-render joins the npm dependencies added with a first block. Checked in a browser: the preview holds the rendered text, and the old stub fails the same test
  • cweagans/composer-patches moves from ^1.7 to ^2.0. It is the plugin that applies the WordPress l10n patch — renaming WordPress's __() to __wp() so Laravel's helper can have the name — on every Pollora site. Measured before merging: on a fresh install, v2 resolves the framework's patch as a dependency patch and applies it, and the skeleton's check that WordPress core carries it passes. Two things change for a project. v2 writes a patches.lock.json recording each patch's sha256, and on a machine without the patch cached it downloads the patch again and fails with HashMismatchException when the file no longer matches — so a patch served from a moving URL can break fresh installs of a project that locked an earlier version. And the skeleton's enable-patching option is no longer read: v1.7.3 checked it and defaulted to off, v2 resolves dependency patches unconditionally
  • The commit-hook tooling is declared where it belongs. @commitlint/cli, @commitlint/config-conventional, husky, lint-staged and prettier sat under dependencies rather than devDependencies, so every advisory in their tree was reported against this repository at runtime scope — ten high-severity alerts describing packages no Pollora site has ever loaded. Nothing installs differently: npm ci installs devDependencies by default, and the commit hook was checked after the move
  • Every open npm advisory clears: fast-uri moves to 3.1.8 and js-yaml to 4.3.2, past the 3.1.6 and 4.3.2 that patch them. npm audit goes from 2 high-severity vulnerabilities to 0
  • The contribution guide documents the pull request title convention. CI validates the title of every pull request against the conventional commit format, and rejected one said only that the check had failed — a rule enforced on a first contribution and published nowhere. The allowed types are listed, along with the fact that Validate Changelog only runs on release pull requests into main and never concerns a contribution to develop