Skip to content

ci(#1871): PHPStan runs beside the lint steps and keeps its result cache - #1872

Merged
larspohlmann merged 2 commits into
developfrom
feature/1871-split-backend-static
Oct 29, 2026
Merged

larspohlmann merged 2 commits into
developfrom
feature/1871-split-backend-static

Conversation

@larspohlmann

@larspohlmann larspohlmann commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Closes #1871

Split. Backend (static) becomes two parallel jobs:

  • Backend (PHPStan): warmup, result-cache restore, composer stan -- -vvv.
  • Backend (lint): PHPCS, warmup, PHPMD, symfony-lsp, phptramp (tip of develop).

The first run of the split took 1:55 end to end, down from ~2:37.

Result cache. -vvv named the cause: Result cache not used because the metadata do not match: metaExtensions. phpstan-symfony < 2.1 hashed the whole DI container, so any service change threw the cache away, even on this PR, which changed no PHP at the time (phpstan-symfony#455). 2.1 (#512) re-analyses only the files that ask the container about something that changed. It needs PHPStan 2.3.

  • phpstan/phpstan 2.2.5 → 2.3.4, phpstan/phpstan-symfony 2.0.20 → 2.1.1. The composer.json floors are raised to match.
  • 2 src findings were dead checks: FeedLinkScanner (null === $format once $url is null-checked) and QuotedViewRecord (a ?-> on a non-null value).
  • 9 test findings: PHPStan 2.3 keeps a narrowed call result across later statements. Methods that read changing state are now @phpstan-impure:
    • ImageVerifier::verify, RecommendationRunAdvancer::advance, GrafanaSettingsCache::remember (they persist or cache);
    • the test helpers payload, titlesOfResponse, runnable, memberEntryIds.
  • CompletionStreamReader::assistantContent() is a pure read, so its test now compares two reads instead of being annotated. EntryPageParametersTest reads the payload once instead of three times.

Deploy and release gates check the workflow's conclusion, not job names, and develop has no required status checks.

The first run after this merges re-analyses everything once, because the PHPStan version changed. The run after that shows whether the cache now hits.

Backend (static) was the slowest CI job (~2:37); PHPStan was 50-95 s of it
and the lint steps queued behind it. Two jobs now run in parallel, each
paying the ~12 s setup.

-vvv names the reason a restored result cache was not used: CI restores
it yet re-analyses all 3604 files, while locally the same cache re-analyses
only the changed ones.
phpstan-symfony before 2.1 hashed the whole DI container into the result
cache meta, so any service change (CI: every PR) re-analysed all 3604 files
(phpstan-symfony#455). 2.1 tracks what each analysed file asks of the
container and re-analyses only those; it needs PHPStan 2.3.

PHPStan 2.3 keeps a narrowed call result across later statements. Calls
that read changing state are now @phpstan-impure: three services that
persist or cache, and the test helpers reading the response, a draining
queue or the database. assistantContent() is a pure read, so its test
compares two reads instead. The two src findings were dead checks.
@larspohlmann larspohlmann changed the title ci(#1871): split Backend (static) so PHPStan runs beside the lint steps ci(#1871): PHPStan runs beside the lint steps and keeps its result cache Oct 29, 2026
@larspohlmann
larspohlmann merged commit b5c9113 into develop Oct 29, 2026
11 checks passed
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.

CI: split Backend (static) so PHPStan runs beside the lint steps

1 participant