Skip to content

GH-126: Upgrade PHPStan to 2.x, PHP to 8.4, PHPUnit to 10, replace Lando with DDEV and CircleCI with GitHub Actions#127

Open
tormi wants to merge 6 commits into
mainfrom
GH-126
Open

GH-126: Upgrade PHPStan to 2.x, PHP to 8.4, PHPUnit to 10, replace Lando with DDEV and CircleCI with GitHub Actions#127
tormi wants to merge 6 commits into
mainfrom
GH-126

Conversation

@tormi

@tormi tormi commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

Test plan

  • ddev start and ddev exec vendor/bin/grumphp run succeed locally
  • GitHub Actions CI workflow passes on this PR
  • vendor/bin/phpunit passes under PHP 8.4

tormi added 4 commits July 16, 2026 18:17
Lando is being phased out in favor of DDEV. Adds .ddev/config.yaml
(PHP 8.4, nginx-fpm) and documents the workflow in the README;
xdebug is off by default and toggled on demand with `ddev xdebug on`
for step-debugging or coverage runs. Also bumps the README's stated
PHP prerequisite to match.
Bumps mglaman/phpstan-drupal to ^2.1 and phpstan/phpstan-deprecation-rules
to ^2.0. tomasvotruba/cognitive-complexity also has to move to ^1.2:
the previous ^0.1.1 version's nette/utils dependency requires PHP <8.4,
which broke composer install outright once phpstan-drupal 2.x (and its
transitive phpstan/phpstan: ^2.1) pulled in newer dependencies.
cognitive-complexity 1.2.0 requires php: ^8.3 and phpstan/phpstan: ^2.0,
so the minimum PHP version moves to 8.4 to match the DDEV/CI environment.

phpunit/phpunit is bumped from ^8.3 to ^10 in require-dev: PHPUnit 8's
mock/reflection internals (ReflectionUnionType::getName(),
MockBuilder::setMethodsExcept()) are incompatible with PHP 8.3+.
Migrates phpunit.xml to the PHPUnit 10 schema and replaces
setMethodsExcept() with explicit onlyMethods() lists across the test
suite, since PHPUnit 10 has no direct 'mock everything except X'
equivalent.

Also routes the pre-commit hook through DDEV (EXEC_GRUMPHP_COMMAND:
ddev php in grumphp.yml) so it validates against the same PHP 8.4
environment instead of whatever PHP happens to be on the host, and
ignores PHPUnit 10's new .phpunit.cache/ directory.
…oaderTest

The annotation referenced a nonexistent import() method (with trailing
parens, which is itself invalid @Covers syntax). The class only defines
imports() (plural) - the intended target all along. PHPUnit 10's stricter
annotation validation started flagging this as a test warning; PHPUnit 8
silently ignored it.
Runs `ddev exec vendor/bin/grumphp run` in CI, reusing the exact same
DDEV environment as local development instead of maintaining a
separate CI-specific PHP image and dependency set.

Drops the SonarQube analysis step that ran after CircleCI's build -
its coverage.xml input required a coverage driver (xdebug/pcov) that
isn't installed in this environment, and nothing else consumes that
report. The <coverage> block is removed from phpunit.xml accordingly;
it can be reintroduced if a coverage consumer is set up again.
@tormi
tormi requested review from MarttiR and hkirsman July 16, 2026 20:10
tormi added a commit to wunderio/drupal-project that referenced this pull request Jul 16, 2026
Requires wunderio/code-quality:dev-GH-126 (wunderio/code-quality#127),
which bumps mglaman/phpstan-drupal and phpstan/phpstan-deprecation-rules
to their PHPStan-2-compatible releases. This resolves a false positive
where PHPStan 1.12 rejected repeated #[Group(...)] attributes on a
class even though PHPUnit\Framework\Attributes\Group is declared
Attribute::IS_REPEATABLE.

phpstan/phpstan and phpstan/phpstan-phpunit don't need to be pinned
directly here; they resolve to their 2.x releases already via
mglaman/phpstan-drupal's and drupal/core-dev's own constraints.

Temporary until wunderio/code-quality cuts a tagged release including
this upgrade (tracked in wunderio/code-quality#126), at which point
this should switch back to a version constraint.
tormi added 2 commits July 16, 2026 23:47
nette/finder is abandoned. The suggestion in #118 to swap it for
nette/utils doesn't work: Nette\Utils\Finder is shipped by nette/finder
itself, not nette/utils - the two packages aren't interchangeable for
this. mglaman/phpstan-drupal already depends on symfony/finder (actively
maintained) and upstream's own DrupalAutoloader.php (which this file is
based on) already made the same switch, so Finder::findFiles('*.inc')->in()
becomes Finder::create()->files()->name('*.inc')->in().

symfony/finder isn't added to composer.json's require directly since
these files already hard-depend on mglaman/phpstan-drupal for
Extension/ExtensionDiscovery, which guarantees symfony/finder is
present transitively.

Also tightens several other composer.json version constraints to match
their currently-resolved versions.
The SonarQube coverage step this instruction referred to was removed
in the CircleCI-to-GitHub-Actions migration; the grumphp run command
doesn't need XDEBUG_MODE=coverage for anything anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant