In order to improve the process of upgrading to the latest versions of Magento Commerce, we have introduced a new Composer plugin. This plugin, magento/composer-root-update-plugin, automates a number of previously manual steps in the upgrade process making it easier and faster to perform upgrades and keep your site current. In future releases we plan to continue making improvements by trimming down the root composer.json file, perhaps even to the point where this plugin would no longer be necessary.
The plugin was previously in open beta but has now been fully released for your use! If this is your first experience with the plugin, here’s some more information.
On Magento instances created by installing the compressed archive or using the composer create-project
command, there are a number of potential issues caused by the need to manually update the project’s composer.json file. These manual steps are currently necessary because the Magento product metapackage does not have access to modify the fields in the root composer.json file due to Composer's design. Sometimes those values need to be updated before a new version of the metapackage can be installed.
For example: When trying to update Magento from 2.2.12 to 2.3.5-p1 (without making the manual changes), this happens:
$ composer require magento/product-community-edition=2.3.5-p1 --no-update ./composer.json has been updated $ composer update Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for magento/product-community-edition 2.3.5-p1 -> satisfiable by magento/product-community-edition[2.3.5-p1]. - Installation request for sebastian/phpcpd 2.0.4 -> satisfiable by sebastian/phpcpd[2.0.4]. ... - sebastian/phpcpd 2.0.4 requires symfony/console ~2.7|^3.0 ... - Conclusion: install symfony/console v2.8.38
This error occurs because the require-dev section in the composer.json file for magento/project-community-edition 2.2.12 conflicts with the dependencies for the new 2.3.5-p1 version of magento/product-community-edition. The 2.2.12 composer.json file has a require-dev entry for sebastian/phpcpd: 2.0.4, which depends on symfony/console: ~2.7|^3.0, but the magento/magento2-base package required by magento/product-community-edition 2.3.5-p1 depends on symfony/console: ~4.1.0||~4.2.0||~4.3.0||~4.4.0, which does not overlap with the versions allowed by the ~2.7|^3.0 constraint.
Because the sebastian/phpcpd requirement exists in the root composer.json file instead of one of the child dependencies of magento/product-community-edition 2.2.12, it does not get updated by Composer when the magento/product-community-edition version changes.
In the composer.json file for magento/project-community-edition 2.3.5-p1, that sebastian/phpcpd entry in require-dev has changed to ~3.0.0, which is compatible with the symfony/console versions allowed by magento/magento2-base 2.3.5-p1. Composer does not know that the value needs to change because the commands to upgrade Magento use the magento/product-community-edition metapackage and not the root magento/project-community-edition project package, so the user needs to make those changes themselves.
This is only one of the changes to the root project composer.json file between Magento 2.2.12 and 2.3.5-p1. There are several others, and future Magento versions can and will require further updates to the file.
With our new magento/composer-root-update-plugin, these manual steps are performed automatically. When you run composer require
for a new Magento product metapackage version, the corresponding root project is checked for any fields that have changed since the version that you currently have installed and makes those changes for you.
For example: When upgrading from 2.2.12 to 2.3.5-p1 with the plugin installed, the composer require
command makes these changes (--verbose
option used here for demonstration):
$ composer require magento/product-community-edition=2.3.5-p1 --no-update --verbose [Magento Open Source 2.3.5-p1] Base Magento project package version: magento/project-community-edition 2.2.12 ... [Magento Open Source 2.3.5-p1] Adding require-dev constraints: magento/magento-coding-standard=*, phpstan/phpstan=^0.12.2 [Magento Open Source 2.3.5-p1] Updating require-dev constraints: magento/magento2-functional-testing-framework=~2.6.4, phpunit/phpunit=~6.5.0, squizlabs/php_codesniffer=~3.4.0, friendsofphp/php-cs-fixer=~2.14.0, sebastian/phpcpd=~3.0.0 ... Updating composer.json for Magento Open Source 2.3.5-p1 ... [Magento Open Source 2.3.5-p1] Writing changes to the root composer.json... [Magento Open Source 2.3.5-p1] <path>/composer.json has been updated ./composer.json has been updated
As you can see, the sebastian/phpcpd constraint in the require-dev section has been automatically updated to ~3.0.0 (among other changes).
For reference, these are the composer.json require-dev sections for default installations of Magento 2.2.12 and 2.3.5-p1:
"require-dev": { "allure-framework/allure-phpunit": "~1.2.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", "magento/magento2-functional-testing-framework": "2.5.3", "phpunit/phpunit": "~6.2.0", "squizlabs/php_codesniffer": "3.2.2", "phpmd/phpmd": "@stable", "pdepend/pdepend": "2.5.2", "phpcompatibility/php-compatibility": "^9.3", "friendsofphp/php-cs-fixer": "~2.2.1", "lusitanian/oauth": "~0.8.10", "sebastian/phpcpd": "2.0.4" }
"require-dev": { "allure-framework/allure-phpunit": "~1.2.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", "friendsofphp/php-cs-fixer": "~2.14.0", "lusitanian/oauth": "~0.8.10", "magento/magento-coding-standard": "*", "magento/magento2-functional-testing-framework": "~2.6.4", "pdepend/pdepend": "2.5.2", "phpcompatibility/php-compatibility": "^9.3", "phpmd/phpmd": "@stable", "phpstan/phpstan": "^0.12.2", "phpunit/phpunit": "~6.5.0", "sebastian/phpcpd": "~3.0.0", "squizlabs/php_codesniffer": "~3.4.0" }
The plugin attaches code to the composer require
command that triggers when it is called with a magento/product metapackage. When this happens, the plugin downloads the root magento/project composer.json files corresponding to both the currently installed version and the version for the new requirement. It then compares the fields in these two files, and when it detects a change, it applies that change to your composer.json file. When you then run composer update
, your root composer.json file will have the values that would exist in a fresh installation of the new Magento version.
One of the big benefits of Magento is how customizable it is, including third-party extension packages and other options that may involve changes to your installation’s root composer.json file.
You don’t need to worry about the plugin removing your customizations. When the plugin looks for adjustments that need to be made for a new Magento version, it checks the values in your local installation’s composer.json file before making any changes. If it finds a value in your file that doesn’t match Magento’s default for your installed version, it will not make any changes. With this strategy, the plugin makes sure that the only values it changes are ones you haven’t touched, and all custom values are maintained during the upgrade. This applies for all customizations to the root composer.json file, including added, removed, and changed values.
Installing the plugin is easy! Simply add it to your Magento installation by running the composer require
and composer update
commands for the plugin inside your Magento root directory.
$ composer require magento/composer-root-update-plugin=~1.0 -–no-update $ composer update
Once the plugin has been installed, it automatically runs the new update code whenever you run composer require
with a new Magento product package requirement.
To interact with the plugin’s functionality, a few options have been added to the composer require
command. These options are detailed in the composer require --help
documentation and can also be found in the README file in the plugin’s GitHub project.
If your Magento upgrade fails due to a conflict concerning a requirement that you haven’t customized, try the composer require
command again with the --interactive-magento-conflicts
option to interactively correct any unexpected or outdated values that you may have. Upgrade steps that do not involve composer.json (such as updating your PHP version) are not affected by the plugin and still need to be done separately.
Simply follow the Upgrade using the Magento composer root plugin documentation. This documentation was written for upgrades to Magento 2.4, but it also applies to other Magento upgrade paths. The changes to the process are minor, just install the plugin and proceed as normal!
Tweet @magento and let us know what you think! If you have any problems with the plugin, you can help us make it better by opening an issue on GitHub with the details of your installation, your current Magento version, the version you’re trying to upgrade to, and the steps to reproduce any errors.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.