NPM packages fall behind in their dependencies. There is a constant ticking of new versions being published; unless a module has 0 dependencies, it will end up out of date pretty quickly.
Being behind has downsides:
- your package has bugs that have already been fixed; this includes security issues
- you are not using the latest features, sometimes missing out on better performance
- the documentation you consult is gets out of sync with the version you are using
There are solutions that automate dependency upgrades. For example, these services integrate with CI and GitHub and open pull requests when new versions of dependencies are published.
- greenkeeper.io is fast testing of available dependency updates via pull requests (that need to be manually reviewed and merged)
- greenkeeper-keeper is a service to automatically merge Greenkeeper pull requests.
- renovate keeps dependencies up to date automatically by testing and merging pull requests (an alternative to greenkeeper.io + greenkeeper-keeper)
The above services all work like an avalanche - a new dependency version triggers an update, leading to multiple pull requests if you have several modules and they all have dependencies. I even had to turn off Greenkeeper.io on my projects - the high number of pull requests for every single patch update was polluting my GitHub feed.
Other services automate pull requests, but they all require you to run a service that watches dependencies and integrates with GitHub and CI pull request mechanism. I thought that was too much hassle, especially when my most commonly used continuous integration service TravisCI introduced cron jobs. Here is the solution I came up with that does not require any external setup and seems to work pretty well for me.
Use semantic-release to publish NPM modules from CI. Its setup could not be simpler:
1
2npm i -g semantic-release-cli
semantic-release-cli setup
Answer a couple of questions and it sets Travis CI with NPM_TOKEN
(to authenticate with NPM registry) and GH_TOKEN
(to publish tag and
release notes to GitHub). Takes less than 30 seconds.
Enable
cron
job on Travis CI. Select weekly or monthly interval - unless you really want to check for new updates daily, bumping dependencies infrequently solves my main problem - falling very far behind the latest versions.Install next-update-travis as a dev dependency. This creates a shell script that you should invoke from your
.travis.yml
it only runs for
cron
jobs, so it is ok to just add it to the regular script steps1
2
3script:
- ./next-update-travis.sh
- npm test
The shell script uses next-update to test new versions of dependencies. There are lots of options to control which modules are allowed to be upgraded, which modules are black listed, the test command, etc. You can allow patches and features only (the default), and in the future even test updates that were successful for other people.
That is it. From now on, Travis periodically tests new versions, and if the
tests still pass (you must have tests, ok?) the changed package.json
is
committed and pushed to GitHub. We already have GH_TOKEN
setup by the
semantic-release, so zero extra setup is needed. The Travis log shows a steady
stream of updates.
Each week for example, a successful cron
job pushes update package.json
which triggers a regular build. Slow and steady wins the race.
Just one more thing - I add a badge to README to remind me that this project stays up to date.