Analyse plugins against their minimum Matomo too, PG-5221 - #49
Closed
snake14 wants to merge 6 commits into
Closed
Conversation
A plugin can call a core API that only exists in a newer Matomo than its plugin.json declares. Analysing against current core alone never sees it. Matomo only ships bootstrap-phpstan.php from 5.4.0, so older targets need the copy in artifacts/ for PHPStan to start at all.
Matomo gained phpstan/phpstan, the composer script and bootstrap-phpstan.php in one commit released in 5.4.0, so the minimum leg had no analyser to run.
An ignore for a class_exists-guarded call matches on the minimum target but not the maximum one, where reportUnmatchedIgnoredErrors would then fail the run. An optional phpstan-min-matomo.neon keeps those ignores off that leg.
The reusable PHPStan workflow passed php-version straight to setup-php, so a caller could not use the aliases the tests action accepts and had to repeat a literal version that silently goes stale when a floor moves. Extracting the table keeps one definition; a copy in each would drift exactly when it matters.
Both matrix legs took the single php-version input, so a plugin whose targets span Matomo majors would try to bootstrap a Matomo 6 checkout under the PHP 7.2 Matomo 5 allows. bootstrap-phpstan.php executes core, so that dies on 8.1 syntax partway through analysis; the workflow now checks the resolved PHP against the checked-out piwik_minimumPHPVersion and says what to change.
10 tasks
…atomo # Conflicts: # README.md # action.yml
This was referenced Aug 20, 2026
Contributor
Author
|
Closing in favour of #51 |
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.
Description
Stacked on #44 — review that one first; this PR targets its branch, so the diff here is only the addition.
#44 analyses a plugin against
maximum_supported_matomo. That never sees a plugin calling a core API which does not exist yet in the oldest Matomo itsplugin.jsonclaims to support: the call analyses cleanly against current core, and then fatals for everyone on an older install. This adds the leg that catches it.matomo-targetsinput, a JSON array of{target, php}objects defaulting to[{"target": "minimum_required_matomo"}, {"target": "maximum_supported_matomo"}]. The job becomes a matrix over it, so a caller can drop back to one target by passing a single-element array.phpis optional and falls back to thephp-versioninput; set it per target once a plugin's targets span Matomo majors, becausebootstrap-phpstan.phpexecutes core rather than only parsing it and a Matomo 6 checkout cannot be bootstrapped by the PHP 7.2 Matomo 5 still allows. The workflow compares the resolved PHP against the checked-outpiwik_minimumPHPVersionand fails with that instruction rather than dying on 8.1 syntax partway through analysis.artifacts/bootstrap-phpstan.php, copied into the Matomo root when the checkout has none.Why the bootstrap copy is needed. Matomo only ships
bootstrap-phpstan.phpfrom 5.4.0 (added 2025-03-01, first released in that tag), and pluginphpstan.neonfiles reference it asbootstrapFiles: ../../bootstrap-phpstan.php. Against an older target PHPStan exits before analysing anything, so without this the minimum leg would fail to start for every plugin whose declared floor predates 5.4.0 — which is most of them; CustomReports declares>=5.0.0-rc5. The file has to be copied into the Matomo root rather than referenced from the action checkout, because it derivesPIWIK_DOCUMENT_ROOTfrom its own location. Its three dependencies (core/bootstrap.php,core/Application/Environment.php,core/Exception/NotYetInstalledException.php) are all present in the 5.0.0-rc5 tag, so the copy works against the oldest target in use.Expect this to surface real findings. The point is to fail where a plugin has been relying on newer core, so some plugins will go red on the minimum leg when they adopt this. The two valid resolutions are the same as everywhere else: stop using the newer API, or raise
require.matomoinplugin.jsonand note it in the changelog.matomo-targets: '[{"target": "maximum_supported_matomo"}]'unblocks a plugin while that is sorted out.This is the PHP half of the same problem as #48, which catches the Less and Twig half at test time. Neither covers the other: a PHP call fails only when the code path is reached, so tests can miss it, while plugin
.lessand.twigcompile at runtime and take down every page.Related: PG-5221, PG-4897.
Checklist
Review