Contribution experience report: Thunderbird

Welcome to my seventh contribution experience report. I have done others for:

My motivation to contribute

Sometimes I forget to join meetings. Generally without being able to offer any good excuse for it. But three years ago I skipped one and I had a genuine reason: it was Thunderbird’s fault! It failed to import an invite in my calendar. When I tried to import it again, it gave me a cryptic error: “Processing message failed. Status: 80004005.” After some digging I found out that it was because the UID field of the ICS file contained some special characters. Frustrating!

First contact with the project

Back then, I clearly had the urge to do something about it, since I took the time to write a bug report about it and even try to contribute a patch. But I somehow couldn’t get Thunderbird to compile on my machine. It was all really heavy and complicated, so I gave up. The patch was left to rot as an attachment to the Bugzilla ticket.

Three years later, someone commented on the ticket that they had the same problem, and this comment landed in my inbox (in Thunderbird, of course). I was pleased to see that I was not alone. Someone else indirectly confirmed that my sloppiness with meetings isn’t entirely my own fault, what a relief! I wanted to try contributing again.

Development environment

So I searched for “thunderbird contribute” online and found this beautiful landing page. I think it does the job very well, offering many ways to contribute without being overwhelming either. From there it was easy to find my way to the Linux build prerequisites.

This felt so much better than last time I tried! I mean, you still need a lot of resources to build Thunderbird, but they have spent time working on a bootstrap.py script which takes care of setting up just about everything for you. And it tells you what it does and asks you for permission when necessary, as far as I can remember.

wget https://hg.mozilla.org/comm-central/raw-file/tip/python/rocboot/bin/bootstrap.py
chmod +x bootstrap.py
./bootstrap.py

I did run into an error at some point, so it wasn’t completely flawless:

*** failed to set up extension firefoxtree: b'wrapfunction target name should be `str`, not `bytes`'
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/mercurial/extensions.py", line 268, in _runextsetup
    extsetup(ui)
  File "/home/antonin/.mozbuild/version-control-tools/hgext/firefoxtree/__init__.py", line 664, in extsetup
    extensions.wrapfunction(hg, b'_peerorrepo', peerorrepo)
  File "/usr/lib/python3/dist-packages/mercurial/extensions.py", line 678, in wrapfunction
    raise TypeError(msg)
TypeError: b'wrapfunction target name should be `str`, not `bytes`'

But I could fix this by removing a .mozbuild directory likely left over from my previous attempt 3 years ago. After a compilation time of about 30 minutes, I had a freshly baked Thunderbird (I say baked because of the heat generated by my processor over the course of the build time).

Anyway, congrats to the Thunderbird team for improving those set-up instructions, it made a real difference to me.

Finding my way into the code base

Since I had crafted a patch three years earlier, I luckily didn’t need to figure it all out from scratch. The changes were in a .jsm file, which contains what looks a lot like Javascript. I applied my patch and thankfully the new compilation round only took a few seconds, so I could easily confirm that my patch indeed solved the issue. So let’s try and get this accepted upstream!

Testing infrastructure

Expecting that a test would be required to merge such a change, I tried to figure out how the code I changed was currently tested, by grepping for various class or method names from the class I modified. This led me to a related test class, where I could duplicate an existing test case and adapt it to my needs.

The tests came under various flavors (cached and uncached) and I didn’t really know what it meant. I went for making an uncached one. It felt reassuring to check that the test case failed without my fix and passed with it.

For this process I was very lucky to discover that I could run single test files with:

./mach xpcshell-test comm/calendar/test/unit/providers/test_caldavCalendar_uncached.js

There are so many projects where it’s actually painful or even borderline impossible to run a single test case from the command line (hello multi-module Maven projects!), it really bugs me. It’s such a basic need! I am grateful I didn’t have to set up a full-blown IDE with support for JSM files (whatever that looks like) to get the privilege of running a single test case. Good job again, Thunderbird team!

Reviewing experience

To get this reviewed, I somehow needed to submit this to Phabricator, for which I first needed to setup 2FA. Fine.

The process of submitting the patch via Mercurial didn’t feel familiar at all, but it was well documented. The hardest part was to figure out who to pick as a reviewer, as they have to be mentioned in the commit message. The documentation even states it: “It can be pretty tricky to figure out who to ask for a review”.

I tried going to https://wiki.mozilla.org/Modules/Calendar. Back then it had a list of people, but only with full names and not usernames, which were used in commit messages. I had to dig through the commit log to try to manually match those names to commit identities and then reviewer ids (which are different things!). After a lot of guesswork I settled on requesting a review from “darktrojan”. That process felt really unnecessarily complicated. But by now, there is a new page listing code owners with full names and usernames together! Amazing!

To do the actual submission, I tried:

$ moz-phab submit
Failed to find draft commits to submit

The failure was due to the fact that I was in the Firefox repository (yes, Thunderbird is built by cloning the Firefox repository and changing some config files to transmutate a fox into a bird). Doing it from the comm/ subfolder worked.

I enjoyed the fact that I could do hg commit --amend to fix my mistakes, and that running moz-phab submit again detected the changes and updated the patch accordingly. It felt like forgiving tooling.

The time to first review was just 2 hours, with friendly feedback requesting sensible changes. Once my patch “landed”, as they say, they quickly took the initiative to backport it on a release branch, so my changes got released pretty quickly (and I think it was even an LTS release). Very lucky me!

Code formatting

This is perhaps the best part. I didn’t format my changes properly, but they did it for me! Why isn’t that the case more often? It’s such a waste of time to dedicate a round of review to ask the contributor to run whatever formatting tool on their side and resubmit. Nicely done, Thunderbird!

Governance and roadmap

I could find a decription of various trust levels for code contributors at Mozilla, which seems to apply to Thunderbird. It feels a bit scary but it does describe some sort of a pathway to become a trusted with merge rights, at least on a formal level. That’s a fairly basic requirement but many projects don’t even meet that standard, so I guess that’s good. Concerning the roadmap, I am vaguely familiar with their plans by following Thunderbird on Mastodon.

Would I contribute again?

Yes! Despite the scary codebase, the experience was a good one. And the impact of contributing to such a project feels undeniable to me. We need good email clients if we want to preserve what’s left of the federated nature of email, to resist against the Gmail / Office365 oligopoly.