update

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package update provides shared logic for checking GitHub releases and determining whether the running build is older than the latest publicly available version.

Checks are parameterised on a release channel:

  • channel="stable" compares against the latest tagged release (/releases/latest). Semver current versions get a numeric compare; SHA currents fall back to string equality (installing would switch channel to stable).
  • channel="main" compares against the rolling "main" release (/releases/tags/main). SHA currents get a commit-graph compare via the GitHub commits-compare API for a "behind by N" / "diverged" readout.

Anything we can't classify (e.g. the literal "dev") is reported as State=DevBuild — the channel's latest is shown for reference but no update is offered.

Index

Constants

This section is empty.

Variables

View Source
var APIBase = "https://api.github.com/repos/cynkra/blockyard"

APIBase is the GitHub API root pointing at the configured repo (e.g. https://api.github.com/repos/cynkra/blockyard). It is a var so SetRepo can rewrite it from config and tests can point it at a local httptest server.

Functions

func AddGitHubAuth

func AddGitHubAuth(req *http.Request)

AddGitHubAuth sets the Authorization header if GITHUB_TOKEN is set.

func FetchInstallTarget

func FetchInstallTarget(channel, currentVersion string) (string, error)

FetchInstallTarget returns the image tag the orchestrator should install on the given channel ("stable" or "main").

For "stable", returns the latest release's semver (e.g. "1.5.0"), or "" when current already matches — version-string equality is a sufficient up-to-date check on this channel.

For "main", returns the rolling tag "main" unconditionally. The main channel pins to the registry-side rolling tag rather than a per-build release Name, so the orchestrator pulls :main and then asks the factory whether the resolved digest matches the running container (factory.IsAlreadyCurrent). This catches Monday-rebuild updates that refresh image content without bumping the release Name, and avoids the broken per-commit tag the publish workflow never pushed (issue #360).

func InferChannel

func InferChannel(version string) string

InferChannel picks the default release channel for a build given its version string: "stable" when the version is a clean semver tag, "main" otherwise. Used by the CLI self-update flow when the caller doesn't pass --channel explicitly.

func SetRepo

func SetRepo(repo string)

SetRepo points subsequent API calls at the given owner/repo (e.g. "cynkra/blockyard"). Called once at server startup from config so forks can self-host without recompiling.

func SpawnChecker

func SpawnChecker(ctx context.Context, version, channel string, store UpdateStore)

SpawnChecker periodically checks GitHub for a newer release on the given channel and stores the result on store. Performs an initial check after one minute (so startup isn't slowed by network), then once every 24 hours. Blocks until ctx is cancelled.

Types

type CompareResult

type CompareResult struct {
	Status   string `json:"status"`
	AheadBy  int    `json:"ahead_by"`
	BehindBy int    `json:"behind_by"`
}

CompareResult is the relevant subset of GitHub's compare-commits response. Status is one of "ahead", "behind", "identical", "diverged"; the counts describe head relative to base.

func CompareCommits

func CompareCommits(base, head string) (*CompareResult, error)

CompareCommits asks GitHub how head relates to base. Returns (nil, nil) when the API responds 404 — typically because base isn't reachable on the remote (fork or unpushed branch).

type GitHubAsset

type GitHubAsset struct {
	Name string `json:"name"`
	URL  string `json:"url"` // API URL — use with Accept: application/octet-stream
}

GitHubAsset represents a downloadable artifact in a release.

type GitHubRelease

type GitHubRelease struct {
	TagName string        `json:"tag_name"`
	Name    string        `json:"name"`
	Assets  []GitHubAsset `json:"assets"`
}

GitHubRelease represents a GitHub release.

func FetchLatestStableRelease

func FetchLatestStableRelease() (*GitHubRelease, error)

FetchLatestStableRelease fetches the latest tagged (non-prerelease) release.

func FetchRelease

func FetchRelease(url string) (*GitHubRelease, error)

FetchRelease fetches a single release from the given GitHub API URL.

func FetchReleaseByTag

func FetchReleaseByTag(tag string) (*GitHubRelease, error)

FetchReleaseByTag fetches a release by its Git tag name. Used by the orchestrator when applying a rolling update.

type Kind

type Kind int

Kind tags the version string format.

const (
	KindUnknown Kind = iota
	KindSemver
	KindSHA
)

type Result

type Result struct {
	State          State  `json:"state"`
	CurrentVersion string `json:"current_version"`
	LatestVersion  string `json:"latest_version,omitempty"`
	Detail         string `json:"detail,omitempty"`
	Channel        string `json:"channel,omitempty"`
}

Result is what consumers persist and render. LatestVersion is a display string (semver tag, short SHA, or empty when unknown); Detail carries human-readable extra context (e.g. "3 commits behind"). Channel records which release stream the check queried so the UI can surface and preserve the user's selection across refreshes.

func CheckLatest

func CheckLatest(currentVersion, channel string) (*Result, error)

CheckLatest queries GitHub for the head of the given channel and compares it to currentVersion. Network errors are folded into the Result as State=NoRemote rather than returned, so callers can render the outcome without an extra error branch — the (error) return is reserved for unrecoverable bugs (none today).

channel is "stable" (default) or "main"; any other value is treated as "stable".

func PerformCheck

func PerformCheck(store UpdateStore, channel string) (*Result, error)

PerformCheck runs a single update check synchronously against the given channel and writes the outcome to store. Always writes — even when the result is "up to date" or "dev build" — so the UI can display the most recent check time. Returns the result so a UI handler can render it directly.

type State

type State string

State enumerates how the running build compares to the upstream version the check found.

const (
	StateUnknown         State = "unknown"          // no check has run yet
	StateUpToDate        State = "up_to_date"       // matches latest release / origin/main HEAD
	StateUpdateAvailable State = "update_available" // older than latest release / behind origin/main
	StateAhead           State = "ahead"            // newer than latest release / ahead of origin/main
	StateDiverged        State = "diverged"         // SHA build that diverged from origin/main
	StateDevBuild        State = "dev_build"        // unparseable version string (e.g. "dev")
	StateNoRemote        State = "no_remote"        // GitHub unreachable or returned an error
	StateLocalNotFound   State = "local_not_found"  // SHA known but origin/main doesn't have it
)

type UpdateStore

type UpdateStore interface {
	SetUpdateStatus(*Result)
	GetVersion() string
}

UpdateStore is the interface a long-lived caller (the server) implements to receive check results. Satisfied by server.Server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL