From 5fdf001dc8d490b1268d03ed25b16cad363c25ba Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 18 Nov 2025 11:54:16 -0500 Subject: [PATCH 1/4] Add --version flag and make release workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add --version flag to display version information - Create make release workflow for creating version tags - Add Homebrew formula for packaging and distribution - Update formula test to use --version flag 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Makefile | 34 +++++++++++++++++++++++++++++++++- cmd/goose/main.go | 8 ++++++++ goose.rb | 27 +++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 goose.rb diff --git a/Makefile b/Makefile index f01784d..041d860 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") LDFLAGS := -X main.version=$(GIT_VERSION) -X main.commit=$(GIT_COMMIT) -X main.date=$(BUILD_DATE) -.PHONY: all build clean deps run app-bundle install install-darwin install-unix install-windows test +.PHONY: all build clean deps run app-bundle install install-darwin install-unix install-windows test release test: go test -race ./... @@ -257,3 +257,35 @@ fix: exit $$exit_code # END: lint-install . + +# Release workflow - creates a new version tag +# Usage: make release VERSION=v1.0.0 +release: + @if [ -z "$(VERSION)" ]; then \ + echo "Error: VERSION is required. Usage: make release VERSION=v1.0.0"; \ + exit 1; \ + fi + @echo "Creating release $(VERSION)..." + @if ! echo "$(VERSION)" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$$'; then \ + echo "Error: VERSION must be in format vX.Y.Z (e.g., v1.0.0)"; \ + exit 1; \ + fi + @if git rev-parse "$(VERSION)" >/dev/null 2>&1; then \ + echo "Error: Tag $(VERSION) already exists"; \ + exit 1; \ + fi + @echo "Running tests..." + @$(MAKE) test + @echo "Running linters..." + @$(MAKE) lint + @echo "Checking for uncommitted changes..." + @if [ -n "$$(git status --porcelain)" ]; then \ + echo "Error: Working directory has uncommitted changes"; \ + git status --short; \ + exit 1; \ + fi + @echo "Creating and pushing tag $(VERSION)..." + @git tag -a "$(VERSION)" -m "Release $(VERSION)" + @git push origin "$(VERSION)" + @echo "✓ Release $(VERSION) created and pushed successfully" + @echo " View release at: https://github.com/codeGROOVE-dev/goose/releases/tag/$(VERSION)" diff --git a/cmd/goose/main.go b/cmd/goose/main.go index 44d2f2c..51c2221 100644 --- a/cmd/goose/main.go +++ b/cmd/goose/main.go @@ -117,6 +117,7 @@ func main() { var targetUser string var noCache bool var debugMode bool + var showVersion bool var updateInterval time.Duration var browserOpenDelay time.Duration var maxBrowserOpensMinute int @@ -124,12 +125,19 @@ func main() { flag.StringVar(&targetUser, "user", "", "GitHub user to query PRs for (defaults to authenticated user)") flag.BoolVar(&noCache, "no-cache", false, "Bypass cache for debugging") flag.BoolVar(&debugMode, "debug", false, "Enable debug logging") + flag.BoolVar(&showVersion, "version", false, "Show version information and exit") flag.DurationVar(&updateInterval, "interval", defaultUpdateInterval, "Update interval (e.g. 30s, 1m, 5m)") flag.DurationVar(&browserOpenDelay, "browser-delay", 1*time.Minute, "Minimum delay before opening PRs in browser after startup") flag.IntVar(&maxBrowserOpensMinute, "browser-max-per-minute", 2, "Maximum browser windows to open per minute") flag.IntVar(&maxBrowserOpensDay, "browser-max-per-day", defaultMaxBrowserOpensDay, "Maximum browser windows to open per day") flag.Parse() + // Handle version flag + if showVersion { + fmt.Printf("goose version %s\ncommit: %s\nbuilt: %s\n", version, commit, date) + os.Exit(0) + } + // Validate target user if provided if targetUser != "" { if err := validateGitHubUsername(targetUser); err != nil { diff --git a/goose.rb b/goose.rb new file mode 100644 index 0000000..cb14316 --- /dev/null +++ b/goose.rb @@ -0,0 +1,27 @@ +class Goose < Formula + desc "Menubar app for GitHub pull request tracking and notifications" + homepage "https://github.com/codeGROOVE-dev/goose" + url "https://github.com/ready-to-review/goose.git", + tag: "v3.7.1", + revision: "920467c86e2123db4d47503de341bfb5aca79b42" + license "GPL-3.0-only" + head "https://github.com/ready-to-review/goose.git", branch: "main" + + depends_on "go" => :build + depends_on "gh" + + def install + ldflags = %W[ + -X main.version=#{version} + -X main.commit=#{Utils.git_short_head} + -X main.date=#{time.iso8601} + ] + + system "go", "build", *std_go_args(ldflags:, output: bin/"goose"), "./cmd/goose" + end + + test do + output = shell_output("#{bin}/goose --version") + assert_match version.to_s, output + end +end From 9f19abf317a037b22b8b2fc86842eb0cb18835d1 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 18 Nov 2025 12:13:37 -0500 Subject: [PATCH 2/4] Release v0.9.1-test --- Makefile | 14 ++++++++++++-- cmd/goose/VERSION | 1 + cmd/goose/main.go | 24 ++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 cmd/goose/VERSION diff --git a/Makefile b/Makefile index 041d860..ffd09da 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,13 @@ BUNDLE_VERSION = 1 BUNDLE_ID = dev.codegroove.r2r # Version information for builds -GIT_VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") +# Try VERSION file first (for release tarballs), then fall back to git +VERSION_FILE := $(shell cat cmd/goose/VERSION 2>/dev/null) +GIT_VERSION := $(shell git describe --tags --always --dirty 2>/dev/null) +BUILD_VERSION := $(or $(VERSION_FILE),$(GIT_VERSION),dev) GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") -LDFLAGS := -X main.version=$(GIT_VERSION) -X main.commit=$(GIT_COMMIT) -X main.date=$(BUILD_DATE) +LDFLAGS := -X main.version=$(BUILD_VERSION) -X main.commit=$(GIT_COMMIT) -X main.date=$(BUILD_DATE) .PHONY: all build clean deps run app-bundle install install-darwin install-unix install-windows test release @@ -278,6 +281,12 @@ release: @$(MAKE) test @echo "Running linters..." @$(MAKE) lint + @echo "Creating VERSION file..." + @echo "$(VERSION)" > cmd/goose/VERSION + @git add cmd/goose/VERSION + @if [ -n "$$(git diff --cached --name-only)" ]; then \ + git commit -m "Release $(VERSION)"; \ + fi @echo "Checking for uncommitted changes..." @if [ -n "$$(git status --porcelain)" ]; then \ echo "Error: Working directory has uncommitted changes"; \ @@ -286,6 +295,7 @@ release: fi @echo "Creating and pushing tag $(VERSION)..." @git tag -a "$(VERSION)" -m "Release $(VERSION)" + @git push origin main @git push origin "$(VERSION)" @echo "✓ Release $(VERSION) created and pushed successfully" @echo " View release at: https://github.com/codeGROOVE-dev/goose/releases/tag/$(VERSION)" diff --git a/cmd/goose/VERSION b/cmd/goose/VERSION new file mode 100644 index 0000000..6cebca5 --- /dev/null +++ b/cmd/goose/VERSION @@ -0,0 +1 @@ +v0.9.1-test diff --git a/cmd/goose/main.go b/cmd/goose/main.go index 51c2221..a475ce4 100644 --- a/cmd/goose/main.go +++ b/cmd/goose/main.go @@ -6,6 +6,7 @@ package main import ( "context" + _ "embed" "flag" "fmt" "log/slog" @@ -24,13 +25,32 @@ import ( "github.com/google/go-github/v57/github" ) +// VERSION file embedded at compile time (created by make release) +// +//go:embed VERSION +var versionFile string + // Version information - set during build with -ldflags. +// If not set via ldflags, getVersion() will read from embedded VERSION file. var ( version = "dev" commit = "unknown" date = "unknown" ) +// getVersion returns the version string, preferring ldflags but falling back to VERSION file. +func getVersion() string { + // If version was set via ldflags and isn't the default, use it + if version != "" && version != "dev" { + return version + } + // Fall back to embedded VERSION file + if v := strings.TrimSpace(versionFile); v != "" { + return v + } + return "dev" +} + const ( cacheTTL = 10 * 24 * time.Hour // 10 days - rely mostly on PR UpdatedAt runningTestsCacheTTL = 2 * time.Minute // Short TTL for PRs with incomplete tests to catch completions quickly @@ -134,7 +154,7 @@ func main() { // Handle version flag if showVersion { - fmt.Printf("goose version %s\ncommit: %s\nbuilt: %s\n", version, commit, date) + fmt.Printf("goose version %s\ncommit: %s\nbuilt: %s\n", getVersion(), commit, date) os.Exit(0) } @@ -176,7 +196,7 @@ func main() { Level: logLevel, } slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, opts))) - slog.Info("Starting Goose", "version", version, "commit", commit, "date", date) + slog.Info("Starting Goose", "version", getVersion(), "commit", commit, "date", date) slog.Info("Configuration", "update_interval", updateInterval, "max_retries", maxRetries, "max_delay", maxRetryDelay) slog.Info("Browser auto-open configuration", "startup_delay", browserOpenDelay, From ea4a6ec2984a93e648d83ef2bcc6b1ec820162c7 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 18 Nov 2025 12:18:05 -0500 Subject: [PATCH 3/4] fix lint errors --- Makefile | 4 ++-- cmd/goose/icons_darwin.go | 2 +- cmd/goose/x11tray/tray_other.go | 14 ++++++++------ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index ffd09da..842c14c 100644 --- a/Makefile +++ b/Makefile @@ -269,8 +269,8 @@ release: exit 1; \ fi @echo "Creating release $(VERSION)..." - @if ! echo "$(VERSION)" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$$'; then \ - echo "Error: VERSION must be in format vX.Y.Z (e.g., v1.0.0)"; \ + @if ! echo "$(VERSION)" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+'; then \ + echo "Error: VERSION must be in format vX.Y.Z or vX.Y.Z-suffix (e.g., v1.0.0, v1.0.0-alpha)"; \ exit 1; \ fi @if git rev-parse "$(VERSION)" >/dev/null 2>&1; then \ diff --git a/cmd/goose/icons_darwin.go b/cmd/goose/icons_darwin.go index 194b02e..6b1ac93 100644 --- a/cmd/goose/icons_darwin.go +++ b/cmd/goose/icons_darwin.go @@ -24,7 +24,7 @@ var iconWarning []byte //go:embed icons/cockroach.png var iconCockroach []byte -func getIcon(iconType IconType, counts PRCounts) []byte { +func getIcon(iconType IconType, _ PRCounts) []byte { switch iconType { case IconGoose, IconBoth: return iconGoose diff --git a/cmd/goose/x11tray/tray_other.go b/cmd/goose/x11tray/tray_other.go index c99ed7b..d0a1520 100644 --- a/cmd/goose/x11tray/tray_other.go +++ b/cmd/goose/x11tray/tray_other.go @@ -1,5 +1,7 @@ //go:build !linux && !freebsd && !openbsd && !netbsd && !dragonfly && !solaris && !illumos && !aix +// Package x11tray provides system tray proxy support for Unix-like systems. +// On non-Unix platforms (macOS, Windows), the systray library handles tray functionality natively. package x11tray import ( @@ -16,18 +18,18 @@ func HealthCheck() error { type ProxyProcess struct{} // Stop is a no-op on non-Unix platforms. -func (p *ProxyProcess) Stop() error { +func (*ProxyProcess) Stop() error { return nil } -// TryProxy is not needed on non-Unix platforms and always returns nil. -func TryProxy(ctx context.Context) (*ProxyProcess, error) { - return nil, nil +// TryProxy is not needed on non-Unix platforms. +func TryProxy(_ context.Context) (*ProxyProcess, error) { + return &ProxyProcess{}, nil } // EnsureTray always succeeds on non-Unix platforms. -func EnsureTray(ctx context.Context) (*ProxyProcess, error) { - return nil, nil +func EnsureTray(_ context.Context) (*ProxyProcess, error) { + return &ProxyProcess{}, nil } // ShowContextMenu is a no-op on non-Unix platforms. From 3ae7cb646107853fccdb1fb94856e0212efdbe7a Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 18 Nov 2025 12:26:57 -0500 Subject: [PATCH 4/4] integrate version string with macOS plist --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 842c14c..efe1a87 100644 --- a/Makefile +++ b/Makefile @@ -136,6 +136,10 @@ app-bundle: out build-darwin install-appify /usr/libexec/PlistBuddy -c "Set :CFBundleDevelopmentRegion en" "out/$(BUNDLE_NAME).app/Contents/Info.plist" @/usr/libexec/PlistBuddy -c "Add :NSUserNotificationAlertStyle string alert" "out/$(BUNDLE_NAME).app/Contents/Info.plist" 2>/dev/null || \ /usr/libexec/PlistBuddy -c "Set :NSUserNotificationAlertStyle alert" "out/$(BUNDLE_NAME).app/Contents/Info.plist" + @/usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string $(BUILD_VERSION)" "out/$(BUNDLE_NAME).app/Contents/Info.plist" 2>/dev/null || \ + /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $(BUILD_VERSION)" "out/$(BUNDLE_NAME).app/Contents/Info.plist" + @/usr/libexec/PlistBuddy -c "Add :CFBundleVersion string $(BUILD_VERSION)" "out/$(BUNDLE_NAME).app/Contents/Info.plist" 2>/dev/null || \ + /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $(BUILD_VERSION)" "out/$(BUNDLE_NAME).app/Contents/Info.plist" # Remove extended attributes and code sign the app bundle @echo "Preparing app bundle for signing..."