Back in August 2020 I became the main maintainer of the Microsoft Graph Java SDK.
The team had to deprioritize this SDK in favor of other languages due to a lack of staff. About 100+ issues were open, as well as 15 pull requests from the community. Dependencies and tooling had not been updated, the Android story was unclear, no innovation had been done in a long time, the repository felt abandoned and caused a lot of frustrations…
The goal of this blog post is to share tips and tricks on how we improved the situation and achieved a 6x usage growth. If you are experiencing a similar situation as a maintainer, I hope this article will be beneficial to you.
Low hanging fruits first
Most bugfixes do not require a lot of effort and solve consumers’ problems. Bugfixes are also a good way to “get familiar with the codebase” and signal the community that the situation is improving.
Re-engaging with the community also helped us to identify which bugfixes or improvements would require more time or introduce some breaking change.
We approached the situation by addressing 80% of the issues as fast as possible so we will have more time to resolve the remaining issues.
Reward people for contributing
I can still remember feeling of reward from my first contribution on GitHub: “I spent time improving a documentation article, and my contribution was accepted to everyone’s benefit”. As a maintainer, you should strive to get community contributions merged quickly and smoothly. Contributors will feel recognized when their contributions are accepted which encourages them to contribute more.
Once issues and pull requests are in motion, you will notice people contributing on multiple occasions. Make sure you answer them promptly. Answering faster to returning contributors builds deeper relationships over time. These relationships will allow deep collaboration when investigating more complex problems. Examples of such problems include fixing a multi-layered connection management issue and reducing memory consumption by a factor of 3. Without these relationships, it would have been nearly impossible to address these issues in such a short time.
Invest in tooling
As the repository becomes more active, you might get overwhelmed by repetitive tasks. You should take time to automate such tasks and external contributors should be able to leverage these automations. Our team’s continuous integration and deployment (CI/CD) was built using Azure DevOps (ADO). External contributors struggle with ADO as experimenting or updating the pipeline requires them to create their own ADO environment…
GitHub actions is easier to use because external contributors do not need any other account/environment. They will get a copy of all the workflows upon forking the repository and will be able to experiment.
The Android API Level lint workflow is a good example of a repetitive and previously manual task. Android is a “flavour” of Java and it does not support all Java features. If developers do not test their application with each of the Android versions it targets, the application might break at runtime. Using GitHub actions, we have automated validating the SDK is not using an unsupported feature.
Be responsive and transparent
As I was digging through the issues, I noticed a set of patterns that created frustration for the community:
Lack of responses or follow-ups
Not responding will require community members to ping maintainers and create frustration. People understand when you have other priorities if priorities are communicated clearly. Make sure you respond to discussions and update progress.
Hunting for additional information
You should use issue templates to encourage people to provide all the details during its creation. You can also label issues to improve status visibility. (e.g “needs author feedback”, “needs attention”, “needs triage”, “bug”…)
Tracking and meeting delivery dates on individual items is a tedious effort. As such, avoid providing a resolution date for each item, you are setting yourself to disappoint people. Use milestones instead to convey the following information:
- The tentative date for a release.
- The scope, a.k.a. the list of issues this release addresses.
- The relative priority of issues: an issue in a milestone with a closer target date is more urgent than another one in a later milestone.
Milestones are low maintenance and easy to understand for someone who is not familiar with the repository. As both the date and the scope can change, you will have more flexibility to adjust your plans. You should provide a reason when changing plans. E.g., “we uncovered this additional thing when working on that”.
I do have a suggestion for milestones if anyone at GitHub is reading: we need to be able to link milestones between repositories: e.g., “v3 of my library depends on v7 of this library”. This will signal there is additional work we depend on before being able to ship the content of the milestone.
Maintain a safe place
“Without respect no trust can be born” Judo moral code.
Authors do not mean to disrespect anyone in most cases when they use curse language. You must take into consideration cultural differences and reading context when evaluating discussions. In 99% of cases, giving a warning on honest mistakes which solves the situation. I lock and report issues when the intention was to harm.
Thanks to all your efforts, repository activity will increase quickly and might become overwhelming. Recharging will only happen if you protect your personal time. I have disabled email notifications from GitHub and only use the notifications page. I also recommend you to fine tune your subscriptions and setting quiet hours on the mobile app.
I hope sharing my experience with the Microsoft Graph Java SDK will help you to make the most of your open-source experience. If you have other tips which are not mentioned here, please leave them in the comments!