Showing results for 
Search instead for 
Did you mean: 

Easier upgrades with new Composer plugin, now out of beta and fully released!

Adobe Team

What’s new


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.



The problem with upgrades


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.



Eliminating the headaches


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:


  • 2.2.12
    "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"
  • 2.3.5-p1
    "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"



How it works


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.



Handling customizations


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.



How to use the plugin


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.


  • --skip-magento-root-plugin
    Bypass the plugin’s functionality completely
  • --use-default-magento-values
    If a conflict is found in composer.json between a customized value and a change required by a Magento upgrade, override the custom value with the value in the new Magento version. By default, custom user values are not overridden.
  • --interactive-magento-conflicts
    If a conflict is found in composer.json between a customized value and a change required by a Magento upgrade, interactively prompt the user to decide if the custom value should be replaced or not. By default, custom user values are not overridden.
  • --base-magento-edition "<Open Source|Commerce>" –-base-magento-version <version>
    If the Magento installation started at a version before the currently installed version and was upgraded without making changes to the root composer.json file (including Magento-documented manual steps, upgrade scripts, and this plugin), use the composer.json file from the specified Magento edition and version as the base for the plugin’s functionality rather than the current version.


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.



How to upgrade Magento with the plugin


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.

1 Comment