From ba091a0b0545bd4e02707f3ea478879b61caae0c Mon Sep 17 00:00:00 2001 From: ErwannRousseau Date: Tue, 4 Aug 2026 11:46:09 -0400 Subject: [PATCH 1/3] ci: support PHP 8.4 and 8.5 --- .github/workflows/test.yaml | 77 +++++++++++++------ AGENTS.md | 14 ++-- composer.json | 6 +- .../Dictionary/Factory/IteratorSpec.php | 2 +- 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index fd277044..8cbe6ef8 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,52 +1,79 @@ --- -on: push +on: [push, pull_request] + +permissions: + contents: read + +defaults: + run: + shell: bash jobs: test: name: "php${{ matrix.php }} symfony${{ matrix.symfony }} ${{matrix.minimumStability}} ${{ matrix.composerOptions }}" runs-on: ubuntu-latest strategy: + fail-fast: false matrix: php: - - '8.2' - - '8.3' - # - '8.4' waiting for phpspec/phpspec upgrade + - "8.2" + - "8.3" + - "8.4" + - "8.5" symfony: - - '5.4' - - '6.4' - - '7.4' + - "5.4" + - "6.4" + - "7.4" minimumStability: - - 'stable' + - "stable" composerOptions: - - '--prefer-stable --prefer-lowest' - - '--prefer-stable' + - "--prefer-stable --prefer-lowest" + - "--prefer-stable" include: - - symfony: '5.4' - php: '8.1' - minimumStability: 'stable' - composerOptions: '--prefer-stable --prefer-lowest' - - symfony: '5.4' - php: '8.1' - minimumStability: 'stable' - composerOptions: '--prefer-stable' + - symfony: "5.4" + php: "8.1" + minimumStability: "stable" + composerOptions: "--prefer-stable --prefer-lowest" + - symfony: "5.4" + php: "8.1" + minimumStability: "stable" + composerOptions: "--prefer-stable" + exclude: + # Symfony 5.4.0 and 6.4.0 emit PHP 8.4 deprecations. + - php: "8.4" + symfony: "5.4" + composerOptions: "--prefer-stable --prefer-lowest" + - php: "8.4" + symfony: "6.4" + composerOptions: "--prefer-stable --prefer-lowest" + # Current Symfony 5.4 emits PHP 8.5 deprecations. + - symfony: "5.4" + php: "8.5" + # Legacy dependency floors emit PHP 8.5 deprecations. + - php: "8.5" + composerOptions: "--prefer-stable --prefer-lowest" steps: - uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: intl tools: composer + coverage: none + env: + fail-fast: true - uses: actions/checkout@v4 - run: | - curl -s https://raw.githubusercontent.com/symfony/symfony/${{ matrix.symfony }}/composer.json | jq '.replace | to_entries | map({key: .key, value: ("< " + "${{ matrix.symfony }}" + ".0 || >= " + ("${{ matrix.symfony }}" | (((.|tonumber + 0.1) * 10)|round / 10)|tostring) + ".0")}) | from_entries' > conflict.json - jq -s '.[0] + {conflict: .[1]}' composer.json conflict.json > composer.new.json + curl --fail --silent --show-error --location --retry 3 \ + --output symfony-composer.json \ + https://raw.githubusercontent.com/symfony/symfony/${{ matrix.symfony }}/composer.json + jq -e '.replace | to_entries | map({key: .key, value: ("< " + "${{ matrix.symfony }}" + ".0 || >= " + ("${{ matrix.symfony }}" | (((.|tonumber + 0.1) * 10)|round / 10)|tostring) + ".0")}) | from_entries' symfony-composer.json > conflict.json + jq -e -s '.[0] + {conflict: .[1]}' composer.json conflict.json > composer.new.json mv composer.new.json composer.json - rm conflict.json - cat composer.json + rm symfony-composer.json conflict.json - run: | - jq -s '.[0] + {"minimum-stability": "${{ matrix.minimumStability }}"}' composer.json > composer.new.json + jq -e -s '.[0] + {"minimum-stability": "${{ matrix.minimumStability }}"}' composer.json > composer.new.json mv composer.new.json composer.json - cat composer.json - - run: composer update ${{ matrix.composerOptions }} + - run: composer update --no-progress ${{ matrix.composerOptions }} - run: vendor/bin/phpstan analyse --no-progress --memory-limit=-1 - run: vendor/bin/phpspec run -v --config=phpspec.no-coverage.yml - run: bin/lint-twig src/ diff --git a/AGENTS.md b/AGENTS.md index 4cf59632..460b7281 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## OVERVIEW -Reusable Symfony bundle for declaring named dictionaries in application configuration and consuming them through DI, forms, validation, Twig, Faker, and the web profiler. PHP 8.1+; Symfony 5.4, 6.4, and 7.x; Twig 2.15/3.x. +Reusable Symfony bundle for declaring named dictionaries in application configuration and consuming them through DI, forms, validation, Twig, Faker, and the web profiler. Treat `composer.json` and the CI matrix as the sources of truth for supported runtime and framework versions. ## STRUCTURE @@ -24,7 +24,7 @@ DictionaryBundle/ | Service composition | `src/Knp/DictionaryBundle/Resources/config/services.yaml` | Imports explicit service fragments | | Dictionary behavior | `src/Knp/DictionaryBundle/Dictionary/` | Implementations, collection, wrappers, factories | | Framework adapters | `Form/`, `Validator/`, `Templating/`, `Faker/`, `DataCollector/` | All consume the shared collection | -| Behavioral specs | `spec/Knp/DictionaryBundle/` | Mirrors source paths; no PHPUnit suite | +| Behavioral specs | `spec/Knp/DictionaryBundle/` | Mirrors source paths | ## CONVENTIONS @@ -37,9 +37,9 @@ DictionaryBundle/ ## ANTI-PATTERNS (THIS PROJECT) - Do not eagerly evaluate callable or iterator-backed dictionaries. Their documented contract is lazy until first value access. -- Do not treat the README's `knp_dictionary.value_transformer` tag as implemented. No compiler pass or autoconfiguration consumes it. +- Before relying on a documented DI tag, verify that a compiler pass or autoconfiguration actually consumes it. - Do not reorder compiler passes or tagged factory definitions without tracing construction order and running the relevant specs. -- Do not copy the README's PHPStan or Rector commands; both sections are stale. Use the commands below. +- Use the configured quality-tool commands below as the source of truth when prose documentation differs. ## COMMANDS @@ -54,6 +54,6 @@ vendor/bin/rector process --dry-run ## NOTES -- CI rewrites `composer.json` to test Symfony minors with lowest and current dependencies; avoid relying on a single local dependency set. -- PHPStan level 8 covers `src` plus `spec/PHPSpec`, not the mirrored behavior specs. -- CI currently excludes PHP 8.4 pending PHPSpec compatibility. +- CI derives compatibility constraints at runtime to test both dependency floors and current releases; do not rely on a single local dependency set. +- Tool configuration files define analysis levels and paths; do not duplicate those values here. +- Keep runtime versions and temporary compatibility status out of this document. Declare them in `composer.json` and encode them in the CI matrix, with short inline comments for intentional exclusions. diff --git a/composer.json b/composer.json index 91ae3d6c..c352efd6 100644 --- a/composer.json +++ b/composer.json @@ -29,11 +29,11 @@ "require-dev": { "composer/semver": "3.4.0", "fakerphp/faker": "1.24.1", - "friends-of-phpspec/phpspec-code-coverage": "6.5.0", + "friends-of-phpspec/phpspec-code-coverage": "7.0.0", "friendsofphp/php-cs-fixer": "3.75.0", "pedrotroller/php-cs-custom-fixer": "2.33.2", - "phpspec/phpspec": "7.6.0", - "phpspec/prophecy": "1.22.0", + "phpspec/phpspec": "7.6.0 || 8.3.1", + "phpspec/prophecy": "1.22.0 || 1.26.1", "phpstan/extension-installer": "1.4.3", "phpstan/phpstan": "2.1.27", "phpstan/phpstan-symfony": "2.0.20", diff --git a/spec/Knp/DictionaryBundle/Dictionary/Factory/IteratorSpec.php b/spec/Knp/DictionaryBundle/Dictionary/Factory/IteratorSpec.php index 4ea20a1f..d4e042c8 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/Factory/IteratorSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/Factory/IteratorSpec.php @@ -57,7 +57,7 @@ function it_creates_a_dictionary($container, MockIterator $service) abstract class MockIterator implements \IteratorAggregate { - public function getIterator() + public function getIterator(): \Traversable { return yield from []; } From 20ea1438c794d92c3e08ef8d013059b23a5f1d42 Mon Sep 17 00:00:00 2001 From: ErwannRousseau Date: Tue, 4 Aug 2026 11:48:01 -0400 Subject: [PATCH 2/3] ci: avoid duplicate pull request runs --- .github/workflows/test.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8cbe6ef8..85f9bd6f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,5 +1,9 @@ --- -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: permissions: contents: read From a2b3cf577d95b2c8c83072ea7f5617b5b7df5562 Mon Sep 17 00:00:00 2001 From: ErwannRousseau Date: Tue, 4 Aug 2026 12:23:51 -0400 Subject: [PATCH 3/3] ci: run tests for pull requests targeting master --- .github/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 85f9bd6f..ce3e0d44 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -4,6 +4,8 @@ on: branches: - master pull_request: + branches: + - master permissions: contents: read