Skip to content

build-go.yml ​

Compiles a Go project across its whole release matrix with GoReleaser, and publishes none of it.

This is the pull-request half of the Go pipeline. Cross-compilation failures are host-independent and invisible from a laptop — a build constraint that resolves on darwin and not on windows compiles clean for everybody who never builds for windows — so the cheapest place to find one is the pull request that introduced it, rather than the tag that ships it.

For the publishing half, see release-go.yml.

Inputs ​

InputTypeDescriptionRequiredDefault
GO_VERSIONstringGo version to use. Empty reads it from go.modNo""
WORKING_DIRECTORYstringDirectory holding the module and its GoReleaser configurationNo"."
CONFIGstringPath to the GoReleaser configuration. Empty lets GoReleaser find its ownNo""
GORELEASER_VERSIONstringGoReleaser version to installNo"~> v2"
DISTRIBUTIONstringGoReleaser distribution (goreleaser, goreleaser-pro)No"goreleaser"
PACKAGEbooleanProduce the full distribution (archives, checksums) instead of bare binariesNofalse
SINGLE_TARGETbooleanBuild only for the runner's platform. Rejected with PACKAGENofalse
IDSstringBuild ids to build, comma-separated. Rejected with PACKAGENo""
ARGSstringExtra arguments appended to the GoReleaser invocationNo""
ARTIFACT_NAMEstringArtifact name for the built distribution. Empty uploads nothingNo""
ARTIFACT_RETENTION_DAYSnumberHow long to keep the uploaded artifactNo7
CACHEbooleanWhether to cache the module and build cachesNotrue
FETCH_DEPTHnumberCheckout depthNo1
RUNS_ONstringRunner labels as JSON arrayNo'["ubuntu-24.04"]'

Secrets ​

SecretDescriptionRequired
GORELEASER_KEYLicense key for goreleaser-proNo

Permissions ​

ScopeAccessDescription
contentsreadRead the checked-out sources

Notes ​

  • contents: read is the point of this workflow existing separately. Everything here runs under --snapshot and publishes nothing, so a caller can run it on a pull request without granting a release-capable token to a job a pull request starts. Keeping one workflow with a "don't publish" switch would have forced contents: write on every caller, including that one.
  • PACKAGE chooses between two GoReleaser commands, not between two destinations. Off runs goreleaser build, GoReleaser's own analogue of go build — binaries and nothing else. On runs goreleaser release --snapshot, which is the only way to get archives and the checksum file. Both publish nothing, and both stamp a snapshot version.
  • SINGLE_TARGET and IDS are refused with PACKAGE rather than ignored. Neither flag exists on goreleaser release, so honouring them silently would let a caller read a green run as having built one target when the whole matrix was built.
  • No credentials reach the checkout. GoReleaser reads the working tree and the local object database here and writes only to dist/.
  • The configuration is checked first. A .goreleaser.yaml that is invalid in a way GoReleaser only notices at publish time is best found on the pull request that introduced it, where nothing is at stake.
  • FETCH_DEPTH is shallow by default, unlike release-go.yml. No changelog is generated and the stamped version is discarded with the run, so the tag history is history this would only pay for.

Usage ​

Compile check on every pull request ​

yaml
name: CI

on:
  pull_request:
    branches:
    - "**"

jobs:
  build:
    uses: this-is-tobi/github-workflows/.github/workflows/build-go.yml@v0
    permissions:
      contents: read

Verifying the packaging pipeline, not just the compile ​

PACKAGE: true runs the archiving, checksumming and SBOM steps that a plain compile never reaches — the ones that break when an archive gains a file that does not exist, or when a hook is added that only runs on the release path.

yaml
jobs:
  package:
    uses: this-is-tobi/github-workflows/.github/workflows/build-go.yml@v0
    permissions:
      contents: read
    with:
      PACKAGE: true
      ARTIFACT_NAME: dist-preview

These archives are not release assets. --snapshot stamps a derived version rather than a tagged one — myapp_0.0.1-next_linux_amd64.tar.gz — and setting GORELEASER_CURRENT_TAG does not change that, because snapshot mode ignores it. Upload them to read, not to hand out. To attach real assets to a release, use release-go.yml, which runs on the tag and stamps it.

A fast check on the runner's platform only ​

Worth it where the matrix is large and a separate job already covers the other targets — and worth understanding as a reduction in what the job checks.

yaml
jobs:
  build:
    uses: this-is-tobi/github-workflows/.github/workflows/build-go.yml@v0
    permissions:
      contents: read
    with:
      SINGLE_TARGET: true

A module in a subdirectory ​

yaml
jobs:
  build:
    uses: this-is-tobi/github-workflows/.github/workflows/build-go.yml@v0
    permissions:
      contents: read
    with:
      WORKING_DIRECTORY: cmd/tool
      CONFIG: .goreleaser.yaml