autoupgrade

package module
v0.0.0-...-88a78ff Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2025 License: MIT Imports: 7 Imported by: 1

README

autoupgrade

Use autoupgrade to install the latest version of your binary, quietly in the background. Zero dependencies.

Features

  • Zero dependencies - Uses only Go standard library
  • Context support - Full cancellation support for upgrade operations
  • Background upgrades - Non-blocking upgrade operations via goroutines
  • Build info access - Get build information from both current and upgraded binaries
  • Smart skipping - Automatically skips upgrades for development builds

Installation

go get github.com/melt-inc/autoupgrade

Usage

Basic Usage
package main

import (
    "context"
    "fmt"
    "time"

    "github.com/melt-inc/autoupgrade"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // Upgrade the current binary
    result := autoupgrade.Upgrade(ctx, "cmd/myapp")

    if result.ExitError != nil {
        fmt.Printf("Upgrade failed: %v\n", result.ExitError)
        return
    }

    if result.DidUpgrade() {
        newInfo, _ := result.NewBuildInfo()
        fmt.Printf("Upgraded from %s to %s\n",
            result.CurrentInfo.Main.Version,
            newInfo.Main.Version)
    } else {
        fmt.Println("No upgrade needed")
    }
}
Background Upgrades
package main

import (
    "context"
    "fmt"
    "time"

    "github.com/melt-inc/autoupgrade"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // Start upgrade in background
    resultCh := autoupgrade.UpgradeBackground(ctx, "cmd/myapp")

    // Do other work while upgrade happens
    fmt.Println("Upgrade started in background...")

    // Wait for result
    result := <-resultCh

    if result.ExitError != nil {
        fmt.Printf("Background upgrade failed: %v\n", result.ExitError)
        return
    }

    if result.DidUpgrade() {
        fmt.Println("Background upgrade completed successfully!")
    }
}
Checking Upgrade Status
result := autoupgrade.Upgrade(ctx, "")

// Check if upgrade actually occurred
if result.DidUpgrade() {
    // Get new build info
    newInfo, err := result.NewBuildInfo()
    if err == nil {
        fmt.Printf("New version: %s\n", newInfo.Main.Version)
    }
}

// Check for errors
if result.ExitError != nil {
    fmt.Printf("Upgrade error: %v\n", result.ExitError)
}

// Access current build info
if result.CurrentInfo != nil {
    fmt.Printf("Current version: %s\n", result.CurrentInfo.Main.Version)
}

API Reference

Types
UpgradeResult

Contains the result of an upgrade operation.

type UpgradeResult struct {
    CurrentInfo *debug.BuildInfo // Current build info of running process
    ExitError   error            // Error from upgrade process, if any
}
Functions
Upgrade(ctx context.Context, packagePath string) *UpgradeResult

Attempts to upgrade the current binary to the latest version using go install. The upgrade is skipped if the current version is a development build or build info is unavailable.

  • ctx: Context for cancellation support
  • packagePath: Relative path from module root to package (use "" for root)
UpgradeBackground(ctx context.Context, packagePath string) <-chan *UpgradeResult

Runs Upgrade in a goroutine and returns a channel that receives the result. Supports context cancellation.

Methods
(u *UpgradeResult) DidUpgrade() bool

Returns true if the upgrade actually occurred. Returns false if:

  • Build information is not available
  • Current version is a development build
  • Upgrade was not necessary (already at latest version)
  • Upgrade failed
(u *UpgradeResult) NewBuildInfo() (*debug.BuildInfo, error)

Returns the build information of the newly installed binary. The result is cached using sync.Once, so the file is only read once per UpgradeResult.

How It Works

  1. Reads current build information using runtime/debug.ReadBuildInfo()
  2. Skips upgrade if current version is "(devel)" or build info unavailable
  3. Runs go install module/path/package@latest to install latest version
  4. Provides access to new build information via lazy-loaded NewBuildInfo() method

License

MIT License

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func UpgradeBackground

func UpgradeBackground(ctx context.Context, packagePath string) <-chan *UpgradeResult

UpgradeBackground runs Upgrade in a goroutine and returns a channel that will receive the UpgradeResult. The channel is closed after the result is sent. This allows for non-blocking upgrade operations. The context can be used to cancel the upgrade operation.

Types

type UpgradeResult

type UpgradeResult struct {
	CurrentInfo *debug.BuildInfo // Current build information of the running process, if available
	ExitError   error            // Error encountered during the upgrade process, if any
	// contains filtered or unexported fields
}

UpgradeResult contains the result of an upgrade operation. It provides access to build information from both the current process and the newly installed binary.

func Upgrade

func Upgrade(ctx context.Context, packagePath string) *UpgradeResult

Upgrade attempts to upgrade the current binary to the latest version using 'go install'. The packagePath parameter specifies the relative path from the module root to the package. Upgrade is skipped if the current version is a development build or build info is unavailable. Context cancellation can be used to kill the go install process.

func (*UpgradeResult) DidUpgrade

func (u *UpgradeResult) DidUpgrade() bool

DidUpgrade returns false if the upgrade did not occur, this can happen when the build information is not available, the current version is a development version, or upgrade was not necessary (e.g., already at latest version).

func (*UpgradeResult) NewBuildInfo

func (u *UpgradeResult) NewBuildInfo() (*debug.BuildInfo, error)

NewBuildInfo returns the build information of the newly installed binary. Returns nil if the executable path cannot be determined or the build info cannot be read.