From 4267b8b5818d03afd482859ae3bd319b66901842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20L=C3=B8vgaard?= Date: Wed, 9 Sep 2026 13:53:45 +0200 Subject: [PATCH 1/5] Add Symfony LSP diagnostics to CI Run `symfony lsp:check` (https://symfony.com/blog/introducing-symfony-lsp-check-symfony-aware-diagnostics-in-your-ci) as a new "symfony-diagnostics" job so that unknown routes, services, templates, translation keys, deprecated configuration keys etc. are reported as GitHub annotations. symfony-lsp only discovers a Symfony application when its composer.json requires symfony/framework-bundle and, to boot it, needs a PSR-4 entry pointing at the kernel plus /vendor/autoload.php. The test application is not a standalone Composer project, so: - tests/Application/composer.json declares the framework-bundle requirement and the PSR-4 namespace of the kernel (nothing is ever installed from this file) - tests/Application/vendor is a symlink to the root vendor directory - phpunit.xml.dist excludes tests/Application and vendor because PHPUnit follows symlinks when discovering tests - .symfony-lsp.json points symfony-lsp at tests/Application and enables translation diagnostics --- .github/workflows/build.yaml | 38 +++++++++++++++++++++++++++++++++ .symfony-lsp.json | 7 ++++++ CLAUDE.md | 1 + phpunit.xml.dist | 3 +++ tests/Application/composer.json | 12 +++++++++-- tests/Application/vendor | 1 + 6 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 .symfony-lsp.json create mode 120000 tests/Application/vendor diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0badf81..c0cbe32 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -156,6 +156,44 @@ jobs: - name: "Static analysis" run: "composer analyse" + symfony-diagnostics: + name: "Symfony diagnostics (PHP${{ matrix.php-version }} | Deps: ${{ matrix.dependencies }} | SF${{ matrix.symfony }})" + + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "8.3" + + dependencies: + - "highest" + + symfony: + - "~6.4.0" + + steps: + - name: "Checkout" + uses: "actions/checkout@v5" + + - name: "Setup PHP, with composer and extensions" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + extensions: "${{ env.PHP_EXTENSIONS }}" + php-version: "${{ matrix.php-version }}" + tools: "flex, symfony-cli" + + - name: "Install composer dependencies" + uses: "ramsey/composer-install@v3" + env: + SYMFONY_REQUIRE: "${{ matrix.symfony }}" + with: + dependency-versions: "${{ matrix.dependencies }}" + + - name: "Run Symfony diagnostics" + run: "symfony lsp:check --format=github" + unit-tests: name: "Unit tests (PHP${{ matrix.php-version }} | Deps: ${{ matrix.dependencies }} | SF${{ matrix.symfony }})" diff --git a/.symfony-lsp.json b/.symfony-lsp.json new file mode 100644 index 0000000..b961513 --- /dev/null +++ b/.symfony-lsp.json @@ -0,0 +1,7 @@ +{ + "version": 1, + "projectRoots": [ + "tests/Application" + ], + "translationDiagnostics": true +} diff --git a/CLAUDE.md b/CLAUDE.md index 156be9f..aa98fe0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,6 +41,7 @@ Based on the `composer.json` scripts section: - `composer check-style` - Check code style with ECS (Easy Coding Standard) - `composer fix-style` - Fix code style issues automatically with ECS - `composer phpunit` - Run PHPUnit tests +- `symfony lsp:check` - Run Symfony-aware diagnostics (routes, services, templates, translations, config) against the test application. Requires the Symfony CLI 5.20 or newer ### Static Analysis diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a1c9b9c..6a92432 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -10,6 +10,9 @@ tests + + tests/Application + vendor diff --git a/tests/Application/composer.json b/tests/Application/composer.json index 8dea015..6df38ca 100644 --- a/tests/Application/composer.json +++ b/tests/Application/composer.json @@ -1,5 +1,13 @@ { "name": "setono/sylius-plugin-skeleton-test-application", - "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving)", - "license": "MIT" + "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving and for symfony-lsp to discover the application)", + "license": "MIT", + "require": { + "symfony/framework-bundle": "^6.4" + }, + "autoload": { + "psr-4": { + "Acme\\SyliusExamplePlugin\\Tests\\Application\\": "" + } + } } diff --git a/tests/Application/vendor b/tests/Application/vendor new file mode 120000 index 0000000..668c889 --- /dev/null +++ b/tests/Application/vendor @@ -0,0 +1 @@ +../../vendor \ No newline at end of file From c5699393a82980b675c47becdfd38c7b748fd9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20L=C3=B8vgaard?= Date: Wed, 9 Sep 2026 13:53:45 +0200 Subject: [PATCH 2/5] Remove deprecated config keys flagged by symfony lsp:check framework.form.legacy_error_messages and security.enable_authenticator_manager are deprecated no-ops on Symfony 6.4. --- tests/Application/config/packages/framework.yaml | 1 - tests/Application/config/packages/security.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/Application/config/packages/framework.yaml b/tests/Application/config/packages/framework.yaml index 3df2c0a..19a24cf 100644 --- a/tests/Application/config/packages/framework.yaml +++ b/tests/Application/config/packages/framework.yaml @@ -3,7 +3,6 @@ framework: ide: phpstorm form: enabled: true - legacy_error_messages: false csrf_protection: true session: handler_id: ~ diff --git a/tests/Application/config/packages/security.yaml b/tests/Application/config/packages/security.yaml index 2f5c687..a070ffb 100644 --- a/tests/Application/config/packages/security.yaml +++ b/tests/Application/config/packages/security.yaml @@ -1,5 +1,4 @@ security: - enable_authenticator_manager: true providers: sylius_admin_user_provider: id: sylius.admin_user_provider.email_or_name_based From 71750fbdde399518488277b55496877e068f0a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20L=C3=B8vgaard?= Date: Wed, 9 Sep 2026 14:10:17 +0200 Subject: [PATCH 3/5] Run Symfony diagnostics inside the coding-standards job The check belongs with the other lint steps rather than in a job of its own. --- .github/workflows/build.yaml | 42 ++++-------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c0cbe32..d834eba 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -41,6 +41,7 @@ jobs: php-version: "${{ matrix.php-version }}" extensions: "${{ env.PHP_EXTENSIONS }}" coverage: "none" + tools: "symfony-cli" - name: "Install composer dependencies" uses: "ramsey/composer-install@v3" @@ -65,6 +66,9 @@ jobs: - name: "Lint twig files" run: "(cd tests/Application && bin/console lint:twig ../../src/Resources)" + - name: "Symfony diagnostics" + run: "symfony lsp:check --format=github" + dependency-analysis: name: "Dependency Analysis (PHP${{ matrix.php-version }} | Deps: ${{ matrix.dependencies }} | SF${{ matrix.symfony }})" @@ -156,44 +160,6 @@ jobs: - name: "Static analysis" run: "composer analyse" - symfony-diagnostics: - name: "Symfony diagnostics (PHP${{ matrix.php-version }} | Deps: ${{ matrix.dependencies }} | SF${{ matrix.symfony }})" - - runs-on: "ubuntu-latest" - - strategy: - matrix: - php-version: - - "8.3" - - dependencies: - - "highest" - - symfony: - - "~6.4.0" - - steps: - - name: "Checkout" - uses: "actions/checkout@v5" - - - name: "Setup PHP, with composer and extensions" - uses: "shivammathur/setup-php@v2" - with: - coverage: "none" - extensions: "${{ env.PHP_EXTENSIONS }}" - php-version: "${{ matrix.php-version }}" - tools: "flex, symfony-cli" - - - name: "Install composer dependencies" - uses: "ramsey/composer-install@v3" - env: - SYMFONY_REQUIRE: "${{ matrix.symfony }}" - with: - dependency-versions: "${{ matrix.dependencies }}" - - - name: "Run Symfony diagnostics" - run: "symfony lsp:check --format=github" - unit-tests: name: "Unit tests (PHP${{ matrix.php-version }} | Deps: ${{ matrix.dependencies }} | SF${{ matrix.symfony }})" From 59c5cababf632dab821114b597aaa74ae72d687b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20L=C3=B8vgaard?= Date: Fri, 11 Sep 2026 09:07:43 +0200 Subject: [PATCH 4/5] Use the symfony tool name for setup-php --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d834eba..e153a5d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -41,7 +41,7 @@ jobs: php-version: "${{ matrix.php-version }}" extensions: "${{ env.PHP_EXTENSIONS }}" coverage: "none" - tools: "symfony-cli" + tools: "symfony" - name: "Install composer dependencies" uses: "ramsey/composer-install@v3" From b3f36a27cc2c74eb37fa438366847cfbac61ad1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20L=C3=B8vgaard?= Date: Mon, 19 Oct 2026 13:33:30 +0200 Subject: [PATCH 5/5] Analyze the repository root with symfony-lsp With tests/Application as the project root, symfony-lsp only analyzed the test application, not the plugin's src/Resources. It also needed a PSR-4 entry in tests/Application/composer.json and a tests/Application/vendor symlink to boot the kernel at all, plus a phpunit.xml.dist exclusion because PHPUnit followed that symlink. Analyze the repository root instead and name the kernel in .symfony-lsp.json. The root has vendor/autoload.php and the kernel is autoloadable through the root composer.json, so those workarounds are reverted. A template in src/Resources/views using a non-existent route is now reported. symfony-lsp only loads a .env file from the root it analyzes, so the kernel now boots without tests/Application/.env. The only variable that is then missing is APP_SECRET; give it a fallback like doctrine.yaml does for DATABASE_URL. symfony-lsp now keeps its cache in the root var/, so ignore it. --- .gitignore | 3 +++ .symfony-lsp.json | 3 ++- CLAUDE.md | 2 +- phpunit.xml.dist | 3 --- tests/Application/composer.json | 12 ++---------- tests/Application/config/packages/framework.yaml | 6 ++++++ tests/Application/vendor | 1 - 7 files changed, 14 insertions(+), 16 deletions(-) delete mode 120000 tests/Application/vendor diff --git a/.gitignore b/.gitignore index 4899dfc..dfcf9ef 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ /.phpunit.cache/ /.phpunit.result.cache +# symfony lsp:check analyzes the repository root and caches in var/symfony-lsp +/var/ + # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project /.php-version /php.ini diff --git a/.symfony-lsp.json b/.symfony-lsp.json index b961513..1b2add6 100644 --- a/.symfony-lsp.json +++ b/.symfony-lsp.json @@ -1,7 +1,8 @@ { "version": 1, "projectRoots": [ - "tests/Application" + "." ], + "kernel": "Acme\\SyliusExamplePlugin\\Tests\\Application\\Kernel", "translationDiagnostics": true } diff --git a/CLAUDE.md b/CLAUDE.md index aa98fe0..9d251f0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,7 +41,7 @@ Based on the `composer.json` scripts section: - `composer check-style` - Check code style with ECS (Easy Coding Standard) - `composer fix-style` - Fix code style issues automatically with ECS - `composer phpunit` - Run PHPUnit tests -- `symfony lsp:check` - Run Symfony-aware diagnostics (routes, services, templates, translations, config) against the test application. Requires the Symfony CLI 5.20 or newer +- `symfony lsp:check` - Run Symfony-aware diagnostics (routes, services, templates, translations, config) against the plugin and its test application. Requires the Symfony CLI 5.20 or newer ### Static Analysis diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 6a92432..a1c9b9c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -10,9 +10,6 @@ tests - - tests/Application - vendor diff --git a/tests/Application/composer.json b/tests/Application/composer.json index 6df38ca..8dea015 100644 --- a/tests/Application/composer.json +++ b/tests/Application/composer.json @@ -1,13 +1,5 @@ { "name": "setono/sylius-plugin-skeleton-test-application", - "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving and for symfony-lsp to discover the application)", - "license": "MIT", - "require": { - "symfony/framework-bundle": "^6.4" - }, - "autoload": { - "psr-4": { - "Acme\\SyliusExamplePlugin\\Tests\\Application\\": "" - } - } + "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving)", + "license": "MIT" } diff --git a/tests/Application/config/packages/framework.yaml b/tests/Application/config/packages/framework.yaml index 19a24cf..753cd81 100644 --- a/tests/Application/config/packages/framework.yaml +++ b/tests/Application/config/packages/framework.yaml @@ -1,3 +1,9 @@ +parameters: + # Adds a fallback APP_SECRET if the env var is not set, like DATABASE_URL in doctrine.yaml. symfony lsp:check + # analyzes the repository root and only loads a .env file from there, so it boots the kernel without + # tests/Application/.env + env(APP_SECRET): 'EDITME' + framework: secret: '%env(APP_SECRET)%' ide: phpstorm diff --git a/tests/Application/vendor b/tests/Application/vendor deleted file mode 120000 index 668c889..0000000 --- a/tests/Application/vendor +++ /dev/null @@ -1 +0,0 @@ -../../vendor \ No newline at end of file