When it comes to rolling out new software updates, the SourceTree team is always looking to deliver a better experience to users with minimal disruption. In the past we announced a beta program for SourceTree, detailed how we deliver releases, and now we’re modifying how we roll updates out to users. By progressively rolling out updates we aim to deliver new features and functionality to users in a more robust fashion.
What’s the plan?
Where we used to roll a new update to all users on day one, we’re now progressively rolling out updates to users. This staged approach offers the SourceTree team granularity during a release, allowing us to scrutinize each update for bugs and showstoppers before it hits critical mass.
The general flow of a build through our release pipeline is common across both Windows and Mac platforms. The below diagram – using our upcoming 2.4 macOS release as an example – outlines our process and describes the granularity of our new staged rollout in more detail.
Once a release leaves beta it’s progressively rolled out to groups of users over a period of a few weeks, with time in-between for fixes to be implemented where necessary.
|Group||Percentage available||Available exclusively for|
How did we implement it?
The implementation is slightly different for Windows and macOS platforms, but aim to achieve the same goals:
- no dependency changes
- client self-assigns update group
- ability to release in stages (group 1 at 5%, group 2 at 15%, etc.)
- no impact on existing alpha/beta distribution
- minimal file duplication on server
- no need for a self-made web service
- automatable process
Having implemented Squirrel.Windows for SourceTree’s beta program, we’ve decided to move GA releases from AdvancedInstaller to Squirrel as well. Why Squirrel? We were attracted by its focus on simplicity and felt it aligned well with our goal of improving the installation process for users:
Windows apps should be as fast and as easy to install and update as apps like Google Chrome. From an app developer’s side, it should be really straightforward to create an installer for my app, and publish updates to it, without having to jump through insane hoops.
We’ve found it very easy to integrate Squirrel with our FAKE-based build process and CI. The resulting installer is much smaller, quicker to run, has a cleaner footprint, and comes with the added bonus of removing the requirement for Admin rights to install. Overall we felt the user install experience is much improved.
For progressive rollouts, Squirrel comes with built-in staged rollout functionality. SourceTree generates a release percentage for this local install; this defines which part of the release schedule the instance falls into. SourceTree will check at start up for any new updates, or the check can be manually triggered via the Tools/Options/Update tab. After each update, SourceTree will regenerate a new release percentage, ensuring a random distribution of updates.
For macOS we weren’t able to find any existing options that met our needs. But Sparkle, the update framework we’re already using, does include a number of hooks for customizing the experience, so we decided to build our own from that. In order to utilize staged updates we only need to take advantage of a single method:
Inside this method we use some randomization to choose groups; that logic is encapsulated in a thoroughly unit tested class (which we’re considering open sourcing if there’s interest). On launch, a user’s group is assigned and cached, clearing when it’s a new app version (2.3.2 → 2.4, not 75 → 76).
On the Server
What happens on the server end is largely unchanged from what we have today. We’ve added new copies of feeds and tweaked release notes so they work in concert with randomization to make staged updates possible.
- direct download and update zip files – a release is uploaded like normal, access to them is managed by feeds; no duplication necessary
- appcast (update) XML feeds – Appcast.xml stays (legacy, no further updates), AppcastAlpha.xml and AppcastBeta.xml stay the same, adds AppcastGroup0.xml through AppcastGroup5.xml
- release notes – ReleaseNotes.html stays (legacy, no further updates), ReleaseNotesAlpha.html and ReleaseNotesBeta.html stay the same, now we use version specific release notes like 2.3.2.html
Build release process
Unsurprisingly, we continue automating via Fastlane:
This former “early access” lane runs a relatively similar process as before: it takes the current version + build info and makes sure the appcast and release notes have been updated properly. If it’s already present no build is produced but the appcasts and release notes are prepared.
Iterating On Our Process
It’s been great revisiting the initial CI and deployment processes we put in place for the beta program and expanding upon them. Figuring out the path of least resistance and what options might work presented a fun challenge and our Fastlane suite is better than ever. Now that we’ve landed this important bit of infrastructure we look forward to the many successful deployments and exciting changes in SourceTree’s future!