Building multi architecture and multiplatform binaries with GoReleaser and Github Actions

github action GoReleaser multiarch multiplatform build

2 min read | by Jordi Prats

In order to build binaries for multiple architectures, we can use GoReleaser together with Github Actions so that they get built automatically when we create a release.

We are going to use as an example how binaries are built for kubectl's searchrule plugin. First we need to configure GoReleaser using the .goreleaser.yaml file:

project_name: kubectl-searchrule
builds:
  - goos:
      - linux
      - windows
      - darwin
    goarch:
      - amd64
      - arm64
    main: ./rule-lookup.go
    binary: kubectl-searchrule
    env:
      - CGO_ENABLED=0
      - >-
        {{- if eq .Os "darwin" }}
          {{- if eq .Arch "amd64"}}CC=o64-clang{{- end }}
          {{- if eq .Arch "arm64"}}CC=aarch64-apple-darwin20.2-clang{{- end }}
        {{- end }}
        {{- if eq .Os "windows" }}
          {{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{- end }}
        {{- end }}
        {{- if eq .Os "linux" }}
          {{- if eq .Arch "arm64" }}CC=aarch64-linux-gnu-gcc{{- end }}
        {{- end }}
    ignore:
      - goos: darwin
        goarch: 386
      - goos: linux
        goarch: arm
        goarm: 7
      - goarm: mips64
      - gomips: hardfloat
      - goamd64: v4

While this file instructs GoReleaser what to do, we'll need to create a Github Action workflow to tell it when to do it.

Using the folowing file in .github/workflows/releaser.yaml we are telling it how to build it using GoReleaser when a tag is pushed that matches the configured regex:

name: Release CLI

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+'

jobs:
  release-cli:
    name: Release CLI
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: 1.19.x

      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v4
        with:
          distribution: goreleaser
          version: latest
          args: -f .goreleaser.yaml release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload assets
        uses: actions/upload-artifact@v3
        with:
          name: kubectl-searchrule
          path: dist/*
          if-no-files-found: error

Since we are using the actions/upload-artifact action, the resulting files will be uploaded as an asset in the releases page.


Posted on 08/08/2023