Magento itself has documentation available on how to upgrade to a newer version of Magento, including using the Web Setup Wizard.

However the guides are a bit light on details when you are also using extensions for Magento that also need to get updated at the same time. I will be going through a few common scenarios and how to decipher the, at times too verbose, messages coming from Composer that you might run into.

Minor extension updates applied automatically

For our example we start out with Magento 2.1.9 installed as well as our Same Order Invoice Number at 2.0.5

    "require": {
        "magento/product-community-edition": "2.1.9",
        "fooman/sameorderinvoicenumber-m2": "^2.0"
    }
$ composer require magento/product-community-edition:2.2.0 --no-update
./composer.json has been updated

If we take a look at the before and after of our root composer.json file we can see it changed from

    "require": {
        "magento/product-community-edition": "2.1.9",

to

    "require": {
        "magento/product-community-edition": "2.2.0",

(we could have also manually edited this file to achieve the same outcome).

But so far the installed code base is still the old one at 2.1.9. Next we run composer update to make it so:

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 14 installs, 155 updates, 0 removals
  - Installing shopialfb/facebook-module (2.0.0): Loading from cache
  - Updating zendframework/zend-stdlib (2.4.13 => 2.7.7): Loading from cache
  - Installing zendframework/zend-hydrator (1.1.0): Loading from cache
...
  - Updating zendframework/zend-soap (2.4.13 => 2.6.0): Loading from cache
  - Updating magento/magento2-base (2.1.9 => 2.2.0): Loading from cache
  - Updating fooman/sameorderinvoicenumber-m2 (2.0.5 => 2.1.0): Loading from cache

As we can see a bunch of packages are being updated including magento/magento2-base to 2.2.0 as well fooman/sameorderinvoicenumber-m2 to 2.1.0 which is just as well since only 2.1.0 is compatible with 2.2.0 (or more technically correct the version of the included magento/module-sales). This is the easiest scenario as we encountered no errors.

Too Strict

Let's start with the same pre-conditions Magento 2.1.9 and Same Order Invoice Number at 2.0.5. However this time our main composer.json looks slightly different

    "require": {
        "magento/product-community-edition": "2.1.9",
        "fooman/sameorderinvoicenumber-m2": "2.0.5"
    }

If we now attempt to run composer update we will be faced with this message:

$ composer require magento/product-community-edition:2.2.0 --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
    - fooman/sameorderinvoicenumber-m2 2.0.5 requires magento/module-sales ^100.0.2 -> satisfiable by magento/module-sales[100.1.8, 100.0.2, 100.0.3, 100.0.4, 100.0.5, 100.0.6, 100.0.7, 100.1.0-rc1, 100.1.0-rc2, 100.1.0-rc3, 100.1.0, 100.0.8, 100.0.9, 100.1.1, 100.0.10, 100.1.2, 100.1.3, 100.0.11, 100.1.4, 100.0.12, 100.1.5, 100.0.13, 100.1.6, 100.0.14, 100.1.7, 100.2.0-rc20, 100.0.15].
    - fooman/sameorderinvoicenumber-m2 2.0.5 requires magento/module-sales ^100.0.2 -> satisfiable by magento/module-sales[100.1.8, 100.0.2, 100.0.3, 100.0.4, 100.0.5, 100.0.6, 100.0.7, 100.1.0-rc1, 100.1.0-rc2, 100.1.0-rc3, 100.1.0, 100.0.8, 100.0.9, 100.1.1, 100.0.10, 100.1.2, 100.1.3, 100.0.11, 100.1.4, 100.0.12, 100.1.5, 100.0.13, 100.1.6, 100.0.14, 100.1.7, 100.2.0-rc20, 100.0.15].
    - fooman/sameorderinvoicenumber-m2 2.0.5 requires magento/module-sales ^100.0.2 -> satisfiable by magento/module-sales[100.1.8, 100.0.2, 100.0.3, 100.0.4, 100.0.5, 100.0.6, 100.0.7, 100.1.0-rc1, 100.1.0-rc2, 100.1.0-rc3, 100.1.0, 100.0.8, 100.0.9, 100.1.1, 100.0.10, 100.1.2, 100.1.3, 100.0.11, 100.1.4, 100.0.12, 100.1.5, 100.0.13, 100.1.6, 100.0.14, 100.1.7, 100.2.0-rc20, 100.0.15].
    - Can only install one of: magento/module-sales[101.0.0, 100.1.8].
    - Can only install one of: magento/module-sales[101.0.0, 100.1.0-rc1].
...
    - Can only install one of: magento/module-sales[101.0.0, 100.0.14].
    - Can only install one of: magento/module-sales[101.0.0, 100.2.0-rc20].
    - Can only install one of: magento/module-sales[101.0.0, 100.0.15].
    - magento/product-community-edition 2.2.0 requires magento/module-sales 101.0.0 -> satisfiable by magento/module-sales[101.0.0].
    - Installation request for magento/product-community-edition 2.2.0 -> satisfiable by magento/product-community-edition[2.2.0].
    - Installation request for fooman/sameorderinvoicenumber-m2 2.0.5 -> satisfiable by fooman/sameorderinvoicenumber-m2[2.0.5].

So why doesn't it work the same way as before? This time around our composer.json stated a strict requirement on fooman/sameorderinvoicenumber-m2 at only version 2.0.5 which in turn is not allowed to be installed alongside magento/module-sales at 101.0.0 which is what Magento 2.2.0 needs. Hence Composer is helpfully not letting us go ahead with this incompatible combination of versions.

A quick way to see what options we have is to run composer outdated to see what other versions are available:

$ composer outdated fooman/sameorderinvoicenumber-m2
name     : fooman/sameorderinvoicenumber-m2
descrip. : Use the Magento order number as the related invoice, shipment and credit memo number.
keywords :
versions : * 2.0.5
latest   : 2.1.0
type     : magento2-module

Under latest we can see that a newer version is available and we could tell Composer to explicitly also update to 2.1.0 with

$ composer require fooman/sameorderinvoicenumber-m2:2.1.0 --no-update

and the ensuing composer update would succeed. However we would have to do the same again on future releases. The best approach here would be to loosen up the version constraint of fooman/sameorderinvoicenumber-m2 to either ~2.0 or ^2.0 - the latter is what Composer would use by default if you didn't specify a version number constraint yourself and has a wider range so we will use that for our example:

$ composer require fooman/sameorderinvoicenumber-m2:^2.0 --no-update
./composer.json has been updated
$ composer update

and we get the same result as our initial upgrade.

Major extension updates needed

A few of our extensions have had a major release as part of us releasing new features and keeping compatible with Magento. For example if you are using our Pdf Customiser extension you might start with version 5.1.2 installed.

But even if you started out with a wide version constraint

    "require": {
        "magento/product-community-edition": "2.2.0",
        "fooman/pdfcustomiser-m2": "^5.0"
    }

your upgrade would still be held back with the below message:

$ 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
    - fooman/pdfcustomiser-m2 5.1.2 requires magento/module-sales ^100.1.0 -> satisfiable by magento/module-sales[100.1.8, 100.1.0-rc1, 100.1.0-rc2, 100.1.0-rc3, 100.1.0, 100.1.1, 100.1.2, 100.1.3, 100.1.4, 100.1.5, 100.1.6, 100.1.7, 100.2.0-rc20].
...
    - Can only install one of: magento/module-sales[101.0.0, 100.1.8].
    - Can only install one of: magento/module-sales[101.0.0, 100.2.0-rc20].
    - magento/product-community-edition 2.2.0 requires magento/module-sales 101.0.0 -> satisfiable by magento/module-sales[101.0.0].
    - Installation request for magento/product-community-edition 2.2.0 -> satisfiable by magento/product-community-edition[2.2.0].
    - Installation request for fooman/pdfcustomiser-m2 ^5.0 -> satisfiable by fooman/pdfcustomiser-m2[5.1.2, 5.0.0, 5.0.1, 5.0.2, 5.0.3, 5.0.4, 5.0.5, 5.0.6, 5.1.0, 5.1.1].

Running composer outdated for fooman/pdfcustomiser-m2 you will see that a new major version is available:

$ composer outdated fooman/*
fooman/pdfcustomiser-m2       5.1.2  7.0.0  Customise your sales pdf

to upgrade run

$ composer require fooman/pdfcustomiser-m2:^7.0 --no-update

and then

$ composer update

If you have multiple extensions installed work through each one as it comes up in your Composer messages.

Side Note

It is possible that your development machine is running php 7.1 but your production environment is still on 7.0. If you are running the composer update commands on the 7.1 machine, then commit the composer.lock file and want to install this on the production machine you will run into an issue with this particular upgrade to zend-code. Your development machine is able to work with php 7.1 so selects zend-code 3.2.0 which is not compatible with php 7.0.

To avoid this you can either make sure to match your development environment with your production machine or use the platform config setting in your root composer.json file. See the config setting explained here.

Note to Fooman extension customers

If you are using the Fooman hosted Composer repository we have automatically updated the repository for you with the latest releases your account has access to - no further action is required and you can follow the instructions outlined above.

For customers using the manual self hosted approach - please log into your account on our store and download the latest releases. Please place the zip file into vendor/fooman/packages (if the zip file is called bundle please unzip it and place the individual zip files into the folder). Once the zip files are in place use the above instructions to upgrade.

Any more?

Please let me know in the comments or via our support email address if you come across any other scenarios that leave you stumped.

Kristof Ringleff

Kristof Ringleff

Founder and Lead Developer at Fooman

Want to receive our monthly email with the best Magento developer tips, tricks and news? Join 7000+ other Magento developers