From 35f8ee534738fbf316ef054b11885f347814d3bd Mon Sep 17 00:00:00 2001 From: Joel Male Date: Wed, 25 Feb 2026 14:40:47 +1000 Subject: [PATCH] feat: version/update subcommands, VERSION file, deploy version bumping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add VERSION file as canonical version source - build.sh reads VERSION file automatically, injects via -ldflags - deploy.sh prompts for major/minor/patch bump, injects version via ldflags into all 4 builds, and writes release/latest JSON file - Add 'pulsewise-collector version' — prints version and checks for update - Add 'pulsewise-collector update' — fetches and applies the latest release - Default version changed to "dev" for local builds without ldflags --- VERSION | 1 + build.sh | 2 +- main.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 VERSION diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..6e8bf73 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0 diff --git a/build.sh b/build.sh index 69a64d1..1641d7f 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -VERSION="${VERSION:-0.1.0}" +VERSION="${VERSION:-$(cat VERSION)}" go build -ldflags "-X main.version=${VERSION}" -o pulsewise-collector . echo "Built: pulsewise-collector (v${VERSION})" diff --git a/main.go b/main.go index 9f6d403..e9f512c 100644 --- a/main.go +++ b/main.go @@ -26,7 +26,7 @@ import ( ) // version is set at build time via -ldflags "-X main.version=x.y.z" -var version = "0.1.0" +var version = "dev" const ( defaultURL = "https://pulsewise.app/api/collect" @@ -144,6 +144,17 @@ type ProcessInfo struct { var prevNet *networkSnapshot func main() { + if len(os.Args) > 1 { + switch os.Args[1] { + case "version": + runVersionCommand() + return + case "update": + runUpdateCommand() + return + } + } + noAutoUpdate := flag.Bool("no-auto-update", false, "disable automatic updates") flag.Parse() @@ -174,6 +185,54 @@ func main() { } } +// ───────────────────────────────────────────────────────────── +// Subcommands +// ───────────────────────────────────────────────────────────── + +func runVersionCommand() { + fmt.Printf("pulsewise-collector v%s\n\n", version) + + fmt.Print("Checking for updates... ") + latest, err := fetchLatestVersion() + if err != nil { + fmt.Printf("(update check failed: %v)\n", err) + return + } + + if latest == version { + fmt.Println("You are on the latest version.") + } else { + fmt.Printf("v%s is available.\n", latest) + fmt.Println("Run 'pulsewise-collector update' to upgrade.") + } +} + +func runUpdateCommand() { + fmt.Printf("pulsewise-collector v%s\n\n", version) + + fmt.Print("Checking for updates... ") + latest, err := fetchLatestVersion() + if err != nil { + fmt.Fprintf(os.Stderr, "update check failed: %v\n", err) + os.Exit(1) + } + + if latest == version { + fmt.Printf("Already on the latest version (v%s).\n", version) + return + } + + fmt.Printf("v%s is available.\n\n", latest) + fmt.Print("Downloading... ") + + if err := downloadAndReplace(); err != nil { + fmt.Fprintf(os.Stderr, "\nUpdate failed: %v\n", err) + os.Exit(1) + } + + fmt.Printf("Done.\nSuccessfully updated to v%s.\n", latest) +} + // ───────────────────────────────────────────────────────────── // Auto-update // ─────────────────────────────────────────────────────────────