Package and ship

Plan publishing and updates

Publish immutable artifacts, test each supported platform, and choose an update path before users depend on the app.

A release isn’t just a file. It’s an upgrade path from the version your users already have. The artifact, its metadata, its signature, and your update policy are one unit. If one is wrong, the others don’t matter.

Test every target

Before publishing, build and test on every operating system and architecture you support. For Desktop Notes that’s macOS, Intel and Apple Silicon, and Windows. On each one: install over the previous version, launch from a clean user account, create and export a note, restart, uninstall. Every release. It’s boring, and it’s where you find the bug that would have hit every user.

Publish immutable artifacts

Each artifact gets published with its version, platform, architecture, and a checksum. Desktop Notes-1.0.1-darwin-arm64.zip plus its SHA-256. Once published, never replace it. If it’s broken, publish 1.0.2.

Keep old releases available. When a user reports “it broke after the update”, you need the previous build to reproduce and compare.

Forge publishers, like the GitHub one, upload artifacts for you. That’s all they do. Uploading a file doesn’t make it safely updateable.

Automatic updates

Electron ships an autoUpdater module that works on macOS and Windows. On Linux, updates normally go through the package manager or another platform-specific route.

Before turning it on, you need:

  • immutable versioned artifacts with compatible update metadata
  • HTTPS from an update source you control
  • signed applications, because the macOS updater refuses unsigned apps
  • a test that upgrades from the previous supported version
  • a response plan for a bad release
  • clear behavior for the user when download, verification, or installation fails

That’s a lot. My advice is to start with manual downloads. Add automatic updates only once signed releases and upgrade tests are routine. An updater that pushes a broken build to everyone at once is worse than no updater.

Two exercises

First, update from 1.0.0 to 1.0.1 and confirm the notes are still there. Same appBundleId, same userData folder, same data. If the notes vanish, the identity changed somewhere.

Second, point the update source at a dead URL and confirm the installed app still starts and still has its data. An app that won’t launch because the update check failed has its priorities backwards.

Rollback is a release

Don’t rely on “latest” as a rollback strategy. Once a broken update is installed, clients won’t downgrade on their own. You need a fixed release with a higher version number, tested, or a documented manual recovery path. Decide which before you need it.

Write the release checklist now, while it’s fresh: version bump, tests, package, sign, malware scan where applicable, upload, download and verify, announce.

Lesson completed