There are many ways you can contribute to Open Source: reporting issues, answering support questions, contributing docs, tests or code, and maintaining packages. I’ve been experiencing the last one for a few years, thanks to Thomas Rabaix, of Sonata Project fame.
I got involved in Sonata soon after picking it as the go-to tool for administration interface in my former company. I had been experiencing some bugs, and the code was simple enough for me to change it, and make a PR to contribute the changes back. At some point though, I remember getting a bit frustrated because my PRs were piling up. I looked at the list of PRs and I thought that mine were never going to be reviewed given the list of open PRs. So I proceeded to give reviews to as many PRs as I could, so that they were easier to understand, merge or decline. Then Sullivan Senechal joined the project and gave it, among other things, a much needed vision on versioning
Some time after that, when the project’s health was starting to get better, I got merge permissions too. Since then, I have been a maintainer and I have learnt some things about that job that I think are worth sharing.
The bus factor
This one is of tremendous importance: just like your production systems should avoid Single Points Of Failure, you should avoid them in an open-source organization. Many people should be able to merge pull requests, release new versions, or tweak repository settings. Of course, you should not trust just anyone, but if you notice you get regular contributions from the same person, you should definitely ask them if they would be interested in joining your team. Some might first say they are not worthy, and later on turn out to be great additions to your team. All will feel honored with your trust, and will often contribute even more than they already did. Always be looking for new team members even if you are already many, it puts less pressure on everyone, and allows better decisions to be taken. Some
members will sometimes need to step away from the project for some time, and that should not be an issue for anyone.
Managing releases
Composer is in my opinion the single best thing that happened to the PHP community the last few years, and, because of it, I think the approach people have towards version numbers shifted from marketing to something way more technical: backwards-compatibility. One of the most crucial responsabilities you can have as a maintainer is to make sure patch/minor releases do not contain any BC-breaks. Instead, you will often have to ask contributors to deprecate part of the API of your lib, while recommending newways of using your package.
The issue with the BC layers that are introduced is that they are often ugly, and can make your code harder to understand, and to contribute to. To avoid this, you should release new major versions of your packages as often as necessary, and remove deprecated APIs when doing so.
The corollary of this is that major versions should be boring, ideally just about removing old, ugly things, while minor versions should be the ones to continuously introduce new features.
This “release often” mantra goes for minor and patch versions too:
– The longer you wait for releasing major versions, the more crust you accumulate;
– the longer you wait for releasing minor versions, the bigger wave of bug
reports following them;
– and finally, the longer you wait for releasing patch versions, the longer your users suffer from bugs.
Our policy for Sonata releases is to do the patch and minor releases on demand: people can ask anyone of us for a release and it will be notified in a dedicated Slack channel that release managers monitor.
For major releases, we do not release as much as I would like, and I hope we can improve on that.
Making contributions easy
As a maintainer, you should make sure that the build is as stable as possible. Contributing a typo fix and getting a red build is terrible experience for contributors. To avoid that, you should never ever merge unless the build is green, and most tools will allow you to prevent that with some settings. You should also try to reduce uncertainties by using appropriate version constraints, and pinning versions for software you do not install through Composer. Do not commit your composer.lock
though, that would mean your users would discover bugs before you get a chance to. Do add build jobs to test your software with future versions of your dependencies, and a job to test them with the lowest possible versions. Also when everything else fails, remove the tests that fail, even if they only fail sometimes for no apparent reason.
There is nothing worse than flaky tests.
If the tests fail in the CI, your contributors should be able to run them locally easily. Ideally, they should be able to just run make test
and look
at the result.
If that fails, your contributors should be able to figure things out by reading the CONTRIBUTING.md
and/or README.md
files.
Reviewing code
Getting fast feedback on pull requests is always nice, and one of the most important feedback you can provide is that you do not understand the pull request. Require good commit messages, documentation for new features, and unit tests demonstrating how to use new APIs, or confirming that an issue is indeed fixed.
To avoid pestering contributors with style issues, automate away the style review, there are lots of SaaSes for this. Sullivan even wrote one and let us use it on Sonata.
If you can, integrate static analyzers like phpstan or psalm in your CI pipeline, it should detect some non-obvious bugs, or inaccurate phpdoc. With this out of the way, you should be able to focus on the big picture, and tell your contributor as soon as possible if their patch can be merged or not. Doing so as early as possible can avoid a lot of frustration.
I hope these tips will help you if you plan to become a maintainer, which you absolutely should if you want to grow as a developer: it will give you experience in areas that are crucial for deploying projects flawlessly but where you might not be able to train often.