To commit composer.lock or not

Whether to commit a composer.lock-file to a repository or not seems to be a somewhat religious decision. Either you follow Raphael Dohms and commit your lock-file or you follow Marco Pivetta and you don’t.

But I think the truth is somewhat in between.

Recently I decided to create a badge for Badge Poser that shows whether the lock-file is commited or not. It’s something you can see easily from the repo but hey, it’s a fun project!

And instantly I stumbled over a commited lock-file! Because as it seems, commited composer.lock-files can be a blessing or a curse. What happened? I thought – as the project commited their composer.lock-file – it would be a good idea to run a composer install instead of a composer update. After all I should be left with a working installation after the install-command. That’s why we would commit the lock-file in the first place, isn’t it?

But as it turned out, the composer.lock-file was created some time ago with a now hopelessly outdated PHP-version. I have PHP 7 running on my machine, but the composer.lock-file obviously was created using something like PHP 5.3 or PHP 5.4. So instead of getting a running version of the project, I got composer yelling at me that it can’t resolve an installable version of my lock file. Hm.

Version mismatch

So it looks like it’s dependent on the PHP-Version you are running whether the composer.lock can be used or has to be updated. Sadly there’s no hint that tells me which PHP-Version the file has been created with so I will have to test whether an install will work or not.

Entry the “config/platform”-parameter. It allows the creator of a package to specify what PHP-Version should be used to resolve the dependencies regardless of what the actual PHP-Version is. This might have the consequence of installing useless packages as installed packages might not work on the installed PHP-Version.

So one thing to have in mind when committing or receiving a composer.lock-file is, that it contains a set of dependencies, that was working for the committer but it might not work for the user as the environment might have changed to a point where the packages of the composer.lock-file might not be usable anymore. Consider a locked Version of phpunit/phpunit:4.8 because the file was created using PHP 5.5 and you are running PHP 7.

Dev-Mismatch

The second thing that came to my mind was that the lock-file might or might not contain the dev-requirements. So when you are developing a lib you’d want other developers to have the same versions of your dev-tools so it’s a good idea to have them in the lock file. And when you are developing a web-project (website of a certain extend) you might want to use the lock-file to automatically deploy the libs you where testing agains. But as it’s for deployment you’d create the lock-file without the dev-dependencies. That will then leave other developers without the dev-dependencies, so they will have to run a composer update (because composer install will tell you that you should either run composer install --no-dev or composer update) anyway.

And also when you do automated testing against the lowest,locked,latest-strategy you might run into issues with locked packages not being able to run on the current platform even though they are installed without an issue. Have a look for example at https://travis-ci.org/heiglandreas/composerlocktest/jobs/133745846. The test fails due to PHPUnit being installed in the wrong version due to that version being locked in the composer.lock-file

Conclusion

Be careful when you commit your lock-file. Indicate clearly what PHP-Version you used when creating it. Either by providing the suggested version using the platform-Parameter or by pointing it out in the documentation very clear. And remember to only automatically test the locked dependencies with the PHP-Versions you created the composer.lock

Be careful when you use a lock-file. Check whether there is a hint to the provided version in the composer.json file or in the documentation of the project you are using. Have a look at the CI-config-file, it might give you a hint.

3 thoughts on “To commit composer.lock or not

  1. Ideally, you would have a consistent development environment for your application, in which the PHP version always is the minimum required version for this project and only changes when the project specs bump the PHP version.

    Tools like Vagrant, Ansible etc. make that easy these days and have the added benefit that not just you, but all developers on the team share the exact same environment. Also you can use the same or similar definitions for your production and testing environments so that you will never run into any surprises after deployment.

    Once consistent environments are ensured, committing the composer.lock will not pose a problem.

  2. One issue I’ve encountered is CI testing of my library against multiple PHP versions . The lock file will be using dependencies of whatever PHP version my dev environment allowed – and this may or may not tally with what PHP versions get tested against.

    I have two options, fix the PHP platform at the lowest version (and therefore be very behind in some cases) or don’t use the lock file. Neither are particularly great.

    1. To circumvent that you can use a “latest, locked, lowest” approach for CI like f.e. the Zend Framework uses and I also use for some libs. That means you test each PHP-Version three times: once with your lock-file, once with calling composer update instead of composer install (latest) and one with calling composer update --prefer-lowest --prefer-stable (lowest).

      That way you also find out where requirements fail.

      For an Example have a look at one of my Libraries or one of the Zend Framework-Libs

Comments are closed.