Putting Some Sparkle On It ✨

I've been releasing about one Lagrange build per week for the past 12 months, but save for Homebrew, Flathub, and TestFlight there hasn't been any way to conveniently upgrade the app. (Unless your OS/distro happens to have freshly updated packages for Lagrange, but that's pretty exceptional.) Each update has been a manual download. It's time to change that.

Unfortunately, self-updating an app is a very platform-dependent affair, so I can't do it on every operating system. Instead, I'm going to rely on the popular Sparkle framework on macOS and its Windows counterpart, WinSparkle. This should cover the two platforms that most sorely need the feature. On Linux (without Flatpak) and *BSD, if you want to stay on the bleeding edge you'll need to roll your own solution. To make things a little easier, I've set up a new RSS feed of releases from the git.skyjake.fi repository.

Self-updating is something I've been planning to figure out and do for quite a while, but something else has always been popping up. Finally today, I decided to get it over with.

I spent the day putting together a series of scripts that produce Appcast feeds. These are RSS feeds that contain download URLs, signatures, and a change log for each new version. Thankfully, Sparkle comes with a couple of command line tools for generating basic appcasts, but of course things weren't that simple. For starters, the canonical source of release notes is the gemtext file "res/about/version.gmi" that is used inside the app as-is. I had to begin by making a script to parse it and produce Markdown/HTML versions with some nice formatting for the Git repositories, Flathub AppData, and Sparkle. A little wrinkle was that some of the notes are platform-specific, so it makes no sense to include them in all feeds. I had to filter the notes based on the target platform. The output from Sparkle's appcast generator needed a little fixing, too: the signature hashes weren't being included for some reason, and the download URLs all needed to be replaced because the version number needs to be part of the path as well as the file name. So I wrote another script that fixes these details in the feed.

I'm using two scripts to do a release: a "gather" script that collects built binaries from machines around the house, and a "teaup" script that pushes them to Gitea along with the release. The appcast generation is now part of "gather". It makes three separate feeds: Intel Mac, arm64 Mac, and Windows. "teaup" then copies these to etc.skyjake.fi for access via HTTPS. For good measure, I also included automatic mirroring of the release to GitHub, which I've been doing manually until now.

All in all, this should reduce the need for manual work quite a bit when making releases. As the app has matured and gotten more complex, the amount of effort to make a release has also been growing: there are simply more bits and bobs to take care of. Once the automation is working, it should streamline things nicely.

Sparkle will be the second HTTPS-based feature in Lagrange. The other is the LibreTranslate language translation service. In both cases, the hardcoded destination of the HTTPS requests is my skyjake.fi server.

The automatic update checks will commence in v1.9 and are opt-in: Sparkle asks for your permission before enabling the checking.

📅 2021-11-07

🏷 Lagrange

CC-BY-SA 4.0