Use a Github Action workflow to build "universal" Rust binaries that work for both MacOS chip architectures.

two realistic Apple logos in red and yellow

Issue

With MacOS's new M1 chip architecture, there are now two build targets for MacOS: x86_64-apple-darwin and aarch64-apple-darwin. Rather than ask our users to identify their chip architecture on a product installation page, I prefer to have one binary that works for all installation targets.

screenshot of a MacbookPro 'About this Mac' page

Apple's happy path uses XCode, but detest using a vendor-specific GUI to ship software on each release. That leaves us with lipo, which ships with MacOS. MacOS Runners are expensive, but it's a good start.

Along the way, we need to notarize the binary with Apple so our users don't get a scary installation popup warning that our application might be malware.

Solution

This Github Workflow creates two binaries, x86_64-apple-darwin and aarch64-apple-darwin and "smushes them together" with lipo. Then it signs and notarizes the resulting binary and bundles it into a .app that's ready to be installed. There are some other goodies in here, such as a minor SemVer bump and some build caching to speed things up.

Kudos

Credit to Federico Terzi's blog post on signing and notarizing MacOS apps with GitHub Actions.