Skip to main content

Overview

The releaser package provides utilities for checking GitHub releases and comparing versions. It’s designed for CLI tools that need to notify users about available updates. Import path:
import "github.com/raystack/salt/cli/releaser"

Types

Info

type Info struct {
    Version string // Version of the release
    TarURL  string // Tarball URL of the release
}
Holds information about a software release fetched from GitHub.
Version
string
The version tag of the release (e.g., "v1.2.3")
TarURL
string
The URL to download the release tarball

Functions

FetchInfo

func FetchInfo(url string) (*Info, error)
Fetches details about the latest release from the provided GitHub API URL.
url
string
required
The GitHub API URL to fetch release information from.Example: "https://api.github.com/repos/raystack/salt/releases/latest"
Returns:
info
*Info
Release information containing version and tarball URL
error
error
Error if the HTTP request fails, returns non-200 status, or JSON parsing fails
Example:
url := "https://api.github.com/repos/raystack/salt/releases/latest"
info, err := releaser.FetchInfo(url)
if err != nil {
    return err
}

fmt.Printf("Latest version: %s\n", info.Version)
fmt.Printf("Download: %s\n", info.TarURL)
Implementation Details:
  • Sets timeout to releaser.Timeout (default 1 second)
  • Sets User-Agent header to "raystack/salt"
  • Parses JSON fields: tag_name and tarball_url
  • Returns error on non-200 HTTP status codes

CompareVersions

func CompareVersions(current, latest string) (bool, error)
Compares two semantic versions to determine if the current version is up-to-date.
current
string
required
The current version string (e.g., "v1.0.0")
latest
string
required
The latest version string to compare against (e.g., "v1.2.0")
Returns:
result
bool
true if current version is greater than or equal to latest version, false otherwise
error
error
Error if version string parsing fails (invalid semantic version format)
Example:
isUpToDate, err := releaser.CompareVersions("v1.0.0", "v1.2.0")
if err != nil {
    return err
}

if !isUpToDate {
    fmt.Println("Update available!")
}
Implementation Details:
  • Uses github.com/hashicorp/go-version for semantic version parsing
  • Supports standard semantic versioning (MAJOR.MINOR.PATCH)
  • Handles version prefixes (e.g., "v" in "v1.0.0")

CheckForUpdate

func CheckForUpdate(currentVersion, repo string) string
Convenience function that fetches the latest release and generates an update message if a newer version is available.
currentVersion
string
required
The current version of your application (e.g., "v1.0.0")
repo
string
required
GitHub repository in the format "owner/repo" (e.g., "raystack/salt")
Returns:
message
string
Update message if a newer version is available. Returns empty string if:
  • Current version is up-to-date
  • Error occurs during fetch or comparison
  • Network request fails
Example:
const version = "v1.0.0"

if msg := releaser.CheckForUpdate(version, "raystack/salt"); msg != "" {
    fmt.Println(msg)
}
// Output (if update available):
// A new release (v1.2.0) is available. consider updating to latest version.
Implementation Details:
  • Constructs GitHub API URL using APIFormat template
  • Calls FetchInfo() to get latest release
  • Calls CompareVersions() to check if update is needed
  • Silently handles errors by returning empty string
  • Does not block or panic on failure

Variables

Timeout

var Timeout = time.Second * 1
Sets the HTTP client timeout for fetching release information. Default is 1 second. Example:
import "time"

// Increase timeout for slower networks
releaser.Timeout = time.Second * 5

APIFormat

var APIFormat = "https://api.github.com/repos/%s/releases/latest"
The GitHub API URL template used to fetch the latest release of a repository. The %s is replaced with the repository name in "owner/repo" format. Example:
// Use custom API endpoint (e.g., GitHub Enterprise)
releaser.APIFormat = "https://github.mycompany.com/api/v3/repos/%s/releases/latest"

Error Handling

The package can return errors in these scenarios:
Error TypeCauseReturned By
HTTP request creation failedInvalid URLFetchInfo()
Network errorConnection timeout, DNS failureFetchInfo()
Non-200 status codeRepository not found, rate limitFetchInfo()
JSON parsing errorInvalid API response formatFetchInfo()
Version parsing errorInvalid semantic version stringCompareVersions()
Example Error Handling:
info, err := releaser.FetchInfo(url)
if err != nil {
    // Log but don't fail the application
    log.Printf("Failed to check for updates: %v", err)
    return
}

Complete Example

package main

import (
    "fmt"
    "time"
    
    "github.com/raystack/salt/cli/releaser"
)

const (
    appVersion = "v1.0.0"
    repoName   = "myorg/myapp"
)

func main() {
    // Configure timeout
    releaser.Timeout = time.Second * 3
    
    // Simple update check
    if msg := releaser.CheckForUpdate(appVersion, repoName); msg != "" {
        fmt.Println(msg)
    }
    
    // Or manual check with more control
    url := fmt.Sprintf(releaser.APIFormat, repoName)
    info, err := releaser.FetchInfo(url)
    if err != nil {
        fmt.Printf("Update check failed: %v\n", err)
        return
    }
    
    isUpToDate, err := releaser.CompareVersions(appVersion, info.Version)
    if err != nil {
        fmt.Printf("Version comparison failed: %v\n", err)
        return
    }
    
    if !isUpToDate {
        fmt.Printf("New version %s available!\n", info.Version)
        fmt.Printf("Download: %s\n", info.TarURL)
    }
}

Source Code Reference

  • Package location: /home/daytona/workspace/source/cli/releaser/release.go
  • Uses github.com/hashicorp/go-version for version comparison
  • Uses github.com/pkg/errors for error wrapping