Spotting errors earlier in GoReleaser files

An easy first step with CUE is shown in Checking existing GoReleaser files using CUE. There, we see the happy path of using cue vet to confirm that one of our existing GoReleaser configuration files is valid. But what does it look like when one of our manually maintained configuration files isn’t valid? How does CUE help us catch errors early, before they’ve had the chance to move further downstream and waste time, resources, and focus?

This guide shows what happens when the cue vet command finds a problem with a GoReleaser configuration file using a curated module from the CUE Central Registry, and how it highlights the data we need to fix.

Login to the Central Registry

$ cue login # only during beta

The Central Registry requires authentication while it’s in beta testing, so we need to login before using its modules.

A broken configuration file

This example is adapted from the goreleaser/example repository – but the deliberate errors introduced here aren’t part of the original file, of course!

# filepath: .goreleaser.yml

project_name: example
builds:
  - goos: [ linux, windows, darwin ]
    goarch: [ amd64, arm64 ]
    env:
      - CGO_ENABLED=0
docker:
  - dockerfile: Dockerfile
    image_templates:
      - ghcr.io/goreleaser/example:{{ .Version }}
    build_flag_templates:
      - --label=org.opencontainers.image.title={{ .ProjectName }}
      - --label=org.opencontainers.image.url=https://github.com/goreleaser/example
nfpms:
  - formats: [ deb, rpm, apk ]
    homepage: https://github.com/caarlos0/tasktimer
    maintainer: Carlos A Becker <root@carlosbecker.dev>
    description: Sample project.
    license: MIT

Validate the configuration file

We use cue vet to validate .goreleaser.yml against the goreleaser package’s #Project definition:

$ cue vet -c -d '#Project' cue.dev/x/goreleaser@latest .goreleaser.yml
docker: field not allowed:
    .goreleaser.yml:7:1

The cue vet command shows us the error (docker: field not allowed)

Fix the configuration file

From the cue vet error message we know that the docker field isn’t permitted. We check the GoReleaser documentation (or perhaps we review the most recent change made to the configuration file in our version control system) and discover that the field should actually be named dockers.

We fix our configuration file by updating the highlighted line, so that the file becomes:

# filepath: .goreleaser.yml

project_name: example
builds:
  - goos: [ linux, windows, darwin ]
    goarch: [ amd64, arm64 ]
    env:
      - CGO_ENABLED=0
dockers:
  - dockerfile: Dockerfile
    image_templates:
      - ghcr.io/goreleaser/example:{{ .Version }}
    build_flag_templates:
      - --label=org.opencontainers.image.title={{ .ProjectName }}
      - --label=org.opencontainers.image.url=https://github.com/goreleaser/example
nfpms:
  - formats: [ deb, rpm, apk ]
    homepage: https://github.com/caarlos0/tasktimer
    maintainer: Carlos A Becker <root@carlosbecker.dev>
    description: Sample project.
    license: MIT

Re-validate the configuration file

$ cue vet -c -d '#Project' cue.dev/x/goreleaser@latest .goreleaser.yml

We know that the curated module has validated our file this time because cue vet doesn’t display any errors.

Next steps

Validating your existing configuration files with CUE can help make development and deployments safer, but defining those same files in CUE lets you build on its first-class templating, referencing, and policy features. Take the first step with Getting started with GoReleaser + CUE