Skip to content
Latchkey

CI/CD for a Go CLI Tool with GitHub Actions

Test, cross-compile, and release your Go CLI for every platform with GoReleaser.

A Go CLI ships as cross-compiled binaries for several OS and architecture pairs. GoReleaser automates the build matrix, archives, checksums, and the GitHub Release. This recipe tests on PRs and releases on tags.

What the pipeline does

  • set up Go with module caching
  • vet and lint
  • run tests
  • cross-compile with GoReleaser on a tag
  • publish archives and checksums to a Release

The workflow

GoReleaser reads .goreleaser.yml for the build matrix and archive config. It runs only on tags and uses GITHUB_TOKEN to create the release.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'
          cache: true
      - run: go vet ./...
      - run: go test ./...
  release:
    needs: test
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'
      - uses: goreleaser/goreleaser-action@v6
        with:
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Caching and speed

setup-go caches modules and build output for the test job. The release job cross-compiles for many targets, which is CPU-heavy; cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) cut release time and auto-retry transient module proxy failures.

Deploying

GoReleaser attaches per-platform archives and a checksums file to the GitHub Release, and can also update a Homebrew tap, push a Docker image, or publish to a Scoop bucket. Users install via the release, brew, or go install.

Key takeaways

  • GoReleaser automates the cross-compile matrix and release.
  • Set fetch-depth: 0 so GoReleaser sees tags and changelog.
  • It can also update Homebrew taps and push Docker images.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →