Releasing Rust Binaries with GitHub Actions - Part 2
Tags: rust, github, webdev, opensource
Published: 2022-11-21 14:50:36

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](https://github.com/briansmith/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
```

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
```

### Compress the binary

We use `tar` to compress the binaries:

```
$ tar --directory=target/release -cf archive.tar.gz nitrogen.exe
```

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
```

### 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
```

**Note: cURL command is edited here for brevity see [here](https://github.com/capeprivacy/nitrogen/blob/main/.github/workflows/release.yaml#L45) 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"
```

MacOS:

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

**Note: cURL command is edited here for brevity see [here](https://github.com/capeprivacy/nitrogen/blob/main/.github/workflows/release.yaml#L65) 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"
```

Check out the full implementation [here](https://github.com/capeprivacy/nitrogen/blob/main/.github/workflows/release.yaml).

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](https://github.com/capeprivacy/nitrogen), check out the quick installation guide [here](https://www.capeprivacy.com/nitrogen?utm_source=devto&utm_medium=blog+post&utm_term=nitrogen&utm_content=blog+educational&utm_campaign=blog+ongoing) and come see what's going on on [Discord](https://discord.gg/nQW7YxUYjh).