feat(monorel): use YAML anchors to DRY up multi-binary build matrices

When a module has more than one binary, the shared build options (env,
ldflags, goos) are defined once via a YAML anchor on the first build and
merged into the rest with <<: *build_defaults.  Single-binary modules use
plain fields with no anchor overhead.

  - id: gsheet2csv          - id: gsheet2csv
    binary: gsheet2csv        binary: gsheet2csv
    env:              →       <<: &build_defaults
      - CGO_ENABLED=0           env:
    goos:                         - CGO_ENABLED=0
      - aix                     goos:
      - ...                       - aix
  - id: gsheet2env               - ...
    binary: gsheet2env      - id: gsheet2env
    env:                      binary: gsheet2env
      - CGO_ENABLED=0           <<: *build_defaults
    goos: ...

The commented-out ios stubs follow the same pattern using a separate
build_defaults_ios anchor so they remain consistent when uncommented.

Also extracts defaultGoos to a package-level var to avoid repetition.
This commit is contained in:
AJ ONeal 2026-03-01 01:50:55 -07:00
parent 445a6e9c07
commit 8405be04ad
No known key found for this signature in database

View File

@ -44,6 +44,14 @@ import (
// Adjust this slice if you ever need to search across repository boundaries. // Adjust this slice if you ever need to search across repository boundaries.
var stopMarkers = []string{".git"} var stopMarkers = []string{".git"}
// defaultGoos is the CGO_ENABLED=0 build matrix used in generated .goreleaser.yaml files.
// Platforms requiring CGO or special toolchains (ios, android) are emitted as comments.
var defaultGoos = []string{
"aix", "darwin", "dragonfly", "freebsd", "illumos",
"js", "linux", "netbsd", "openbsd", "plan9",
"solaris", "wasip1", "windows",
}
// ── Types ────────────────────────────────────────────────────────────────── // ── Types ──────────────────────────────────────────────────────────────────
// binary describes one Go main package to build and release. // binary describes one Go main package to build and release.
@ -1241,34 +1249,52 @@ func goreleaserYAML(projectName string, bins []binary) string {
w(" # you may remove this if you don't need go generate\n") w(" # you may remove this if you don't need go generate\n")
w(" - go generate ./...\n") w(" - go generate ./...\n")
// When multiple binaries share a module, define the common build options
// once with a YAML anchor on the first build and merge them into the rest.
// Single-binary modules use plain fields (no anchor overhead).
multibin := len(bins) > 1
w("\nbuilds:\n") w("\nbuilds:\n")
for _, bin := range bins { for i, bin := range bins {
wf(" - id: %s\n", bin.name) wf(" - id: %s\n", bin.name)
wf(" binary: %s\n", bin.name) wf(" binary: %s\n", bin.name)
if bin.mainPath != "." { if bin.mainPath != "." {
wf(" main: %s\n", bin.mainPath) wf(" main: %s\n", bin.mainPath)
} }
w(" env:\n - CGO_ENABLED=0\n")
w(" ldflags:\n") // Shared build options — defined once via anchor, merged into the rest.
w(" - -s -w" + switch {
" -X main.version={{.Env.VERSION}}" + case !multibin:
" -X main.commit={{.Commit}}" + // Single binary: plain fields.
" -X main.date={{.Date}}" + w(" env:\n - CGO_ENABLED=0\n")
" -X main.builtBy=goreleaser\n") w(" ldflags:\n")
w(" goos:\n") w(" - -s -w" +
w(" - aix\n") " -X main.version={{.Env.VERSION}}" +
w(" - darwin\n") " -X main.commit={{.Commit}}" +
w(" - dragonfly\n") " -X main.date={{.Date}}" +
w(" - freebsd\n") " -X main.builtBy=goreleaser\n")
w(" - illumos\n") w(" goos:\n")
w(" - js\n") for _, g := range defaultGoos {
w(" - linux\n") wf(" - %s\n", g)
w(" - netbsd\n") }
w(" - openbsd\n") case i == 0:
w(" - plan9\n") // First of multiple binaries: define the anchor.
w(" - solaris\n") w(" <<: &build_defaults\n")
w(" - wasip1\n") w(" env:\n - CGO_ENABLED=0\n")
w(" - windows\n") w(" ldflags:\n")
w(" - -s -w" +
" -X main.version={{.Env.VERSION}}" +
" -X main.commit={{.Commit}}" +
" -X main.date={{.Date}}" +
" -X main.builtBy=goreleaser\n")
w(" goos:\n")
for _, g := range defaultGoos {
wf(" - %s\n", g)
}
default:
// Subsequent binaries: reference the anchor.
w(" <<: *build_defaults\n")
}
// iOS requires CGO and Xcode toolchain — commented out by default. // iOS requires CGO and Xcode toolchain — commented out by default.
wf(" # iOS requires CGO_ENABLED=1 and the Xcode toolchain.\n") wf(" # iOS requires CGO_ENABLED=1 and the Xcode toolchain.\n")
@ -1277,7 +1303,14 @@ func goreleaserYAML(projectName string, bins []binary) string {
if bin.mainPath != "." { if bin.mainPath != "." {
wf(" # main: %s\n", bin.mainPath) wf(" # main: %s\n", bin.mainPath)
} }
w(" # env:\n # - CGO_ENABLED=1\n") if multibin && i == 0 {
w(" # <<: &build_defaults_ios\n")
w(" # env:\n # - CGO_ENABLED=1\n")
} else if multibin {
w(" # <<: *build_defaults_ios\n")
} else {
w(" # env:\n # - CGO_ENABLED=1\n")
}
w(" # goos:\n # - ios\n") w(" # goos:\n # - ios\n")
// Android: CGO_ENABLED=0 supports arm64 only; full CGO requires the NDK. // Android: CGO_ENABLED=0 supports arm64 only; full CGO requires the NDK.