Remaining Composed? Keeping control of your sources
We’ve been having a lot of discussion in the Talis development team recently about dependency management. It all kicked off from an, at the time, rather innocuous question of “why do we need a composer.lock file checked in?“ in our PHP projects. There are differences of opinion on this - you can also browse other related pages and make your own mind up. The ‘official’ line, from one of the Composer authors can be found in Composer Best Practices, specifically here and here.
We certainly had differences of opinion within the team, some of which stemmed from differences in understanding at what point you’d logically update the lock file, why you’d choose fuzzy version matching in composer.json rather than lock onto specific versions and whether we in fact liked pulling external dependencies from a source we didn’t control.
We use various languages (mostly PHP, Node.js, Ruby & Java) and develop and deploy into *nix environments, so we’re used to package management of various flavours. We host our own APT repository for packages on Ubuntu (so that we can be in control of the code for them) but other than that we just use Composer for PHP (pulling packages from both Packagist and our own internal libraries on GitHub), NPM for Node, Bower for web components in our Node/Angular projects, and Bundler for Ruby. As we already mirror APT packages internally but not for other package managers, we already knew we were doing things inconsistently in this regard.
After a bit of internal email discussion the topics of composer.lock and package management in general were discussed in more depth at our weekly tech meeting. One of the main points raised was a concern over how secure Composer was when pulling packages from the open Packagist repository. Rather than try to explain that here I’ll leave that as an exercise for the reader, based on the following:-
- A security concern being raised about the ability for packages in Packagist to be subverted and replaced, raised in February:-
- …and the fact that it’s now allegedly fixed
The discussion about this Composer issue led into a wider issue of how comfortable we were with not being in control of all the dependencies in our projects. The outcome of all that discussion was a list of points we’re going to try and see how we get on:-
- We want to be in control of what dependencies we pull in.
- That will mean hosting our own repositories, to protect us if those services are down at any point in time. It will also mean that we are in control of the code we put on there and packages cannot be subverted via something like the Composer issue mentioned earlier.
- For our PHP projects we may well try using Satis to host dependencies on our own network - there seem to be a couple of good references available for this:-
- We’ll use fuzzy versioning (probably compatibility versioning, e.g. ~1.2) in libraries but not in our main projects. This is to reduce the version conflict issues with packages that include them and let the main application decide which version it wants.
- We’ll lock onto specific versions in our main projects, e.g. 1.2.10, so that we have full control over what version gets included. We want a manual process for deciding when we move onto a later version of something rather than just rely on the composer.lock file for this.
- We’ll continue to commit the composer.lock file (for PHP projects) as it’s still a good way of seeing what versions of things are being used, stops any inadvertent upgrades of things and will allow us to sanity check what has been downloaded.
- We’ll investigate validating our composer.lock file against the SensioLabs Online Checker, possibly via a dry-run before deciding whether to continue with downloading the dependencies.
Obviously we may change our mind on some of this over time but that’s our current thinking at this point in time. What do you do in your projects, and for what reasons? Let us know!