update

package
v1.0.47571 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package update discovers whether a newer circleci release exists and, when so, hands the caller a notice to print after a successful command. It never blocks the command, corrupts piped output, or surfaces its own errors.

Index

Constants

View Source
const (
	// ToolName is the value sent as filter[tool] and echoed back as the "tool"
	// attribute. It is the CLI's GitHub repository name and part of the server's
	// public contract, so it must never be derived from anything dynamic.
	ToolName = "circleci-cli"

	// ForceEnv bypasses the TTY and dev-build gates and supplies the version to
	// treat as current. Internal test hook (double underscore); never user-set.
	ForceEnv = "__CIRCLE_UPDATE_FORCE"
)

Variables

This section is empty.

Functions

func EffectiveVersion

func EffectiveVersion(version string) string

EffectiveVersion returns the version the check should treat as current: the ForceEnv override when set (test hook), otherwise version.

func PrintNotice

func PrintNotice(ctx context.Context, currentVersion string, rel *ReleaseInfo)

PrintNotice writes the two-line update notice to stderr, blank-line padded and after all command output. The second line links the new release's GitHub release page. It is a no-op when rel is nil.

The notice only prints when both Out and Err are TTYs (see ShouldCheck), so color is always safe here — there is no pipe to corrupt. The color helpers still fall back to plain text under NO_COLOR / TERM=dumb, so the message text is unchanged when color is disabled.

func ShouldCheck

func ShouldCheck(ctx context.Context, cfg *config.Config, version string) bool

ShouldCheck reports whether this invocation may perform an update check.

Agents and MCP cannot act on a prompt, and the notice must never corrupt a pipe — so a detected agent or a non-TTY stream silences it. No token is required: GET /api/v3/tool/releases serves anonymously, so unauthenticated users (fresh installs, config-validate-only) still get the notice. ForceEnv bypasses the TTY and dev-build gates for tests but not the agent/preference gates.

Types

type Notifier

type Notifier struct {
	// contains filtered or unexported fields
}

Notifier carries a background update check. Create one with Start, then call Finish once the command has produced all its output.

func Start

func Start(ctx context.Context, src Source, statePath, currentVersion string) *Notifier

Start launches an update check in the background against src. The check runs with a child of ctx so Finish can cancel any in-flight request.

func (*Notifier) Finish

func (n *Notifier) Finish() *ReleaseInfo

Finish returns the release worth telling the user about, or nil. It cancels any in-flight request first (so a slow request never adds command latency) and then blocks until the background check settles — bounded, because the cancel aborts the request.

type ReleaseInfo

type ReleaseInfo struct {
	Version     string    // semver, no leading "v" — matches main.version
	PublishedAt time.Time // zero when unknown; treated as "notify"
}

ReleaseInfo is the newest stable release the source reported.

func Check

func Check(ctx context.Context, src Source, statePath, currentVersion string) (*ReleaseInfo, error)

Check returns a release worth telling the user about, or nil. It refreshes from src at most once per cacheWindow, but evaluates notifyDelay against cached state on every call — so a notice suppressed by the delay appears the moment the delay elapses, without waiting for the next network fetch.

Errors are best-effort: a contended lock or unreadable state returns nil, nil rather than surfacing, because an update check is the last thing that should ever print an error.

type Source

type Source interface {
	Latest(ctx context.Context) (*ReleaseInfo, error)
}

Source returns the newest stable release, or nil if it cannot tell. proxySource (GET /api/v3/tool/releases) is the only implementation; see the package plan for the contingency it exists for.

func NewProxySource

func NewProxySource(client *apiclient.Client) Source

NewProxySource returns the Source backed by GET /api/v3/tool/releases.

Jump to

Keyboard shortcuts

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