bitcrowd has been developing and maintaining an open source browser extension since 2015 - Tickety-Tick! Within our fleet of open source projects, the browser extension has always been a special breed. It is more of a niche technology, not something we develop every day, and generally an area of web development which feels a bit more wild west compared to others.
With the lack of best practises - even though Mozilla and Chrome are continuously working on better documentation of the topic - there wasnʼt an obvious way to “deploy” a browser extension and make use of automation for it. So hereʼs our journey on how to release browser extensions like itʼs 1999. Maybe people can draw inspiration from our approach for their own niche web technology situation.
Problem
Tickety-Tick is a browser extension for naming Git branches and commit messages, a classic “developersʼ little helper” kind of tool (check it out if you havenʼt already). Pretty much from its early days on, itʼs been available for Firefox, Chrome, Safari and Opera. Actually making it available and releasing a new version to its users however, used to be a tedious manual process. The developer assigned with the task had to:
- 🧑💻 Check out and run the latest version of the code on their machine.
- 🏷️ Bump the version number, add a Git tag and prepare a pull request for it.
- ✅ Merge the pull request and run automated checks on the soon to be released version.
- 👷♀️Build releases for Firefox and Chrome locally (one requires a directory, the other a zip file…).
- 🦊 Log into the Firefox Add-ons management backend and go through the form to upload a new version.
- 🌐 Log into the Chrome Web Store management backend and go through another form to upload a new version.
- 🐙 Draft a release with release notes on GitHub.
- 🙋 Wait for questions and/or approval on Firefox Add-Ons.
- 📬 Answer emails from the review processes on Firefox or Chrome and send/upload the source code to the reviewers.
- ⏳ Frequently come back to see whether things are done now.
- …
tl;dr: it was a time consuming process which involved bundling the extension locally and logging into different accounts to manually upload it. We tried our best to document the procedure so that anyone with access to the accounts could do it. But it was hard to keep up with the frequent UI and process changes of both platforms, so releasing Tickety-Tick always required a bit of domain knowledge and definitely a lot of time and attention. Naturally, we all shied away from this task and released only very infrequently which made us even less confident about doing it. A classic decay spiral…
We donʼt do separate releases on platforms for Safari and Opera. Safari users can manually install the release and Opera uses Chrome extensions.
History of Attempts
While the pain points of releasing our browser extension were obvious, it wasnʼt until a train ride from Berlin to Rotterdam for Euroku in 2019, that we actually made an attempt to tackle them. Still on the train, we started to hack away some automations to make releasing require less attention and prior knowledge.
The idea was to offload as many tasks as possible from the developerʼs hands to CI and automate them there.
Testing and building on CI was straightforward, and even drafting GitHub releases with a changelog was doable with the tools at hand. But we could not find any solid solutions for the biggest pain points of the release process: logging into different accounts and going through way too detailed upload forms. This was the blocker for any quick automation solution we were coming up with.
We tinkered with the idea on and off over the years and ended up with a semi-automated release process based on a dedicated set of tools and scripts. As weʼre so used to fully automated releases these days, a patchwork “semi-automated” flow may seem counterintuitive, but it turned out to be the best fit for our needs here.
Hereʼs what we came up and why:
Solution
Tinkering along we found that several rather diverse factors play into the equation for finding a suitable release process. Some come from us and are more organisational and political, some come from the fact that weʼre dealing with a browser extension here and are more technical:
-
🕵️♂️ Find reliable APIs, tools and libraries for automation.
Since we are dealing with multiple 3rd parties (Firefox, Chrome, GitHub, etc.), there no silver bullet tool to rule them all. Instead we have to find individual solutions and tools for all steps of the workflow and see how much of the manual process can be automated with them. The tools need to be specific for their task and general enough so that they can be combined to a bigger pipeline.
-
🕊️ Users need to be free to install any version.
Platforms like Firefox Add-ons or the Chrome Webstore are handy, but we still want people to manually install Tickety-Tick and have full control over which version they are running. By default, browsers auto-update themselves and their installed extensions without the ability to downgrade again. So in order to give people the options to freely up- and downgrade whenever they want, any release on GitHub should provide a running version for manual installation in all of the browsers we support.
Chrome/Opera and Safari are uncomplicated with that, but Firefox requires a special
.xpifile signed by Mozilla… -
🔐 Shipping to browsers has security impacts.
As browsers by default roll out updates to their extensions automatically without prompting or notifying the users, releasing browser extensions comes with big responsibilities. Browsers are peopleʼs main entry point to the web and they see a lot of very private information (contacts, payment data, messages, etc.). A previously trusted extension being “hacked”, taken over or shipped with hidden malicious code can do a lot of damage.
In order to not take any risks here, we prefer to not share any credentials with other parties outside of the bitcrowd organisation. If GitHub or CircleCI cannot upload to Firefox Add-ons, their potential issues are not becoming our issues.
-
🔂 Devs need the ability to monitor and replay steps.
The release submission, especially with Mozillaʼs addons-API is very brittle: processing takes a lot of time, API schemas change, responses change, error codes change, things time out, etc. There are just too many unforeseen interruptions to have this process done by a machine alone without a human monitoring it.
Uploading new extension versions on Chromeʼs Webstore and Firefox Add-ons is not idempotent and released versions cannot be overridden.
The developer observing also needs to be able to quickly abort, adjust and replay certain steps of the release pipeline. It may be that submitting to Chrome and Firefox worked fine, but drafting the release on GitHub failed for some reason. In that scenario it may not be possible to roll back the submissions any more, but we want to fix and repeat the part about GitHub.
Considering all of this lead us to a semi-automated release pipeline. A developer with maintainer access triggers the release from their local machine, monitors what is happening and can interrupt and replay when necessary. It feels more like a Capistrano deploy from back in the days than a fully automated pipeline somewhere in the cloud, but itʼs working perfectly fine and addressed all pain points without overdoing it 🎉.