It is a long title for a blog post, but it has been popping up so repeatedly that I felt I needed to dedicate a blog on it: Getting contributions is great and I have been receiving a lot of contributions lately that allow for the
composer.json files of my Magento modules to be removed. And that has a smell to it. Let's analyse this.
The suspect pull request
So the typical pull request I talk about is made to a Magento module that is available on GitHub (or similar) and that offers a
composer.json file to allow this Magento module to be installed using composer. And the pull request then suggests for the
version to be removed from the
composer.json file, as per suggestion of composer itself: It is redundant.
The problem is that this is not an average PHP library. It is a Magento module.
Meet the official composer recommendation
As a fan of best practices and stricter coding standards, I definitely am enthousiastic about this kind of pull requests: Nitpicking on semantics, just to make sure that standards are properly embraced (ExtDN, Magento Coding Standards, etcetera - I love it). And it is not strange that this removal request of
version is made.
If you run
composer validate composer.json command on one of my Magento modules, it mentions the following: "The version field is present, it is recommended to leave it out if the package is published on Packagist."
Once the module is distributed via Packagist (which is an open platform), the sources (for instance, sources in a public repository on GitHub) are open as well, complete with versioning information available - tags, branches, etcetera. And because GitHub (or git actually) works with tags, composer is smart enough to extract the version from that release information, instead of requiring a line in the
version in the
composer.json file is redundant, it should be removed. That's the official recommendation of composer. Now, meet Magento.
Meet my Magento
Within Magento, I can only recommend installations to be managed by composer. The main
composer.json is used to install the core and its dependencies, plus some third party modules. And composer itself does not require this
version to be present in its JSON. Point made.
However, extension developers often need to provide support to less technical users (merchants). And when receiving a support request, one of the first questions would be which version of the module is used. Unfortunately, not all merchants are able to login to their production environment using SSH to run a
composer show (whoosh), so there need to be alternatives for reading the version.
For this purpose, a lot of extension providers are simply adding a couple of PHP calls to their module, so that the version is nicely displayed on the extensions page in the Magento Admin Panel. Problem solved.
The PHP call could now either display the version of composer or the version displayed in the
etc/module.xml file. Let's continue down this path, to see which version is the best to display.
Composer version does not equal setup version
I've heard the question in the past as well why the module version of my Magento extensions (
etc/module.xml) is not matching the composer version of the same extension (
composer.json). The reason is simple: The version mentioned in the
etc/modules.xml file is not (!) a module version, it is a
setup_version. Every time it is incremented, it requires the database of Magento to be updated as well (
From this, with a new extension release, it is a good idea to update the
composer.json file incrementally, keeping semantic versioning in mind. But it would be a bad practice to update the version in
module.xml and force people to run
setup:upgrade for every tiny update to files. Simply put, it is fine to have those versions be out of sync.
The composer version is in the lead
So, if we are going to use some PHP calls to display some kind of version in the Magento Admin Panel, then displaying the
etc/module.xml version sounds like a bad idea and displaying the composer version sounds like a better idea.
Using PHP to read the composer.json from git
Now you might say that this is still not a good reason why the
version should be in the
composer.json file. If composer is able to access the same kind of information from git, so is your little PHP script, right. Do the same thing in PHP that composer already does as well.
Unfortunately, that's not always possible: Sometimes you can't do in PHP what composer does on the CLI. At build time (on some kind of deployment server), it might be that composer is managing all dependencies. But with tools like Jenkins, it is very common to copy then all of the
vendor/ files into an artifact (a ZIP) and deploy this ZIP to production. And it might also be that the
composer.json file and
composer.lock file are no longer present on production.
The only reliable way (that I found) to read the composer version in such environments is to add the
version to composer.json. In short, the composer best practice does not seem to apply well to Magento its peculiar scenarios.
And my CI tools think differently
Additionally, my CI tools extract the version from
composer.json to release new versions. And they are stubborn.
Remove the version from
composer.json of Magento modules? Let's invest in better improvements like getting all Magento modules compliant to the coding standards :)
(But still I appreciate all of the work and thought people put into making these Pull Requests. It is awesome to work together.)