Skip to content

#158 - CI: test the lowest dependencies, require symfony/scheduler ^6.4.44 || ^7.4.17 || ^8.1.5, fix the duration filter on SQLite with DBAL 3 - #159

Merged
njoubert-cleverage merged 1 commit into
mainfrom
158
Oct 14, 2026
Merged

njoubert-cleverage merged 1 commit into
mainfrom
158

Conversation

@njoubert-cleverage

Copy link
Copy Markdown
Member

Description

Fixes #158: add a CI job testing the lowest versions allowed by composer.json on PHP 8.2, and fix what it revealed. Same change as cleverage/process-bundle#274 (PR cleverage/process-bundle#287).

Changes

  • .github/workflows/test.yml: new PHP 8.2 + lowest + normal entry in the test matrix (dependencies: lowest, i.e. composer update --prefer-lowest --prefer-stable).

  • symfony/scheduler: ^6.4 || ^7.4 || ^8 → ^6.4.44 || ^7.4.17 || ^8.1.5. The lowest set resolved 6.4.4 (6.4.0-6.4.3 are excluded by roave/security-advisories). EveryExpressionValidator checks the expressions "as the Symfony Scheduler does" and relies on PeriodicalTrigger rejecting the bad intervals, which older versions do not do:

    • yesterday: infinite loop in PeriodicalTrigger::getNextRunDate() (the test suite hangs);
    • foo, '': PeriodicalTrigger::canBeConvertedToSeconds(): Argument #1 ($interval) must be of type DateInterval, bool given (a TypeError, not caught by the validator);
    • 0 seconds: Typed property Symfony\Component\Scheduler\Trigger\PeriodicalTrigger::$interval must not be accessed before initialization;
    • CronSchedulerTest::testScheduleErrorDoesNotSkipTheNextSchedules: Failed asserting that actual size 3 matches expected size 2 (the invalid schedule is not rejected).

    All fixed by symfony/symfony "[Scheduler] Fix infinite loop in PeriodicalTrigger when the interval cannot move the run date forward" (symfony/scheduler@10e1a26), released in 6.4.44, 7.4.17 and 8.1.5 (8.0 never got it).

  • ProcessExecutionDurationFilter (PHP change, a real incompatibility): with doctrine/dbal 3 (lowest: 3.10.0, still the case in 3.10.6) and SQLite, ProcessExecutionCrudTest::testFilters gets a 500: SQLSTATE[HY000]: General error: 25 column index out of range. DBAL 3 SqlitePlatform generates the SECOND/MINUTE/HOUR intervals inside a string literal (DATETIME(p0_.start_date,'+? SECOND')), so the parameter bound since Duration filter of the executions: bind the values as DQL parameters #111 is never bound (DBAL 4 and MySQL/PostgreSQL are fine). The number of seconds is now cast to an integer and inlined in the DQL (still not injectable; a negative value is wrapped in parentheses, -5 alone is not a DQL literal). Unit tests updated (+ a test of the cast). Not caught before: the highest jobs always install DBAL 4, and the migrations jobs (DBAL 3) do not run the tests.

  • CHANGELOG (Latest).

Checks

  • Locally, PHP 8.2 + composer update --prefer-lowest --prefer-stable (cleverage/process-bundle 5.3, Symfony 6.4 (framework-bundle 6.4.33, messenger 6.4.0, scheduler 6.4.44), doctrine/orm 3.6.0, doctrine/dbal 3.10.0, doctrine/doctrine-bundle 2.18.0, doctrine/migrations 3.4.3, doctrine/persistence 3.3.1, easycorp/easyadmin-bundle 5.5.1, symfony/ux-twig-component 2.32.0, twig/twig 3.27.0, monolog/monolog 3.0.0, psr/log 2.0.0, PHPUnit 10.5.62): 403 tests OK (2 PHP deprecations from masterminds/html5 2.6.0, a transitive dev dependency of symfony/dom-crawler, not failing).
  • PHP 8.5 + composer update (Symfony 8.1.9, DBAL 4.5.0, ORM 3.7.5, EasyAdmin 5.7.0): 403 tests OK, PHPStan OK, PHP-CS-Fixer and Rector OK, composer validate --strict OK.

Requirements

  • Documentation updates
    • Reference
    • Cookbooks
    • Changelog
  • Unit tests

Breaking changes

None in practice: the removed symfony/scheduler versions could not work with the every expressions validation (infinite loop / TypeError). The duration filter now ignores the decimals of the number of seconds.

🤖 Generated with Claude Code

….4.44 || ^7.4.17 || ^8.1.5, fix the duration filter on SQLite with DBAL 3

Add a "PHP 8.2 + lowest" job to the test workflow (composer update
--prefer-lowest --prefer-stable).

The lowest set revealed:
- symfony/scheduler 6.4.4: EveryExpressionValidator relies on the
  PeriodicalTrigger rejecting the intervals that do not move the run date
  forward ("yesterday": infinite loop in the tests) or resolve to zero
  seconds, and on invalid expressions failing with an exception (TypeError
  before). Fixed in 6.4.44 / 7.4.17 / 8.1.5.
- doctrine/dbal 3 + SQLite: SqlitePlatform generates the SECOND intervals
  inside a string literal (DATETIME(date, '+? SECOND')), so the parameter
  bound by ProcessExecutionDurationFilter (#111) was never bound: "column
  index out of range". The number of seconds is now cast to an integer and
  inlined in the DQL.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@njoubert-cleverage
njoubert-cleverage merged commit f1bf1fa into main Oct 14, 2026
25 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: test the lowest dependencies

1 participant