Release Go CLI Application using GoReleaser

Photo by Richy Great on Unsplash

Release Go CLI Application using GoReleaser

Simplify Your Go CLI Releases: The Power of GoReleaser

Setup GoReleaser

First of all install GoReleaser cli tools on my machine using homebrew. if you're not using homebrew you can check all available installation method here.

After installing GoReleaser then I initialize goreleaser using command goreleaser init. It will added /dist directory to .gitignore and add .goreleaser.yaml for configuring GoReleaser.

Configuring GoReleaser

Because of my main.go is not in a root directory, I have to modify generated .goreleaser.yaml in a build block to add my main.go location

...
builds:
  - main: ./cmd/cli/
    env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin
...

Try build snapshot version

To validate GoReleaser configuration I try to build a snapshot version using GoReleaser using command goreleaser build --snapshot --clean. --clean arguments is used to clean distribution directory if it is exists. It will build a binearies for windows, macOS(darwin), and linux.

Create tag for release

GoReleaser use the latest Git tag of our repository. In order to use it properly we need to annotate commit tag for release. It is also common practices when managing release.

Signing Application

GoReleaser provide configuration using sign binary file. Then i configure my .goreleaser.yaml by adding following configuration.

...
signs:
  - artifacts: checksum
    cmd: gpg2
    args: 
      - "--batch"
      - "-u"
      - "{{ .Env.GPG_FINGERPRINT }}"
      - "--output"
      - "${signature}"
      - "--detach-sign"
      - "${artifact}"
...

Currently GPG is not installed on my machine then i installed using homebrew `brew install gnupg. Or you can download the installer from GnuPG.

Generate GPG Key

gpg --full-generate-key

Export the GPG private key as an ASCII armored version to your clipboard

gpg --armor --export-secret-key <email> | pbcopy

Setup github workflow to automate release process

Lucky me. GoReleaser have a great documentation to use it on CI/CD.

Here's my github workflow configuration:

name: Release

on:
  push:
    tags:
      - "*"
permissions:
  contents: write

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-deep: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
      - name: Import GPG Key
        id: import_gpg
        uses: crazy-max/ghaction-import-gpg@v6
        with:
          gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
          passphrase: ${{ secrets.GPG_PASSPHRASE }}
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v6
        with:
          args: "release --clean"
        env:
          GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
          GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}

Workflow is executed whenever any tags is pushed to repository.

Conclusions

GoRelease is helps me to release my cli application to Github release.

References