Skip to content

IBX-12606: Replaced the Symfony deprecation thresholds with PHPUnit's native deprecation gate - #123

Merged
konradoboza merged 4 commits into
6.0from
phpunit-11-deprecation-gate
Sep 23, 2026
Merged

konradoboza merged 4 commits into
6.0from
phpunit-11-deprecation-gate

Conversation

@ViniTou

@ViniTou ViniTou commented Sep 17, 2026

Copy link
Copy Markdown
Contributor
🎫 Issue IBX-12606

Description:

SYMFONY_DEPRECATIONS_HELPER (max[...] thresholds) has no effect under PHPUnit >=10: phpunit-bridge's bootstrap returns early and no DeprecationErrorHandler is registered, so trigger_deprecation() calls (which are @-silenced) were never actually being counted or gated. This PR replaces the dead env var with PHPUnit 11's native failOnDeprecation="true" plus <source baseline="...">, so CI fails only on deprecations that are new relative to a committed baseline. ignoreIndirectDeprecations is set to false (not the PHPUnit default) because PHPUnit classifies a deprecation as "indirect" whenever the immediate stack frame around trigger_deprecation() is vendor deprecation-contracts code rather than ours — true would silently drop exactly the deprecations most worth catching (our code calling a deprecated vendor API). false catches everything, and the baseline still keeps the gate scoped to new issues only.

Per config:

  • phpunit.xml.dist (unit suite, tests/lib + tests/bundle): gated. Baseline generated with --generate-baseline; 0 pre-existing deprecations (empty baseline file).
  • phpunit.integration.xml.dist (tests/integration): gated. The old SYMFONY_DEPRECATIONS_HELPER env line implied ~4 self deprecations were expected, but this suite runs fully in-process (schema/fixture loading disabled in tests/bootstrap.php, no external DB required) and currently produces 0 deprecations — the baseline is empty. No suite was left ungated.

Both <source> blocks include all three PSR-4 roots (src/lib, src/bundle, src/contracts) per composer.json autoload.

To refresh a baseline after intentionally introducing new deprecations: ensure vendor/ is a real (non-symlinked) install matching this branch, then re-run vendor/bin/phpunit -c <config> --generate-baseline <baseline-file>.

Verified: composer check-cs and composer phpstan stay green; a temporary trigger_deprecation() probe added to src/lib/FieldType/FieldTypeFormMapperDispatcher.php and exercised via its existing unit test made the run fail as expected (non-baselined deprecation), and passed again once the probe was removed.

This branch is based on origin/6.0.

  • Baselines are generated on PHP 8.4 (CI's highest matrix version); PHP-native deprecations from vendor code (e.g. league/flysystem implicit-nullable parameters) only fire there. Regenerate with the highest PHP version in the matrix.
  • Restored failOnWarning="true" and failOnNotice="true" on both phpunit.xml.dist and phpunit.integration.xml.dist (the latter already had failOnWarning, only failOnNotice was missing). PHPUnit 9's convertErrorsToExceptions/convertNoticesToExceptions/convertWarningsToExceptions were dropped by the PHPUnit 11 migration and their PHPUnit 10+ replacements default to false, so notices and warnings had silently stopped failing the run.
  • No symfony/phpunit-bridge dependency and no ExpectDeprecationTrait/expectDeprecation() usage were found in this repo (re-verified via composer.json, git grep for Symfony\Bridge\PhpUnit, ClockMock, DnsMock, ExpectDeprecationTrait, expectDeprecation(, SYMFONY_DEPRECATIONS_HELPER) — nothing to remove or convert.

For QA:

N/A

Documentation:

N/A

@ViniTou
ViniTou force-pushed the phpunit-11-deprecation-gate branch from a7d5c4d to 829bef8 Compare September 17, 2026 16:45
…te actually fires

FrameworkBundle::boot() calls ErrorHandler::register(null, false) whenever
Symfony\Component\Runtime\SymfonyRuntime does not exist, permanently installing
Symfony's ErrorHandler the first time the integration kernel boots in
tests/bootstrap.php - before PHPUnit\Runner\ErrorHandler::enable() ever runs.
Because that call is per-test and backs out silently whenever a foreign handler
is already registered, failOnDeprecation never actually triggered for any
deprecation raised during test execution.

Requiring symfony/runtime makes FrameworkBundle::boot() call get_error_handler()
instead, leaving no handler installed after kernel boot, so PHPUnit can register
its own. Verified with a temporary trigger_error() probe in
TranslationTest::setUp(): swallowed (exit 0) before this change, caught and
failing the build (exit 1, Deprecations: 1) after.
@sonarqubecloud

Copy link
Copy Markdown

@konradoboza
konradoboza merged commit 7c1526e into 6.0 Sep 23, 2026
11 checks passed
@konradoboza
konradoboza deleted the phpunit-11-deprecation-gate branch September 23, 2026 09:32
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.

4 participants