github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/releases/versions.go (about)

     1  package releases
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"runtime"
     7  	"runtime/debug"
     8  
     9  	"github.com/jzelinskie/cobrautil/v2"
    10  	"github.com/rs/zerolog/log"
    11  	"golang.org/x/mod/semver"
    12  )
    13  
    14  // CurrentVersion returns the current version of the binary.
    15  func CurrentVersion() (string, error) {
    16  	bi, ok := debug.ReadBuildInfo()
    17  	if !ok {
    18  		return "", fmt.Errorf("failed to read BuildInfo because the program was compiled with Go %s", runtime.Version())
    19  	}
    20  
    21  	return cobrautil.VersionWithFallbacks(bi), nil
    22  }
    23  
    24  // SoftwareUpdateState is the state of this software relative to whether updates are available.
    25  type SoftwareUpdateState int
    26  
    27  const (
    28  	// Unknown indicates an unknown state.
    29  	Unknown SoftwareUpdateState = iota
    30  
    31  	// UnreleasedVersion indicates that the current software version running is an unreleased version.
    32  	UnreleasedVersion
    33  
    34  	// UpdateAvailable indicates an update is available.
    35  	UpdateAvailable
    36  
    37  	// UpToDate indicates that the software is fully up-to-date.
    38  	UpToDate
    39  )
    40  
    41  // CheckIsLatestVersion returns whether the current version of the software is the latest released.
    42  // Returns the state, as well as the latest release.
    43  func CheckIsLatestVersion(
    44  	ctx context.Context,
    45  	getCurrentVersion func() (string, error),
    46  	getLatestRelease func(context.Context) (*Release, error),
    47  ) (SoftwareUpdateState, string, *Release, error) {
    48  	currentVersion, err := getCurrentVersion()
    49  	if err != nil {
    50  		return Unknown, currentVersion, nil, err
    51  	}
    52  
    53  	if currentVersion == "" || !semver.IsValid(currentVersion) {
    54  		return UnreleasedVersion, currentVersion, nil, nil
    55  	}
    56  
    57  	release, err := getLatestRelease(ctx)
    58  	if err != nil {
    59  		return Unknown, currentVersion, nil, err
    60  	}
    61  
    62  	if !semver.IsValid(release.Version) {
    63  		log.Warn().Str("version", release.Version).Msg("invalid version")
    64  		return Unknown, currentVersion, nil, err
    65  	}
    66  
    67  	if semver.Compare(currentVersion, release.Version) < 0 {
    68  		return UpdateAvailable, currentVersion, release, nil
    69  	}
    70  
    71  	return UpToDate, currentVersion, release, nil
    72  }