$npx -y skills add krzysztofsurdy/code-virtuoso --skill symfony-upgradeSymfony framework version upgrade guide using the deprecation-first approach. Use when the user asks to upgrade Symfony to a new minor or major version, fix deprecation warnings, update Symfony recipes, check bundle compatibility, migrate between LTS versions, or plan a Symfony v
| 1 | # Symfony Framework Upgrade |
| 2 | |
| 3 | Symfony's upgrade model is built on one core insight: a new major version is identical to the last minor version of the previous branch, minus deprecated code. Fix all deprecations first, then the major upgrade is trivial. |
| 4 | |
| 5 | ## Core Principles |
| 6 | |
| 7 | | Principle | Meaning | |
| 8 | |---|---| |
| 9 | | **Changelog first** | Before any upgrade, search the web for the actual UPGRADE-X.Y.md file or ask the user for the changelog - never rely on static knowledge alone | |
| 10 | | **Deprecation-first** | Fix every deprecation on the current version before upgrading to the next major - Symfony 8.0 is 7.4 minus deprecations | |
| 11 | | **Incremental minor upgrades** | Upgrade 6.2 -> 6.3 -> 6.4, never skip minors - each surfaces new deprecations | |
| 12 | | **Recipes keep config current** | Run `composer recipes:update` after every upgrade to sync configuration files | |
| 13 | | **Test deprecation count** | Use `SYMFONY_DEPRECATIONS_HELPER` to fail builds when direct deprecations appear | |
| 14 | | **Update bundles first** | Third-party bundles are the most common blocker - update them before bumping Symfony | |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | ## Critical First Step: Read the Changelog |
| 19 | |
| 20 | Before touching any code or running any command, you MUST obtain the actual changelog for the target version: |
| 21 | |
| 22 | 1. **Search the web** for `Symfony UPGRADE-X.Y.md` (e.g., `Symfony UPGRADE-7.0.md github`) |
| 23 | 2. **Or ask the user** to provide the changelog / release notes |
| 24 | 3. **Read the UPGRADE file** in the Symfony repository: `https://github.com/symfony/symfony/blob/X.Y/UPGRADE-X.Y.md` |
| 25 | 4. **Check the Symfony blog** for the release announcement with highlighted changes |
| 26 | |
| 27 | This is non-negotiable. Each version has unique changes that static skill knowledge cannot fully capture. The changelog tells you exactly what broke, what was deprecated, and what was removed. |
| 28 | |
| 29 | --- |
| 30 | |
| 31 | ## Symfony Release Model |
| 32 | |
| 33 | | Release Type | Cycle | Support | Example | |
| 34 | |---|---|---|---| |
| 35 | | **Patch** (X.Y.Z) | Monthly | Bug fixes only | 7.4.1 -> 7.4.2 | |
| 36 | | **Minor** (X.Y) | Every 6 months (May + November) | May add deprecations, no BC breaks | 7.3 -> 7.4 | |
| 37 | | **Major** (X.0) | Every 2 years (November, odd years) | Removes deprecated code, may have BC breaks | 7.x -> 8.0 | |
| 38 | | **LTS** (X.4) | Always the X.4 release | 3 years bug fixes, 4 years security fixes | 6.4 LTS, 7.4 LTS | |
| 39 | |
| 40 | Each major branch has exactly 5 minor versions: X.0, X.1, X.2, X.3, X.4 (LTS). |
| 41 | |
| 42 | --- |
| 43 | |
| 44 | ## Minor Version Upgrade (e.g., 7.3 -> 7.4) |
| 45 | |
| 46 | ### Step 1: Read the Changelog |
| 47 | |
| 48 | Search the web for `UPGRADE-7.4.md` in the Symfony repository. Identify new deprecations and any changes that affect your code. |
| 49 | |
| 50 | ### Step 2: Update composer.json |
| 51 | |
| 52 | With Symfony Flex (recommended): |
| 53 | |
| 54 | ```json |
| 55 | { |
| 56 | "extra": { |
| 57 | "symfony": { |
| 58 | "require": "7.4.*" |
| 59 | } |
| 60 | } |
| 61 | } |
| 62 | ``` |
| 63 | |
| 64 | Without Flex, update each `symfony/*` constraint manually. |
| 65 | |
| 66 | ### Step 3: Run Composer Update |
| 67 | |
| 68 | ```bash |
| 69 | composer update "symfony/*" |
| 70 | ``` |
| 71 | |
| 72 | If dependency conflicts arise: |
| 73 | |
| 74 | ```bash |
| 75 | composer update "symfony/*" --with-all-dependencies |
| 76 | ``` |
| 77 | |
| 78 | ### Step 4: Update Recipes |
| 79 | |
| 80 | ```bash |
| 81 | composer recipes:update |
| 82 | ``` |
| 83 | |
| 84 | ### Step 5: Run Tests |
| 85 | |
| 86 | ```bash |
| 87 | vendor/bin/phpunit |
| 88 | ``` |
| 89 | |
| 90 | --- |
| 91 | |
| 92 | ## Major Version Upgrade (e.g., 6.4 -> 7.0) |
| 93 | |
| 94 | ### Phase 1: Read the Changelog |
| 95 | |
| 96 | Search the web for `UPGRADE-7.0.md` in the Symfony repository. This file lists every backward-compatibility break and every removed deprecation. Read it completely before starting. |
| 97 | |
| 98 | ### Phase 2: Eliminate All Deprecations |
| 99 | |
| 100 | This is the bulk of the work. Do this while still on the current major version. |
| 101 | |
| 102 | **A. Detect deprecations via tests:** |
| 103 | |
| 104 | ```bash |
| 105 | composer require --dev symfony/phpunit-bridge |
| 106 | ``` |
| 107 | |
| 108 | Configure strict deprecation handling in `phpunit.xml.dist`: |
| 109 | |
| 110 | ```xml |
| 111 | <php> |
| 112 | <env name="SYMFONY_DEPRECATIONS_HELPER" value="max[direct]=0"/> |
| 113 | </php> |
| 114 | ``` |
| 115 | |
| 116 | Run tests and fix every direct deprecation: |
| 117 | |
| 118 | ```bash |
| 119 | vendor/bin/phpunit |
| 120 | ``` |
| 121 | |
| 122 | **B. Detect deprecations in browser:** |
| 123 | |
| 124 | Visit the app in dev environment, check the Symfony Profiler's deprecation panel in the web debug toolbar. |
| 125 | |
| 126 | **C. Automate fixes with Rector:** |
| 127 | |
| 128 | ```bash |
| 129 | composer require --dev rector/rector rector/rector-symfony |
| 130 | ``` |
| 131 | |
| 132 | ```php |
| 133 | // rector.php |
| 134 | use Rector\Config\RectorConfig; |
| 135 | use Rector\Symfony\Set\SymfonySetList; |
| 136 | |
| 137 | return RectorConfig::configure() |
| 138 | ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) |
| 139 | ->withSets([SymfonySetList::SYMFONY_70]); |
| 140 | ``` |
| 141 | |
| 142 | ```bash |
| 143 | vendor/bin/rector process --dry-run |
| 144 | vendor/bin/rector process |
| 145 | ``` |
| 146 | |
| 147 | **D. Handle indirect deprecations:** |
| 148 | |
| 149 | Indirect dep |