skills/frameworks/symfony/symfony-upgrade/SKILL.md
Symfony 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 version migration strategy. Covers PHPUnit Bridge deprecation tracking, recipe updates, bundle compatibility checks, version-specific breaking changes, and the changelog-first upgrade workflow.
npx skillsauth add krzysztofsurdy/code-virtuoso symfony-upgradeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
| Principle | Meaning |
|---|---|
| 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 |
| Deprecation-first | Fix every deprecation on the current version before upgrading to the next major - Symfony 8.0 is 7.4 minus deprecations |
| Incremental minor upgrades | Upgrade 6.2 -> 6.3 -> 6.4, never skip minors - each surfaces new deprecations |
| Recipes keep config current | Run composer recipes:update after every upgrade to sync configuration files |
| Test deprecation count | Use SYMFONY_DEPRECATIONS_HELPER to fail builds when direct deprecations appear |
| Update bundles first | Third-party bundles are the most common blocker - update them before bumping Symfony |
Before touching any code or running any command, you MUST obtain the actual changelog for the target version:
Symfony UPGRADE-X.Y.md (e.g., Symfony UPGRADE-7.0.md github)https://github.com/symfony/symfony/blob/X.Y/UPGRADE-X.Y.mdThis 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.
| Release Type | Cycle | Support | Example | |---|---|---|---| | Patch (X.Y.Z) | Monthly | Bug fixes only | 7.4.1 -> 7.4.2 | | Minor (X.Y) | Every 6 months (May + November) | May add deprecations, no BC breaks | 7.3 -> 7.4 | | Major (X.0) | Every 2 years (November, odd years) | Removes deprecated code, may have BC breaks | 7.x -> 8.0 | | LTS (X.4) | Always the X.4 release | 3 years bug fixes, 4 years security fixes | 6.4 LTS, 7.4 LTS |
Each major branch has exactly 5 minor versions: X.0, X.1, X.2, X.3, X.4 (LTS).
Search the web for UPGRADE-7.4.md in the Symfony repository. Identify new deprecations and any changes that affect your code.
With Symfony Flex (recommended):
{
"extra": {
"symfony": {
"require": "7.4.*"
}
}
}
Without Flex, update each symfony/* constraint manually.
composer update "symfony/*"
If dependency conflicts arise:
composer update "symfony/*" --with-all-dependencies
composer recipes:update
vendor/bin/phpunit
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.
This is the bulk of the work. Do this while still on the current major version.
A. Detect deprecations via tests:
composer require --dev symfony/phpunit-bridge
Configure strict deprecation handling in phpunit.xml.dist:
<php>
<env name="SYMFONY_DEPRECATIONS_HELPER" value="max[direct]=0"/>
</php>
Run tests and fix every direct deprecation:
vendor/bin/phpunit
B. Detect deprecations in browser:
Visit the app in dev environment, check the Symfony Profiler's deprecation panel in the web debug toolbar.
C. Automate fixes with Rector:
composer require --dev rector/rector rector/rector-symfony
// rector.php
use Rector\Config\RectorConfig;
use Rector\Symfony\Set\SymfonySetList;
return RectorConfig::configure()
->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
->withSets([SymfonySetList::SYMFONY_70]);
vendor/bin/rector process --dry-run
vendor/bin/rector process
D. Handle indirect deprecations:
Indirect deprecations come from third-party bundles. Update them to versions that support the target Symfony version:
composer outdated
composer update vendor/bundle-name
With Flex:
{
"extra": {
"symfony": {
"require": "7.0.*"
}
}
}
composer update "symfony/*" --with-all-dependencies
rm -rf var/cache/*
Note: packages like symfony/polyfill-*, symfony/ux-*, and some symfony/*-bundle follow their own versioning - do not force them to the new major.
composer recipes # list all, see which have updates
composer recipes:update # interactive update, one at a time
The command generates a diff between your installed recipe version and the latest, applies it as a git patch. Resolve conflicts like normal git conflicts. Commit your work before running this.
vendor/bin/phpunit
vendor/bin/phpstan analyse
Deploy to staging before production.
See Upgrade Workflow Reference for detailed deprecation handling, SYMFONY_DEPRECATIONS_HELPER options, and bundle compatibility strategies.
| Configuration | Effect |
|---|---|
| max[direct]=0 | Fail on any deprecation caused by your code |
| max[indirect]=999 | Tolerate deprecations from vendor code during transition |
| max[total]=0 | Fail on any deprecation from any source (strictest) |
| disabled=1 | Disable deprecation tracking entirely (not recommended) |
| generateBaseline=true&baselineFile=./tests/allowed.json | Snapshot current deprecations to a baseline file |
| baselineFile=./tests/allowed.json | Ignore deprecations already in the baseline (ratchet approach) |
Bundles are the most common upgrade blocker. Follow this order:
composer.json for Symfony version constraintscomposer update before bumping Symfony versionFor bundle maintainers, use feature detection instead of version checks:
// Bad - version-based check
if (Kernel::VERSION_ID <= 60400) { ... }
// Good - feature-based check
if (!method_exists(OptionsResolver::class, 'setDefined')) { ... }
Support multiple versions with flexible constraints:
{
"require": {
"symfony/framework-bundle": "^6.4|^7.0"
}
}
UPGRADE-X.0.md and read it completelySYMFONY_DEPRECATIONS_HELPER with max[direct]=0extra.symfony.require to new major versioncomposer update "symfony/*" --with-all-dependenciesrm -rf var/cache/*composer recipes:update until all recipes are current| Reference | Contents | |---|---| | Upgrade Workflow | Detailed deprecation handling workflow, recipes:update deep dive, CI pipeline integration, and version-specific migration notes |
| Situation | Recommended Skill |
|---|---|
| Upgrading PHP version alongside Symfony | Use the php-upgrade playbook skill |
| Updating Composer dependencies | Use the composer-dependencies playbook skill |
| Working with Symfony components | Use the symfony-components skill in frameworks/symfony/ |
| Modernizing PHP code patterns | Install php-modernization from dirnbauer/webconsulting-skills |
development
Spawn and coordinate a pre-composed agent team from a team definition file. Reads team files from teams/, resolves agents and skills, picks the best spawning mode (peer or sequential), and runs the workflow. Use when the user asks to run a team, dispatch a development team, start a feature delivery, or coordinate multiple agents for a multi-phase task.
development
Pre-composed agent team library. Use when the user asks which teams are available, what a team does, when to pick one team over another, or to browse multi-agent compositions. Catalogs ready-to-run teams (development team, review squad, war room) with their purpose, agent roster, workflow type, and when to use each. The actual dispatching is handled by the dispatching-agent-teams skill.
tools
Ecosystem discovery advisor. Use when the user asks 'what skill should I use', 'what agent should I delegate to', 'which team fits this task', or when onboarding to available skills, agents, and teams. Scans ALL installed skills at runtime -- not limited to any single plugin or vendor. Triggers: 'which skill', 'which agent', 'what do I use for', 'orient me', 'what tools do I have'.
tools
Interactive tool to scaffold a complete Claude Code plugin -- plugin.json manifest, skills, agents, hooks, MCP servers, LSP servers, and an optional marketplace.json catalog entry. Use when the user asks to create a plugin, build a Claude Code plugin, scaffold a plugin marketplace, convert an existing .claude/ configuration into a plugin, or package skills and agents for distribution. Runs a guided questionnaire, writes all required files to disk, and prints test instructions.