From 98bdc477463bd40c00d71fb7da577b5f8ff6fbf4 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 1 Mar 2026 00:10:36 -0700 Subject: [PATCH] feat(monorel): validate existing .goreleaser.yaml instead of diffing content Replace the exact-content comparison with yamlLooksCorrect(), which checks three semantic markers: - -X main.version={{.Env.VERSION}} present (version injection) - _{{ .Env.VERSION }}_ present for every binary (archive naming) - {{ .ProjectName }} / {{.ProjectName}} absent (not a stock template) If the file passes all checks it is left completely untouched, preserving any compatible local edits. Only files that fail a check are regenerated. --- tools/monorel/main.go | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tools/monorel/main.go b/tools/monorel/main.go index 4e807ce..f196155 100644 --- a/tools/monorel/main.go +++ b/tools/monorel/main.go @@ -317,7 +317,7 @@ func initModuleGroup(group *moduleGroup, dryRun bool) { yamlPath := filepath.Join(modRoot, ".goreleaser.yaml") existing, readErr := os.ReadFile(yamlPath) isNewFile := readErr != nil - isChanged := isNewFile || string(existing) != yamlContent + isChanged := isNewFile || !yamlLooksCorrect(string(existing), bins) if dryRun { if isChanged { fmt.Fprintf(os.Stderr, "[dry-run] would write %s\n", yamlPath) @@ -966,9 +966,10 @@ func processModule(group *moduleGroup, relPath string) { yamlPath := filepath.Join(modRoot, ".goreleaser.yaml") existing, readErr := os.ReadFile(yamlPath) isNewFile := readErr != nil - isChanged := isNewFile || string(existing) != yamlContent + isChanged := isNewFile || !yamlLooksCorrect(string(existing), bins) if !isNewFile && isChanged { - // Warn if a stock {{ .ProjectName }} template is in use. + // Warn if a stock {{ .ProjectName }} template is in use (one of the + // reasons yamlLooksCorrect may have returned false). hasProjectName := strings.Contains(string(existing), "{{ .ProjectName }}") || strings.Contains(string(existing), "{{.ProjectName}}") gitInfo, gitErr := os.Stat(filepath.Join(modRoot, ".git")) @@ -1243,6 +1244,31 @@ func goreleaserYAML(projectName string, bins []binary) string { return b.String() } +// yamlLooksCorrect returns true when content appears to be a valid monorel- +// generated (or compatible) .goreleaser.yaml for the given binaries: +// +// - `-X main.version={{.Env.VERSION}}` is present (version injection) +// - `_{{ .Env.VERSION }}_` is present for every binary (archive naming) +// - `{{ .ProjectName }}` / `{{.ProjectName}}` are absent (stock goreleaser template) +// +// When these hold the file is left untouched so that compatible local edits +// (e.g. adding extra build targets or tweaking flags) are preserved. +func yamlLooksCorrect(content string, bins []binary) bool { + if !strings.Contains(content, "-X main.version={{.Env.VERSION}}") { + return false + } + for _, bin := range bins { + if !strings.Contains(content, bin.name+"_{{ .Env.VERSION }}_") { + return false + } + } + if strings.Contains(content, "{{ .ProjectName }}") || + strings.Contains(content, "{{.ProjectName}}") { + return false + } + return true +} + // ── Release script generation ────────────────────────────────────────────── // printModuleScript emits one module's release steps to stdout.