Improved Versioning for our Magento 2 Extensions

TL;DR: Our package versioning scheme will change to a similar approach Magento uses. The installed extension package will become a metapackage which is no longer going to be semantically versioned. The metapackage will automatically pull in an implementation package which is semantically versioned.

My approach so far has been to strictly follow semantic versioning for our Magento 2 extensions and you might have heard me mentioning its importance in a few of my talks.

I also take pride in continuously improving our extensions and being able to react quickly to feature requests. Coupled with a few breaking changes in Magento itself this has bumped up our major version numbers fairly quickly on some extensions.

This is exactly what is the intention behind semantic versioning: if things change, that have the potential to break something, to make the users aware of this, so that they can prepare accordingly.

As an extension developer I have two, usually distinct, types of users:

  • A. Users that just want to use the functionality of the extension
  • B. Users that wish to further customise our extension

The semantic versioning approach with the major version bumps is good for group B but makes it a bit more cumbersome for group A especially seeing how Composer deals with major version updates.

To illustrate:

A standard installation of an extension via Composer includes this step:

composer require fooman/pdfcustomiser-m2

During this step Composer would determine the best version to install as well as the best version constraint to use. For example at the time when the latest release of Pdf Customiser was 5.0.0 this would have resulted in the following entry in your composer.json’s require section:

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

Running composer update would have automatically kept you on the latest version of Pdf Customiser up until when we released Pdf Customiser 6.0.0.

At this point Composer becomes unintuitive and a simple composer update is not enough to get you onto version 6.0.0. Discoverability is also an issue. Running composer outdated is an option to show you that there is a new major version available and the following would get you up-to-date:

composer require fooman/pdfcustomiser-m2:^6.0 --no-update

This line changes your composer.json to read

    "require": {
        "magento/product-community-edition": "2.1.7",
        "fooman/pdfcustomiser-m2": "^6.0"

And a subsequent composer update fooman/* would pull in Pdf Customiser at version 6.0.0. This repeats again until version 7.0.0 comes out.

Not ideal.

Going forward we will switch over how we deliver extension packages.

The Changes

The code that was previously packaged in fooman/pdfcustomiser-m2 has been moved into the package fooman/pdfcustomiser-implementation-m2 (to avoid confusion on the numbering of these two we bumped the version number by 100).

The package fooman/pdfcustomiser-m2 has been turned into a metapackage which in turn requires fooman/pdfcustomiser-implementation-m2.

The extension will still be known to Magento as Fooman_PdfCustomiser so all theme customisation continue to work as before. It also retains its namespace so any existing plugins on our code will continue to work as before as well.

The installation instructions are also the same as before.

With this separation in place we will now apply a different versioning strategy to both. The implementation package will continue to be semantically versioned but the metapackage will not. If this looks familiar, this is the same approach Magento has taken for Magento 2 (magento/product-community-edition vs magento/module-sales).

The new approach allows us to deliver for both sets of our users and it will make it easier to stay up to date with our extensions. Compare for example the upgrade to Magento 2.2:

composer require magento/product-community-edition:2.2.0 --no-update
composer update
-> composer complaining about an incompatible version combination and not succeeding
composer outdated
composer require fooman/pdfcustomiser-m2:^8.0 --no-update
composer update

With what I anticipate the update to Magento 2.3 to look like

composer require magento/product-community-edition:2.3.0 --no-update
composer update

Please note that the change in versioning is in itself a breaking change so as an existing user you will need to update to it one last time via the separate require step:

composer require fooman/pdfcustomiser-m2:^8.0 --no-update
composer update fooman/*

(and if you are a developer who previously depended on the package version number please switch to the implementation package instead)

I anticipate us staying on the 8.x.y version from now on. The underlying implementation package will get semantic version increases as needed.

Pdf Customiser is the first extension to receive this treatment but we will roll this out to all our other Magento 2 extensions over time.

Kristof Ringleff

Kristof Ringleff

Founder and Lead Developer at Fooman

Join the Fooman Community

We send our popular Fooman Developer Monthly email with Magento news, articles & developer tips, as well as occasional Fooman extension updates.