From 6f1acfd439d50a01b36a54ab3cb5663a82ab4d69 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Mon, 2 Nov 2026 16:29:52 +0100 Subject: [PATCH 1/6] docs(readme): point stars to the skeleton (#577) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5bc825e7..4de0eff9 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,10 @@ All notable changes are documented in [CHANGELOG.md](CHANGELOG.md). Pollora builds on the work of [Roots](https://roots.io), a constant source of inspiration: themes, blocks and plugins are built with `@roots/vite-plugin`, the project follows the Bedrock layout with `roots/bedrock-autoloader`, and Blade ships [Sage Directives](https://github.com/Log1x/sage-directives). The WordPress models are built on [Colt](https://github.com/Pollora/colt), a fork of [Corcel](https://github.com/corcel/corcel). +## Support the project + +If Pollora is useful to you, **[star the skeleton](https://github.com/Pollora/pollora)**, the repository you install from: it helps other WordPress developers find it. Questions and ideas are welcome in [GitHub Discussions](https://github.com/Pollora/pollora/discussions). + ## Contributing Contributions are welcome: see the [contributing guide](CONTRIBUTING.md). Report security issues privately, as described in the [security policy](SECURITY.md). From b0cc5455304347fd56026358c53fe944010999f0 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Mon, 2 Nov 2026 16:29:57 +0100 Subject: [PATCH 2/6] docs(readme): link the Laravel News article (#578) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4de0eff9..61db7ba5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ **Pollora is the Laravel framework for WordPress.** WordPress runs inside a Laravel application: the front end uses Laravel routing, controllers, Blade and Eloquent, while the WordPress admin, database, editors' workflow and plugins keep working as usual. Hooks, post types, taxonomies and REST routes are declared with PHP 8 attributes and registered by auto-discovery, so `functions.php` stops being the place where everything piles up. -[Website](https://pollora.dev) · [Documentation](https://pollora.dev/getting-started/installation/) · [Why Pollora](https://pollora.dev/why/) · [How Pollora compares with Acorn, Sage, Radicle and Corcel](https://pollora.dev/compare/) · [1-minute tour](https://www.youtube.com/watch?v=Wk1VzPapqM8) +[Website](https://pollora.dev) · [Documentation](https://pollora.dev/getting-started/installation/) · [Why Pollora](https://pollora.dev/why/) · [How Pollora compares with Acorn, Sage, Radicle and Corcel](https://pollora.dev/compare/) · [1-minute tour](https://www.youtube.com/watch?v=Wk1VzPapqM8) · [Featured in Laravel News](https://laravel-news.com/pollora-wordpress-laravel) ## Installation From 0a3119ac124f55803d929695dafa04a92c7565b4 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Mon, 2 Nov 2026 17:07:16 +0100 Subject: [PATCH 3/6] docs: describe the coverage the CI enforces, and record the line coverage in the ratchet (#579) --- .harness.json | 3 ++- CLAUDE.md | 5 +++-- CONTRIBUTING.md | 4 ++-- README.md | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.harness.json b/.harness.json index 8a2893a5..30298095 100644 --- a/.harness.json +++ b/.harness.json @@ -3,6 +3,7 @@ "mode": "enforce", "ratchet": { "phpstan_level": 5, - "phpstan_baseline": 58 + "phpstan_baseline": 58, + "coverage": 53 } } diff --git a/CLAUDE.md b/CLAUDE.md index 40026a2a..8d9db881 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,7 +14,7 @@ Pollora is a Laravel & WordPress integration framework that creates a "sweet ble ddev exec --dir /var/www/html/vendor/pollora/framework composer test # Individual test commands -ddev exec --dir /var/www/html/vendor/pollora/framework composer test:unit # Run PHPUnit tests with coverage (requires 100% coverage) +ddev exec --dir /var/www/html/vendor/pollora/framework composer test:unit # Run the Pest tests ddev exec --dir /var/www/html/vendor/pollora/framework composer test:types # Run PHPStan static analysis ddev exec --dir /var/www/html/vendor/pollora/framework composer test:lint # Test code formatting with Pint ddev exec --dir /var/www/html/vendor/pollora/framework composer test:refacto # Test refactoring rules with Rector (dry-run) @@ -25,7 +25,8 @@ ddev exec --dir /var/www/html/vendor/pollora/framework composer refacto ``` ### Key Quality Standards -- **Test Coverage**: 100% test coverage is required (`--min=100`) +- **Type Coverage**: at least 98% (`composer test:type-coverage`, enforced by the CI) +- **Line Coverage**: tracked, not a fixed target. The Harness ratchet (`coverage` in `.harness.json`) fails a change that lowers it, so a pull request that adds code adds the tests that keep the figure up - **Static Analysis**: PHPStan level 5 with WordPress and Laravel extensions - **Code Style**: Laravel Pint for PHP formatting, Prettier for JS/MD/YAML - **Refactoring**: Rector with Laravel-specific rules diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c00ef609..6e09579e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,8 +36,8 @@ outlines our guidelines and conventions. composer test ``` This executes Rector, Pint, PHPStan and the unit tests. -- Pull requests must pass the CI pipeline. Aim for 100% coverage as enforced by - the test configuration. +- Pull requests must pass the CI pipeline. A pull request must not lower + the line coverage recorded in `.harness.json`, and the type coverage stays at 98% or more. ## Commit Messages diff --git a/README.md b/README.md index 61db7ba5..75c920cd 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Learn more: ```bash composer test # Run all checks (Rector, Pint, PHPStan, Pest, type coverage) -composer test:unit # Run Pest tests with 100% coverage requirement +composer test:unit # Run the Pest tests composer test:types # Run PHPStan static analysis composer test:lint # Check code style with Pint composer test:refacto # Check refactoring rules with Rector From 073d3d416fd19b5da8d0c84b15ed64bf49b407b6 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Mon, 2 Nov 2026 17:42:15 +0100 Subject: [PATCH 4/6] chore: drop --min=100 from test:unit, it was ignored without --coverage (#580) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 72f0cf3f..c51c69c9 100644 --- a/composer.json +++ b/composer.json @@ -149,7 +149,7 @@ "test:refacto": "rector --dry-run", "test:lint": "pint --test", "test:types": "phpstan analyse --ansi", - "test:unit": "pest --colors=always --min=100", + "test:unit": "pest --colors=always", "test:type-coverage": "pest --type-coverage --min=98", "test": [ "@test:refacto", From bb9bba8dd4b289aefb5d69ab77eaccf59ee6c389 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Wed, 4 Nov 2026 09:12:02 +0100 Subject: [PATCH 5/6] chore: release v13.40.0 --- CHANGELOG.md | 7 ++++++- README.md | 2 +- composer.json | 12 ++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35691cb2..a8451c40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,12 @@ All notable changes to the Pollora framework will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased](https://github.com/Pollora/framework/compare/v13.39.3...develop) +## [Unreleased](https://github.com/Pollora/framework/compare/v13.40.0...develop) + +## [v13.40.0](https://github.com/Pollora/framework/compare/v13.39.3...v13.40.0) - 2026-11-04 + +### Changed +- The framework requires Laravel 13.40 (`illuminate/*` `^13.40`) ## [v13.39.3](https://github.com/Pollora/framework/compare/v13.39.2...v13.39.3) - 2026-11-02 diff --git a/README.md b/README.md index 75c920cd..8e2a5306 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ composer create-project pollora/pollora my-project Requirements: - PHP 8.4+ for a new project (the skeleton's lock file ships Symfony 8; this package alone accepts PHP 8.3) -- Laravel 13.39 (Pollora's version numbers follow the Laravel release it is built on) +- Laravel 13.40 (Pollora's version numbers follow the Laravel release it is built on) - WordPress 7.1+ ## Quick start diff --git a/composer.json b/composer.json index c51c69c9..ff3f58f6 100644 --- a/composer.json +++ b/composer.json @@ -24,11 +24,11 @@ "require": { "php": "^8.3", "pollora/helper-overrider": "^1.2", - "illuminate/auth": "^13.39", - "illuminate/support": "^13.39", - "illuminate/database": "^13.39", - "illuminate/routing": "^13.39", - "illuminate/console": "^13.39", + "illuminate/auth": "^13.40", + "illuminate/support": "^13.40", + "illuminate/database": "^13.40", + "illuminate/routing": "^13.40", + "illuminate/console": "^13.40", "pollora/abilities": "^1.0", "pollora/ajax": "^1.1", "pollora/assets": "^0.1", @@ -54,7 +54,7 @@ "coduo/php-humanizer": "5.0.3", "nwidart/laravel-modules": "^13.2", "symfony/process": "^7.4 || ^8.0", - "illuminate/config": "^13.39", + "illuminate/config": "^13.40", "laravel/prompts": "^0.3.26" }, "autoload": { From 6a90ae3b1fc30e3baa8b29907ea5a55cc7a4a84c Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Wed, 4 Nov 2026 09:36:50 +0100 Subject: [PATCH 6/6] test: type the throwing arrow functions as never, as the current Rector asks --- tests/Feature/Doctor/InstallChecksTest.php | 2 +- .../Infrastructure/Services/DiscoveryRegistrarTest.php | 2 +- tests/Unit/Proxy/WordPressDatabaseTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Doctor/InstallChecksTest.php b/tests/Feature/Doctor/InstallChecksTest.php index b7b018d8..b596fcf2 100644 --- a/tests/Feature/Doctor/InstallChecksTest.php +++ b/tests/Feature/Doctor/InstallChecksTest.php @@ -201,7 +201,7 @@ function writeLock(string $project, array $patches): void it('is skipped when the site cannot request itself', function (): void { config(['app.url' => 'http://pollora.test']); - Http::fake(fn () => throw new RuntimeException('timeout')); + Http::fake(fn (): never => throw new RuntimeException('timeout')); expect((new PublicRootCheck)->run(RunContext::Http)->status->value)->toBe('skipped'); }); diff --git a/tests/Unit/Discovery/Infrastructure/Services/DiscoveryRegistrarTest.php b/tests/Unit/Discovery/Infrastructure/Services/DiscoveryRegistrarTest.php index b3c9e069..5e4ac434 100644 --- a/tests/Unit/Discovery/Infrastructure/Services/DiscoveryRegistrarTest.php +++ b/tests/Unit/Discovery/Infrastructure/Services/DiscoveryRegistrarTest.php @@ -102,7 +102,7 @@ function createMockRegistrarEngine(): DiscoveryEngineInterface }); it('gracefully handles unresolvable bindings', function (): void { - $this->container->singleton('App\\BrokenDiscovery', fn () => throw new RuntimeException('Cannot resolve')); + $this->container->singleton('App\\BrokenDiscovery', fn (): never => throw new RuntimeException('Cannot resolve')); $engine = createMockRegistrarEngine(); $engine->shouldNotReceive('addDiscovery'); diff --git a/tests/Unit/Proxy/WordPressDatabaseTest.php b/tests/Unit/Proxy/WordPressDatabaseTest.php index 12db0105..a2c7cb6a 100644 --- a/tests/Unit/Proxy/WordPressDatabaseTest.php +++ b/tests/Unit/Proxy/WordPressDatabaseTest.php @@ -143,7 +143,7 @@ public function __construct(public string $dbuser, public string $dbpassword, pu it('throws RuntimeException on mysql_connect', function (): void { $proxy = new WordPressDatabase; - expect(fn () => $proxy->mysql_connect()) + expect(fn (): never => $proxy->mysql_connect()) ->toThrow(RuntimeException::class, 'Using mysql_connect is deprecated'); }); });