An auto-updater library for Go applications built with make-go. It handles automatic update checking, downloading, and in-place binary replacement with seamless restarts.
- Automatic hourly update checks
- Manual update triggering via SIGHUP
- Channel-based release management (e.g., stable, testing)
- Atomic binary replacement
- Cross-platform support (Linux, macOS, FreeBSD, Windows)
- Busy state management to prevent updates during critical operations
- Peer version signaling for cluster-aware updates
go get github.com/KarpelesLab/goupdpackage main
import "github.com/KarpelesLab/goupd"
func main() {
// Start the auto-updater (only active in production mode)
goupd.AutoUpdate(false)
// Your application code here
}Most variables are auto-detected from Go's build info at runtime:
| Variable | Source | Description |
|---|---|---|
PROJECT_NAME |
Auto-detected | Derived from module path |
GIT_TAG |
Auto-detected | First 7 chars of vcs.revision |
DATE_TAG |
Auto-detected | Commit timestamp from vcs.time (YYYYMMDDhhmmss) |
VERSION |
Auto-detected | Module version from build info |
The following variables should be set at build time via -ldflags:
| Variable | Description | Example |
|---|---|---|
MODE |
Build mode (DEV or PROD) |
PROD |
CHANNEL |
Release channel (branch name) | master |
Example build command:
go build -ldflags "-X github.com/KarpelesLab/goupd.MODE=PROD \
-X github.com/KarpelesLab/goupd.CHANNEL=master"Note: When using make-go, these variables are set automatically.
| Variable | Description |
|---|---|
GOUPD_DELAY |
Seconds to delay startup after restart (set automatically) |
GOUPD_NOW |
If set, triggers an immediate update check on startup |
// Start the auto-updater
goupd.AutoUpdate(allowTest bool)
// Manually trigger an update check
updated := goupd.RunAutoUpdateCheck()
// Switch to a different release channel
switched := goupd.SwitchChannel("testing")Prevent updates during critical operations:
goupd.Busy()
defer goupd.Unbusy()
// Critical operation that shouldn't be interruptedOr use TryBusy() for non-blocking acquisition:
if goupd.TryBusy() {
defer goupd.Unbusy()
// Perform work
}// Get latest version info
version, err := goupd.GetLatest("myproject", "master")
// Check if version matches current
if !version.IsCurrent() {
// Install the update
err := version.Install()
}
// Save to a specific path
err := version.SaveAs("/path/to/binary")For clustered applications, notify when peers have newer versions:
// Signal a peer's version (triggers update if peer is newer)
goupd.SignalVersion(peerGitTag, peerDateTag)
// With channel filtering
goupd.SignalVersionChannel(peerGitTag, peerDateTag, peerChannel)// Customize pre-restart behavior
goupd.BeforeRestart = func() {
// Cleanup before restart
}
// Trigger a restart
goupd.Restart()The library expects updates to be hosted at HOST (default: https://dist-go.tristandev.net/) with the following structure:
/{project}/LATEST # Latest version info (space-separated: date git prefix)
/{project}/LATEST-{channel} # Channel-specific latest version
/{project}/{prefix}.arch # Supported architectures (space-separated)
/{project}/{prefix}/{project}_{os}_{arch}.bz2 # Compressed binary
MIT License - see LICENSE for details.