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!
This commit is contained in:
Tobias Gesellchen
2026-01-11 17:27:07 +01:00
parent ab21c5aef9
commit 1ed562f45e
5 changed files with 82 additions and 44 deletions
+2 -2
View File
@@ -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"
+21 -26
View File
@@ -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..."
+1
View File
@@ -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)
+34 -5
View File
@@ -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",
+24 -11
View File
@@ -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