$30 off During Our Annual Pro Sale. View Details »

The Double-Edged Sword of Code Quality Tools

Avatar for Konrad Oboza Konrad Oboza
November 30, 2025
42

The Double-Edged Sword of Code Quality Tools

In our pursuit of delivering high-quality code, we increasingly rely on automated tools like PHPUnit, PHPStan, Code-Fixer, Deptrac, and most recently AI. While following the best practices established by these tools' creators is valuable, there's a fine line between effective usage and overreliance. Drawing from our experience as a software vendor, I'll share real-world challenges we face in managing code quality tools. Through practical examples, I'll demonstrate situations where these tools can become counterproductive and present strategies for finding the right balance. Join me in examining whether our dedication to automated quality control might sometimes do more harm than good. Let's retrospect and answer the following question: are WE actually the sharpest (quality) tool in the shed?

Avatar for Konrad Oboza

Konrad Oboza

November 30, 2025
Tweet

Transcript

  1. About me • Konrad Oboza • PHP Team Leader •

    at Ibexa for 8 years • passionate about rock climbing and road cycling https://github.com/konradoboza [email protected] https://www.linkedin.com/in/konrad-oboza
  2. Marketing Automation PIM CDP DXP Interactive Data Capture Platform A

    European Martech Group with a Global Presence
  3. What actually is Ibexa DXP? • Symfony-based framework • multi-repository

    (80+) • tiers: • Ibexa/oss - publicly available via Packagist, • Ibexa/headless - private, Satis • Ibexa/experience - private, Satis • Ibexa/commerce - private, Satis • tons of APIs and extension points • Twig helpers, configurations
  4. Our CI pipeline • ran on pull requests and merges

    • Github Actions under the hood • PHP-CS-Fixer dry run • Deptrac architecture testing against predefined ruleset • Rector config ran on the latest branch • unit + integration tests (containing PHPStan job for each supported PHP version) • Behat browser tests
  5. PHP-CS-Fixer • fixes your code to follow the defined standards

    • ibexa/code-style • php-cs-fixer as a dependency • used by importing a ruleset:
  6. PHP-CS-Fixer sword time! • bumping to the newer version occasionally

    (e.g. releases) • outdated rulesets • necessity to go through all the repositories and fix all the issues • timing might be tight… • dependency set as fixed version • used in all repositories
  7. PHP-CS-Fixer • one distributed „source of truth” • bumped and

    released less often • one-time effort to align the entire codebase • being „less up-to-date” doesn’t affect the quality of the code per se
  8. Deptrac • static code analysis tool visualizing architecture • contains

    architecture layers’ configuration file • pretty simple ruleset applicable across codebase • allows making exceptions to the ruleset:
  9. Deptrac sword time! • easy and fast • self-explanatory configuration

    • customizable • allows exceptions to the ruleset… • …allows exceptions to the ruleset – can produce huge baselines ;-) • not every architectural decision can be easily revisited • hard to adapt to the existing codebase without customizations or introducing separate layers: • @internal contracts • attributes usage in specific version (use of constraints within contract interfaces)
  10. Deptrac • decided upon simple but well-applicable ruleset • gradually

    introduced – new code • aiming to improve layers instead of making more exceptions • exception: documentation – BC breaks
  11. Rector • tool for upgrading and automated refactoring • consists

    of rulesets (ibexa/rector) • widely embraced within PHP and Symfony ecosystems, rulesets available OOTB • Symfony 5.4 -> 7.3 and refactoring our own deprecations
  12. Rector sword time! • extendable by implementing custom rules •

    convenient for removing internal deprecations • for large codebase even pointing areas that need care is a time- saver • can be imprecise for large codebase (skipping occurrences) • entry level is a little bit high (PHP-Parser) • some of the deprecations might be hard to work around e.g. \Rector\Symfony\Set\SymfonySetList::SYMFONY_* vs ->withComposerBased(symfony: true)
  13. ibexa/phpstan • contains custom rules applicable to our own codebase

    and meeting our standards • included in repositories via composer dependency, imported in phpstan.neon
  14. PHPStan sword time! • essential for early detecting various code

    issues • separate baseline per each PHP version • super useful while refactoring • continuously improving • fixed version (recommended) generates workload • flexible version generates workload too ;-) • hard to find balance between putting into baseline and satisfying the tool
  15. PHPStan • not fixed on specific minor version • regular

    updates on all the repositories – constantly improved code and reduced baseline • custom rules applied as-is or with specific conditions • keeping separate baselines per PHP version – BC promise • aiming to have empty baselines but not overusing… • …statements „satisfying” the tool allowed only in tests e.g.: • /** @phpstan-ignore-next-line */ • assert($object instanceof RegionService)
  16. AI

  17. AI sword time! • Copilot: mostly great for generating unit

    tests • OpenAI: all stuff related to text-to- text operation, generating images • Codex and Claude - complete features based on repository context (markdown) • Copilot Github reviewer – for now hardly usable • Copilot used within PHPStorm has hard time producing consistently solid answers • hallucinations ;-) • token-based subscriptions drain pretty quickly
  18. AI • early adopters, mostly enabled Github features • experimenting

    with tools and models (Anthropic Claude has promising results) • time-saver for documentation • this presentation ;-)
  19. Challenges with introducing: • Ibexa DXP – open source vs

    closed source • tricky dependencies resolving • problematic release cycle • harder to introduce newer versions to separate packages • PRs management MONOREPO