DEV Community

Justin Patriquin
Justin Patriquin

Posted on

Releasing Rust Binaries with GitHub Actions - Part 2

In this part I'm going to go over how I ended up releasing binaries for MacOS and Windows MSVC.

Cross Compilation

Ideally, we could use the cross compilation to build all of the binaries on the same runner type in GitHub Actions. This allows you to build binaries on one platform (e.g. Linux x86_64) that can then run on other platforms. Being able to do this would make our GitHub Action easier to write and maintain. But, there was issue I ran into that prevented cross compilation with Nitrogen from being able to build for different platforms.

The AWS Rust library we were using as a dependency depended on a cryptography library called ring. This library leverages C and assembly code to implement its cryptographic primitives. Unfortunately, cross compiling when C is involved can add complexity to the build process. While it might've been possible to overcome these issues I decided that it wasn't worth digging into more.

Implementation

Fortunately, the GitHub Action implementation I ended up going with wasn't that complicated. I just had to use separate runners. One for MacOS Arm and one for Windows MSVC. Here are the steps I had to do for each release type.

Build the binary

For Windows it was as simple as running a release build:

$ cargo build --release
Enter fullscreen mode Exit fullscreen mode

The MacOS Arm build is just slightly more complex because the GitHub Actions runner isn't running on Arm architecture so we have to add the separate toolchain and target.

$ rustup toolchain install stable-aarch64-apple-darwin
$ rustup target add aarch64-apple-darwin
$ cargo build --release --target aarch64-apple-darwin
Enter fullscreen mode Exit fullscreen mode

Compress the binary

We use tar to compress the binaries:

$ tar --directory=target/release -cf archive.tar.gz nitrogen.exe
Enter fullscreen mode Exit fullscreen mode

The MacOS tar command differs slightly because of the cross compilation required to build for Arm.

$ tar --directory=target/aarch64-apple-darwin/release -cf archive.tar.gz nitrogen
Enter fullscreen mode Exit fullscreen mode

Upload the artifact

Since the release is already created we need to query the release ID and then upload the archived binary to the release using the GitHub API.

The Windows and MacOS version of these differs slightly because Windows has to run in the PowerShell where MacOS would be using bash. You can select the bash shell in the Windows runner but I had an issue with this where it couldn't find the gh command line tool.

Windows:

$ $id = gh api -H "Accept: application/vnd.github+json" /repos/capeprivacy/nitrogen/releases/tags/${{ github.ref_name }} --jq .id
Enter fullscreen mode Exit fullscreen mode

Note: cURL command is edited here for brevity see here for the full command

$ curl -X POST --data-binary "@archive.tar.gz" "https://uploads.github.com/repos/capeprivacy/nitrogen/releases/$id/assets?name=nitrogen_${{ github.ref_name }}_x86_64-pc-windows-msvc.tar.gz"
Enter fullscreen mode Exit fullscreen mode

MacOS:

$ id=$(gh api -H "Accept: application/vnd.github+json" /repos/capeprivacy/nitrogen/releases/tags/${{ github.ref_name }} --jq .id)
Enter fullscreen mode Exit fullscreen mode

Note: cURL command is edited here for brevity see here for the full command

$ curl -X POST --data-binary @"archive.tar.gz" "https://uploads.github.com/repos/capeprivacy/nitrogen/releases/$id/assets?name=nitrogen_${{ github.ref_name }}_aarch64-apple-darwin.tar.gz"
Enter fullscreen mode Exit fullscreen mode

Check out the full implementation here.

This was an interesting problem to work on and I learned a lot. Let me know if you have any questions!

Thanks for reading! If Nitrogen sounds cool to you check it out and give it a star here, check out the quick installation guide here and come see what's going on on Discord.

Top comments (0)