Pragmatism in the real world

Using GitHub Actions to add Go binaries to a Release

Shortly after building a script to create binaries for Rodeo, my command line Flickr uploader, I realised that I could use a Github Actions workflow to run it and attach the created binaries to the Release page once I had created it.

This is what I did.

Trigger on release

A GitHub Actions workflow is a YAML file and each workflow has to be triggered. For Continuous Integration, it’s common to trigger when new PR is opened or a new commit is pushed and then run tests on the code. In this case, I want to trigger when a new release is created.

This is done in the on section:

.github/workflows/build-release-binaries.yml

name: Build Release Binaries

on:
  release:
    types:
      - created

GitHUb documents the list of events that trigger workflows and there’s many. For each event (such as release) there are a number of activity types so you can be quite selective on exactly when you want the workflow to run. In this case, I want to bulid the binaries when the release is created.

The workflow steps

I have one job which is imaginatively named build.

Set up

Each job has a set of steps and the first few are set up ones:

jobs:
  build:
    name: Build Release Assets
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Go
        uses: actions/setup-go@v1
        with:
          go-version: 1.20

      - name: Display the version of go that we have installed
        run: go version

      - name: Display the release tag
        run: echo ${{ github.event.release.tag_name }}

The workflow runs inside a container, so firstly we checkout the code and install Go. I then display the version of Go and the tag name to check that all is okay. This is mostly useful when something goes wrong.

Build the binaries

We already know how to build release binaries, so we can just run a script that does that:

      - name: Build the Rodeo executables
        run: ./build-executables.sh ${{ github.event.release.tag_name }}

      - name: List the Rodeo executables
        run: ls -l ./release

I’ve written build-executables.sh to take the version number as the first argument so that we can pass in the tag name. We then list what has been built to ensure that it is as we expect.

Upload the binaries

Finally we need to upload the binaries to the release. We use Sven-Hendrik Haase’s upload-release-action to do this.

      - name: Upload the Rodeo binaries
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.ref }}
          file: ./release/rodeo-*
          file_glob: true

A really nice feature of this action is that it can upload multiple binaries in a single step. This is incredibly useful as GitHub Actions workflows do not support looping of steps, just looping of jobs via the matrix property. Using matrix is wastegul for us as it creates a whole new container for each iteration. We do not need this as with Go one container can build all the binaries.

By setting the file_glob property to true, we can set the file property to a glob pattern and so reference all the files in the release directory.

and done

This workflow runs automatically whenever I create a new release on GitHub, automatically building the binaries against that version of the code and attaching them so that people can download them without needing to build themselves.

Automations like this are what CI/CD pipelines are for.

One thought on “Using GitHub Actions to add Go binaries to a Release

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *