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 ¶
- Variables
- func AddGitHubAuth(req *http.Request)
- func FetchInstallTarget(channel, currentVersion string) (string, error)
- func InferChannel(version string) string
- func SetRepo(repo string)
- func SpawnChecker(ctx context.Context, version, channel string, store UpdateStore)
- type CompareResult
- type GitHubAsset
- type GitHubRelease
- type Kind
- type Result
- type State
- type UpdateStore
Constants ¶
This section is empty.
Variables ¶
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 ¶
AddGitHubAuth sets the Authorization header if GITHUB_TOKEN is set.
func FetchInstallTarget ¶
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 ¶
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 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 ¶
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 ¶
UpdateStore is the interface a long-lived caller (the server) implements to receive check results. Satisfied by server.Server.