From 1ed562f45e4805c6e4c6e6b8ec29a8b41f5182ea Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Sun, 11 Jan 2026 17:27:07 +0100 Subject: [PATCH] refactor: Replace ldflags version injection with debug.BuildInfo - Use debug.ReadBuildInfo() for version information (Go 1.18+ best practice) - Extract version from module info and VCS settings (vcs.revision, vcs.time) - Remove complex ldflags setup from Makefile and GitHub workflows - Simplify build process while maintaining all version information - Cleaner approach recommended by Go community Thanks to Gopher Slack feedback for this improvement! --- .github/workflows/release.yml | 4 +-- Makefile | 47 ++++++++++++++++------------------- cmd/soundtouch-cli/common.go | 1 + cmd/soundtouch-cli/main.go | 39 +++++++++++++++++++++++++---- scripts/post-release.md | 35 ++++++++++++++++++-------- 5 files changed, 82 insertions(+), 44 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30c9607..03db629 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -154,9 +154,9 @@ jobs: rm -f "$OUTPUT_NAME" "$OUTPUT_NAME.sha256" "$OUTPUT_NAME.sha512" go clean -cache - # Build with optimizations and version info + # Build with optimizations (using debug.BuildInfo for version info) if ! go build \ - -ldflags="-s -w -X main.version=v${{ needs.validate.outputs.version }} -X main.commit=${{ github.sha }} -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + -ldflags="-s -w" \ -o "$OUTPUT_NAME" \ ./cmd/soundtouch-cli; then echo "❌ Build failed" diff --git a/Makefile b/Makefile index f63c39d..59a82f1 100644 --- a/Makefile +++ b/Makefile @@ -21,12 +21,7 @@ SCANNER_PATH=./cmd/$(SCANNER_NAME) BUILD_DIR=./build # Version info -VERSION?=dev -BUILD_TIME=$(shell date -u '+%Y-%m-%d_%H:%M:%S') -COMMIT=$(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") - -# Linker flags -LDFLAGS=-X main.version=$(VERSION) -X main.date=$(BUILD_TIME) -X main.commit=$(COMMIT) +# No ldflags needed - using debug.BuildInfo since Go 1.18 all: check build @@ -35,50 +30,50 @@ build: build-cli build-examples build-cli: @echo "Building $(BINARY_NAME)..." @mkdir -p $(BUILD_DIR) - $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME) $(BINARY_PATH) + $(GOBUILD) -o $(BUILD_DIR)/$(BINARY_NAME) $(BINARY_PATH) build-examples: @echo "Building $(EXAMPLE_MDNS_NAME)..." @mkdir -p $(BUILD_DIR) - $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME) $(EXAMPLE_MDNS_PATH) + $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME) $(EXAMPLE_MDNS_PATH) @echo "Building $(EXAMPLE_UPNP_NAME)..." - $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME) $(EXAMPLE_UPNP_PATH) + $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME) $(EXAMPLE_UPNP_PATH) @echo "Building $(SCANNER_NAME)..." - $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(SCANNER_NAME) $(SCANNER_PATH) + $(GOBUILD) -o $(BUILD_DIR)/$(SCANNER_NAME) $(SCANNER_PATH) build-all: build-linux build-darwin build-windows build-examples-all build-linux: @echo "Building for Linux..." @mkdir -p $(BUILD_DIR) - GOOS=linux GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 $(BINARY_PATH) + GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 $(BINARY_PATH) build-darwin: @echo "Building for macOS..." @mkdir -p $(BUILD_DIR) - GOOS=darwin GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-amd64 $(BINARY_PATH) - GOOS=darwin GOARCH=arm64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-arm64 $(BINARY_PATH) + GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-amd64 $(BINARY_PATH) + GOOS=darwin GOARCH=arm64 $(GOBUILD) -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-arm64 $(BINARY_PATH) build-windows: @echo "Building for Windows..." @mkdir -p $(BUILD_DIR) - GOOS=windows GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe $(BINARY_PATH) + GOOS=windows GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe $(BINARY_PATH) build-examples-all: @echo "Building examples for all platforms..." @mkdir -p $(BUILD_DIR) - GOOS=linux GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-linux-amd64 $(EXAMPLE_MDNS_PATH) - GOOS=darwin GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-darwin-amd64 $(EXAMPLE_MDNS_PATH) - GOOS=darwin GOARCH=arm64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-darwin-arm64 $(EXAMPLE_MDNS_PATH) - GOOS=windows GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-windows-amd64.exe $(EXAMPLE_MDNS_PATH) - GOOS=linux GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-linux-amd64 $(EXAMPLE_UPNP_PATH) - GOOS=darwin GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-darwin-amd64 $(EXAMPLE_UPNP_PATH) - GOOS=darwin GOARCH=arm64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-darwin-arm64 $(EXAMPLE_UPNP_PATH) - GOOS=windows GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-windows-amd64.exe $(EXAMPLE_UPNP_PATH) - GOOS=linux GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(SCANNER_NAME)-linux-amd64 $(SCANNER_PATH) - GOOS=darwin GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(SCANNER_NAME)-darwin-amd64 $(SCANNER_PATH) - GOOS=darwin GOARCH=arm64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(SCANNER_NAME)-darwin-arm64 $(SCANNER_PATH) - GOOS=windows GOARCH=amd64 $(GOBUILD) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(SCANNER_NAME)-windows-amd64.exe $(SCANNER_PATH) + GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-linux-amd64 $(EXAMPLE_MDNS_PATH) + GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-darwin-amd64 $(EXAMPLE_MDNS_PATH) + GOOS=darwin GOARCH=arm64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-darwin-arm64 $(EXAMPLE_MDNS_PATH) + GOOS=windows GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_MDNS_NAME)-windows-amd64.exe $(EXAMPLE_MDNS_PATH) + GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-linux-amd64 $(EXAMPLE_UPNP_PATH) + GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-darwin-amd64 $(EXAMPLE_UPNP_PATH) + GOOS=darwin GOARCH=arm64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-darwin-arm64 $(EXAMPLE_UPNP_PATH) + GOOS=windows GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(EXAMPLE_UPNP_NAME)-windows-amd64.exe $(EXAMPLE_UPNP_PATH) + GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(SCANNER_NAME)-linux-amd64 $(SCANNER_PATH) + GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(SCANNER_NAME)-darwin-amd64 $(SCANNER_PATH) + GOOS=darwin GOARCH=arm64 $(GOBUILD) -o $(BUILD_DIR)/$(SCANNER_NAME)-darwin-arm64 $(SCANNER_PATH) + GOOS=windows GOARCH=amd64 $(GOBUILD) -o $(BUILD_DIR)/$(SCANNER_NAME)-windows-amd64.exe $(SCANNER_PATH) test: @echo "Running tests..." diff --git a/cmd/soundtouch-cli/common.go b/cmd/soundtouch-cli/common.go index 6a9c89f..e7973be 100644 --- a/cmd/soundtouch-cli/common.go +++ b/cmd/soundtouch-cli/common.go @@ -150,6 +150,7 @@ func PrintWarning(message string) { // showVersionInfo displays detailed version information including build details func showVersionInfo(_ *cli.Context) error { + version, commit, date := getBuildInfo() fmt.Printf("soundtouch-cli version %s\n", version) fmt.Printf("Build commit: %s\n", commit) fmt.Printf("Build date: %s\n", date) diff --git a/cmd/soundtouch-cli/main.go b/cmd/soundtouch-cli/main.go index fa74dce..3c14605 100644 --- a/cmd/soundtouch-cli/main.go +++ b/cmd/soundtouch-cli/main.go @@ -3,18 +3,47 @@ package main import ( "log" "os" + "runtime/debug" + "time" "github.com/urfave/cli/v2" ) -// Build-time variables injected via ldflags -var ( +// getBuildInfo extracts version information from debug.BuildInfo +func getBuildInfo() (version, commit, date string) { version = "dev" - commit = "unknown" - date = "unknown" -) + commit = "unknown" + date = "unknown" + + if info, ok := debug.ReadBuildInfo(); ok { + // Get version from module info + if info.Main.Version != "" && info.Main.Version != "(devel)" { + version = info.Main.Version + } + + // Extract build settings + for _, setting := range info.Settings { + switch setting.Key { + case "vcs.revision": + if len(setting.Value) >= 7 { + commit = setting.Value[:7] + } else { + commit = setting.Value + } + case "vcs.time": + if t, err := time.Parse(time.RFC3339, setting.Value); err == nil { + date = t.Format("2006-01-02_15:04:05") + } + } + } + } + + return +} func main() { + version, _, _ := getBuildInfo() + app := &cli.App{ Name: "soundtouch-cli", Usage: "Command-line interface for controlling Bose SoundTouch devices", diff --git a/scripts/post-release.md b/scripts/post-release.md index e2b897a..3c4e82b 100644 --- a/scripts/post-release.md +++ b/scripts/post-release.md @@ -14,9 +14,10 @@ After successfully releasing v1.0.0, follow this checklist to maximize visibilit ``` Title: "Bose SoundTouch Go Library v1.0.0 - 100% API Coverage + WebSocket Events" Content: Highlight production-ready features, real hardware testing, excellent docs + Include: Code examples, performance metrics, real device compatibility list ``` -- [ ] **Gopher Slack** (#general, #show-and-tell): +- [x] **Gopher Slack** (#general, #show-and-tell): ✅ **COMPLETED** ``` "Just released a comprehensive Go library for Bose SoundTouch speakers 🎵 ✅ 100% API coverage (19/19 official endpoints) @@ -33,7 +34,7 @@ After successfully releasing v1.0.0, follow this checklist to maximize visibilit ``` ### Social Media -- [ ] **Twitter/X** announcement: +- [x] **Twitter/X** announcement: ✅ **COMPLETED** ``` "🎵 Just released Bose SoundTouch Go Library v1.0.0! @@ -49,6 +50,8 @@ After successfully releasing v1.0.0, follow this checklist to maximize visibilit https://github.com/gesellix/bose-soundtouch" ``` +- [x] **Bluesky** announcement: ✅ **COMPLETED** + - [ ] **LinkedIn** professional post (if applicable) ## 📋 Medium-term Actions (Within 1 week) @@ -81,6 +84,8 @@ After successfully releasing v1.0.0, follow this checklist to maximize visibilit ### Technical Communities - [ ] **Go Forum** announcement: https://forum.golangbridge.org/ +- [ ] **Golang Weekly** newsletter submission: https://golangweekly.com/ +- [ ] **Go Time podcast** community shoutouts: https://changelog.com/gotime - [ ] **Home Assistant Community**: https://community.home-assistant.io/ - [ ] **Bose Community Forums** (if they exist) - [ ] **Smart Home subreddits**: r/homeautomation, r/smarthome @@ -105,6 +110,9 @@ After successfully releasing v1.0.0, follow this checklist to maximize visibilit ```bash brew install gesellix/tap/soundtouch-cli ``` +- [ ] **Arch Linux AUR** package submission +- [ ] **Nix package** for NixOS users +- [ ] **GitHub Sponsors** setup for ongoing development ## 📊 Success Metrics to Track @@ -113,6 +121,7 @@ After successfully releasing v1.0.0, follow this checklist to maximize visibilit - [ ] pkg.go.dev page views: Monitor via GitHub insights - [ ] CLI downloads: Track release download counts - [ ] Reddit/HN engagement: Upvotes, comments, discussions +- [ ] Go module proxy downloads: Check via `go list -m -versions` ### Medium-term (1 month) - [ ] GitHub stars: Target 100+ @@ -173,21 +182,25 @@ Best regards, ## 🎯 Priority Ranking -**High Impact, Low Effort:** +### High Impact, Low Effort:** 1. Reddit r/golang post -2. Gopher Slack announcement +2. ~~Gopher Slack announcement~~ ✅ **DONE** 3. awesome-go submission -4. Twitter announcement +4. ~~Twitter/X announcement~~ ✅ **DONE** +5. ~~Bluesky announcement~~ ✅ **DONE** +6. Golang Weekly submission **High Impact, Medium Effort:** -5. Blog post on Dev.to -6. Home automation community posts -7. Example projects repository +6. Blog post on Dev.to +7. Home automation community posts +8. Example projects repository +9. pkg.go.dev badge and documentation polish **Medium Impact, High Effort:** -8. YouTube video/conference talk -9. Podcast appearances -10. Advanced integration examples +10. YouTube video/conference talk +11. Podcast appearances +12. Advanced integration examples +13. Package manager distributions ## 🚨 Common Pitfalls to Avoid