Documentation
¶
Overview ¶
Package setup provides initialisation helpers for GTB-based tools, including configuration directory bootstrapping, default config file creation, and self-update orchestration.
The Initialiser interface supports a modular hook-based pattern for extending the init process — SSH key setup, authentication configuration, and custom post-init steps can be composed and ordered. Update checks use semantic version comparison against the configured release source (GitHub or GitLab).
Package setup provides self-update and bootstrap functionality for GTB-based tools. This file registers all built-in release providers via blank imports so that they are available whenever pkg/setup is imported.
Package setup signing primitives.
This file defines the cryptographic foundation for Phase 2 of the remote-update-checksum-verification spec: a TrustSet of vetted public keys, a minimum-strength policy that runs at TrustSet construction time, and a verifier for a detached ASCII-armored signature over the checksums manifest.
Trust sets are immutable once constructed. Verification iterates the set and returns nil on the first key that validates the signature; the failure path returns ErrSignatureInvalid without naming the keys tried.
Index ¶
- Constants
- Variables
- func AddCommandWithMiddleware(parent, cmd *cobra.Command, feature props.FeatureCmd)deprecated
- func ApplyMiddlewareRecursively(cmd *cobra.Command, feature props.FeatureCmd)deprecated
- func Chain(feature props.FeatureCmd, runE func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error
- func GetChecks() map[props.FeatureCmd][]CheckProvider
- func GetDefaultConfigDir(fs afero.Fs, name string) string
- func GetFeatureFlags() map[props.FeatureCmd][]FeatureFlag
- func GetInitialisers() map[props.FeatureCmd][]InitialiserProvider
- func GetSubcommands() map[props.FeatureCmd][]SubcommandProvider
- func GetTimeSinceLast(fs afero.Fs, name string, status timeSinceKey) time.Duration
- func Initialise(props *props.Props, opts InitOptions) (string, error)
- func Register(feature props.FeatureCmd, ips []InitialiserProvider, sps []SubcommandProvider, ...)
- func RegisterChecks(feature props.FeatureCmd, cps []CheckProvider)
- func RegisterGlobalMiddleware(mw ...Middleware)
- func RegisterMiddleware(feature props.FeatureCmd, mw ...Middleware)
- func ResetRegistryForTesting()
- func Seal()
- func SealRegistry()
- func SetTimeSinceLast(fs afero.Fs, name string, status timeSinceKey) error
- func SkipUpdateCheck(fs afero.Fs, name string, cmd *cobra.Command) bool
- func VerifyChecksum(fs afero.Fs, sidecarPath string, data []byte) error
- func VerifyChecksumFromManifest(manifest []byte, filename string, data []byte) error
- func VerifyChecksumFromManifestReader(manifest []byte, filename string, dataReader io.Reader, dst io.Writer, ...) (int64, error)
- func WKDURLs(email string) (advanced, direct, advancedHost string, _ error)
- type CheckFunc
- type CheckProvider
- type CheckResult
- type Command
- type CompositeResolver
- type FeatureFlag
- type FeatureRegistry
- type InitOptions
- type Initialiser
- type InitialiserProvider
- type KeyResolver
- type KeyResolverConfig
- type Middleware
- type SelfUpdater
- func (s *SelfUpdater) DownloadAsset(ctx context.Context, asset release.ReleaseAsset) (bytes.Buffer, error)
- func (s *SelfUpdater) GetCurrentVersion() string
- func (s *SelfUpdater) GetLatestRelease(ctx context.Context) (release.Release, error)
- func (s *SelfUpdater) GetLatestVersionString(ctx context.Context) (string, error)
- func (s *SelfUpdater) GetReleaseNotes(ctx context.Context, from string, to string) (string, error)
- func (s *SelfUpdater) GetStructuredReleaseNotes(ctx context.Context, from, to string, archive ...bytes.Buffer) (*changelog.Changelog, error)
- func (s *SelfUpdater) IsLatestVersion(ctx context.Context) (bool, string, error)
- func (s *SelfUpdater) SignatureAssetName() string
- func (s *SelfUpdater) Update(ctx context.Context) (string, error)
- func (s *SelfUpdater) UpdateFromFile(filePath string) (string, error)
- type SubcommandProvider
- type TrustSet
- type UpdaterOption
- type WKDResolverConfig
Constants ¶
const ( UpdatedKey = timeSinceKey("updated") CheckedKey = timeSinceKey("checked") )
const (
DefaultConfigFilename = "config.yaml"
)
Variables ¶
var ( // MaxChecksumsSize caps the byte length of a downloaded checksums // manifest. A GoReleaser manifest for a typical multi-OS release // is ~1 KiB; 1 MiB is 1000× headroom. MaxChecksumsSize int64 = 1 << 20 // MaxBinaryDownloadSize caps the byte length of a downloaded // binary asset. 512 MiB is far above any realistic CLI binary; // raise this only for tools that legitimately ship larger artefacts. MaxBinaryDownloadSize int64 = 512 << 20 )
Size bounds on untrusted inputs. Exported as variables so tools with exceptional release layouts can reassign them before calling Update; the defaults are generous but protect against a hostile server streaming an unbounded response.
var ( // MaxSignatureSize caps the bytes read from a detached signature // download. GPG detached signatures are typically 400-800 bytes; // 8 KiB is 10x headroom. MaxSignatureSize int64 = 8 << 10 // MaxWKDResponseSize caps the bytes read from a WKD public-key fetch. MaxWKDResponseSize int64 = 64 << 10 )
Size bounds on signing-path untrusted inputs. Exported as variables so tool authors with exceptional release layouts can adjust them; the defaults are generous but protect against an unbounded download.
var ( // DefaultRequireSignature is the compile-time default for signature // enforcement. Tool authors should set this to true in main() once // the first signed release is available and clients have received an // embedded key in a prior release (see the N+1 / N+2 / N+3 rollout // in docs/development/phase2-signing-prep.md). DefaultRequireSignature = false // DefaultKeySource is the compile-time default for the key-source // mode. Accepted values: "embedded", "external", "both" (default). DefaultKeySource = "both" // DefaultRequireExternalCrosscheck controls whether a failure to // reach the external key resolver (WKD) aborts the update. Set to // true in locked-down environments where silent fallback to // embedded-only is unacceptable. DefaultRequireExternalCrosscheck = false // DefaultExternalKeyEmail is the email used to derive the WKD URL. // Tool authors should set this in main() to their release email. DefaultExternalKeyEmail = "" )
Compile-time defaults for signature enforcement. Tool authors override these in main() to change behaviour for their binary; downstream config and env vars override per-invocation.
var ( // ErrSignatureInvalid is returned when no key in the trust set // validates the detached signature over the checksums manifest. The // same error is used for malformed signatures: an unparseable // signature is not distinguishable from a forged one for the // caller's purpose. ErrSignatureInvalid = errors.New("signature verification failed") // ErrSignatureMissing is returned when require_signature is true and // no signature asset was found in the release. ErrSignatureMissing = errors.New("signature asset not found in release") // ErrWeakKey is returned when a public key (embedded or fetched) // fails the minimum-strength policy at LoadTrustSet time. ErrWeakKey = errors.New("public key fails minimum-strength policy") // ErrSignatureTooLarge is returned when the signature download // exceeds MaxSignatureSize. ErrSignatureTooLarge = errors.New("signature download exceeds maximum size") // ErrKeyResolverMismatch is returned by CompositeResolver when the // fingerprint sets returned by child resolvers do not match. ErrKeyResolverMismatch = errors.New("key resolvers returned mismatched trust sets") // fetch its keys (network failure, DNS, TLS) and RequireAll or // RequireExternalCrosscheck is true. ErrKeyResolverUnavailable = errors.New("key resolver unavailable") // ErrWKDResponseTooLarge is returned when a WKD response exceeds // MaxWKDResponseSize. ErrWKDResponseTooLarge = errors.New("WKD response exceeds maximum size") )
Sentinel errors raised by the signing primitives. Callers should match on these with errors.Is rather than string comparison.
var DefaultConfig []byte
var DefaultRequireChecksum = false
DefaultRequireChecksum is the compile-time default for checksum enforcement when neither config nor env var provides one. Tool authors should set this to true in main() for security-critical tools that want fail-closed verification from day one.
var ErrChecksumAssetNotFound = errors.New("asset not found in checksums manifest")
ErrChecksumAssetNotFound is returned when the target filename is not listed in the checksums manifest. The release may have been created without GoReleaser or with a non-default checksums layout.
var ErrChecksumManifestMalformed = errors.New("checksums manifest is malformed")
ErrChecksumManifestMalformed is returned when the checksums manifest does not conform to the expected GoReleaser format (`<sha256-hex> <filename>` per line). Rather than silently skip malformed lines, the parser rejects the entire manifest so a truncated or corrupted download never produces a false pass.
var ErrChecksumTooLarge = errors.New("download exceeds maximum size")
ErrChecksumTooLarge is returned when either the checksums manifest or the binary download exceeds its configured size bound. Indicates a hostile or misbehaving server; the update aborts before hashing.
Functions ¶
func AddCommandWithMiddleware
deprecated
func AddCommandWithMiddleware(parent, cmd *cobra.Command, feature props.FeatureCmd)
AddCommandWithMiddleware adds cmd as a subcommand of parent and wraps cmd.RunE with the middleware Chain for feature.
Deprecated: use Command.Register instead. AddCommandWithMiddleware remains as a thin shim that delegates to Register and will be removed in v1.0. Unlike the prior implementation it does NOT recursively re-wrap descendants with feature — each command should be wrapped with its own feature at construction (via Wrap) and added to its parent via the parent's Register method, which wires middleware exactly once per command.
func ApplyMiddlewareRecursively
deprecated
func ApplyMiddlewareRecursively(cmd *cobra.Command, feature props.FeatureCmd)
ApplyMiddlewareRecursively applies middleware to cmd and all of its descendants with the same feature key.
Deprecated: prefer wrapping each command with its own feature at construction (via Wrap) and registering subcommands via Command.Register, which wires middleware exactly once per command. ApplyMiddlewareRecursively remains for backward compatibility and will be removed in v1.0.
func Chain ¶
func Chain(feature props.FeatureCmd, runE func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error
Chain applies all registered middleware (global + feature-specific) to the given RunE function and returns the wrapped function.
func GetChecks ¶
func GetChecks() map[props.FeatureCmd][]CheckProvider
GetChecks returns a snapshot of all registered check providers.
func GetDefaultConfigDir ¶
GetDefaultConfigDir returns the default config directory for the named tool (~/.toolname/).
func GetFeatureFlags ¶
func GetFeatureFlags() map[props.FeatureCmd][]FeatureFlag
GetFeatureFlags returns a snapshot of all registered feature flag providers.
func GetInitialisers ¶
func GetInitialisers() map[props.FeatureCmd][]InitialiserProvider
GetInitialisers returns a snapshot of all registered initialiser providers.
func GetSubcommands ¶
func GetSubcommands() map[props.FeatureCmd][]SubcommandProvider
GetSubcommands returns a snapshot of all registered subcommand providers.
func GetTimeSinceLast ¶
GetTimeSinceLast returns the duration since the last update check or update.
func Initialise ¶
func Initialise(props *props.Props, opts InitOptions) (string, error)
Initialise creates the default configuration file in the specified directory.
func Register ¶
func Register(feature props.FeatureCmd, ips []InitialiserProvider, sps []SubcommandProvider, fps []FeatureFlag)
Register adds initialisers, subcommands, and flags for a specific feature. Panics if the registry has been sealed.
func RegisterChecks ¶
func RegisterChecks(feature props.FeatureCmd, cps []CheckProvider)
RegisterChecks adds diagnostic check providers for a specific feature. Panics if the registry has been sealed.
func RegisterGlobalMiddleware ¶
func RegisterGlobalMiddleware(mw ...Middleware)
RegisterGlobalMiddleware adds middleware that is applied to all feature commands. Global middleware runs before feature-specific middleware in the chain.
func RegisterMiddleware ¶
func RegisterMiddleware(feature props.FeatureCmd, mw ...Middleware)
RegisterMiddleware adds middleware that will be applied to commands belonging to the specified feature. Middleware is applied in registration order.
func ResetRegistryForTesting ¶
func ResetRegistryForTesting()
ResetRegistryForTesting clears both the middleware and feature registries. This should only be used in tests to avoid state leakage between test runs.
func Seal ¶
func Seal()
Seal prevents further middleware registration. Called after all commands have been registered.
func SealRegistry ¶
func SealRegistry()
SealRegistry prevents further feature registration. Called after all commands have been registered. Subsequent Register* calls will panic.
func SetTimeSinceLast ¶
SetTimeSinceLast records the current time as the last check or update timestamp.
func SkipUpdateCheck ¶
SkipUpdateCheck returns true if the update check should be skipped for this invocation.
func VerifyChecksum ¶
VerifyChecksum reads a SHA-256 sidecar file and verifies it against the provided data. The sidecar format is "<hex-hash> <filename>" (matching sha256sum output and GoReleaser checksums.txt entries). Returns nil if the checksum matches, or an error with a hint on mismatch.
Hash comparison uses subtle.ConstantTimeCompare on decoded bytes. This is defence-in-depth — practical timing attacks on checksum comparison of unknown binary content are infeasible, but the constant-time primitive eliminates the class of concern at near-zero cost and makes future audits simpler.
func VerifyChecksumFromManifest ¶
VerifyChecksumFromManifest verifies data against a named entry in a GoReleaser-style checksums manifest. The manifest format is one "<hex-sha256> <filename>" entry per line; blank lines are permitted at end-of-file. Every non-blank line must match the expected shape or the manifest is rejected as malformed.
Returns nil if the checksum matches, ErrChecksumAssetNotFound if the filename is not listed, ErrChecksumManifestMalformed on invalid syntax, or an error wrapping errors.WithHint on mismatch.
func VerifyChecksumFromManifestReader ¶
func VerifyChecksumFromManifestReader( manifest []byte, filename string, dataReader io.Reader, dst io.Writer, maxBytes int64, ) (int64, error)
VerifyChecksumFromManifestReader is the streaming equivalent of VerifyChecksumFromManifest. It computes the SHA-256 of dataReader while copying into dst, avoiding a second pass over multi-megabyte binary data.
maxBytes bounds the total copied; exceeding it returns ErrChecksumTooLarge. A typical caller passes MaxBinaryDownloadSize.
Returns the number of bytes copied on success, or an error on checksum mismatch, size-limit violation, or copy/IO failure. The manifest is parsed before any bytes are hashed, so a manifest- lookup failure aborts without touching dst.
func WKDURLs ¶ added in v0.12.0
WKDURLs derives the advanced and direct WKD URLs and the canonical advanced host ("openpgpkey.<domain>") for an email address, per draft-koch-openpgp-webkey-service. The advanced URL is the preferred fetch target; resolvers fall back to the direct URL on 404. Returns an error for malformed input (missing '@', empty local or domain).
Types ¶
type CheckFunc ¶
type CheckFunc func(ctx context.Context, props *props.Props) CheckResult
CheckFunc is the signature for individual diagnostic checks.
type CheckProvider ¶
CheckProvider is a function that returns diagnostic checks for a feature.
type CheckResult ¶
type CheckResult struct {
Name string `json:"name"`
Status string `json:"status"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}
CheckResult represents the outcome of a single diagnostic check.
type Command ¶ added in v0.5.0
type Command struct {
*cobra.Command
// Feature is the middleware lookup key. The empty string means "no
// feature-specific middleware" (global middleware still applies).
Feature props.FeatureCmd
}
Command composes cobra.Command with the middleware feature key it belongs to. The feature is the lookup key Chain uses to find feature-specific middleware (registered via RegisterMiddleware).
Composing rather than wrapping means callers can use any cobra.Command method directly (the embedded pointer satisfies the interface), and code that needs the raw *cobra.Command — e.g. to pass to a cobra API or store in a parent's Commands() slice — accesses it via .Command.
Commands are typically built via Wrap in each generated NewCmd<Name> constructor and attached to a parent via the parent's Command.Register method, which wires middleware automatically. See the `2026-05-30-command-composition-registration` spec.
func Wrap ¶ added in v0.5.0
func Wrap(feature props.FeatureCmd, cmd *cobra.Command) *Command
Wrap pairs a cobra command with the feature it belongs to. The returned *Command embeds cmd, so it behaves as a cobra.Command for every method cobra offers; .Command exposes the underlying pointer when the cobra API needs *cobra.Command directly.
func (*Command) Register ¶ added in v0.5.0
Register adds each child as a subcommand and wraps the child's RunE with the middleware Chain for the child's own feature.
Each child is wrapped exactly once, at the point its parent registers it. A child's own descendants are wired when the child registers them, so Register never re-wraps a subtree (unlike the legacy recursive ApplyMiddlewareRecursively path, which re-applied the parent's feature down the tree).
Children with a nil RunE (pure command groups) are still attached but receive no RunE-wrapping — there is nothing to wrap.
type CompositeResolver ¶ added in v0.12.0
type CompositeResolver struct {
Resolvers []KeyResolver
RequireAll bool
Logger logger.Logger
}
CompositeResolver wraps an ordered list of KeyResolvers and requires them to agree on the set of key fingerprints. It is the production default for tools that publish both an embedded key and an external (WKD) key: trust is only granted when both sources match, so an attacker must compromise both within the same window.
RequireAll controls the failure mode when a child resolver returns a non-mismatch error (network failure, weak key, malformed data):
- true — any child failure aborts with ErrKeyResolverUnavailable wrapping the first child's error. The fail-closed posture.
- false — child failures are logged at Warn and the composite returns the successful children's trust set, as long as at least one resolver succeeded. The fail-open posture, suitable for tools that tolerate WKD outages.
Fingerprint disagreement among successful resolvers always aborts with ErrKeyResolverMismatch, regardless of RequireAll: a mismatch means at least one trust anchor has been tampered with.
func (*CompositeResolver) Name ¶ added in v0.12.0
func (c *CompositeResolver) Name() string
Name returns "composite[<child1>,<child2>,...]" for diagnostics.
func (*CompositeResolver) Resolve ¶ added in v0.12.0
func (c *CompositeResolver) Resolve(ctx context.Context) (*TrustSet, error)
Resolve runs each child resolver concurrently with the supplied context and applies the RequireAll / fingerprint-agreement policy. Returns ErrKeyResolverUnavailable when no usable trust set survives, or ErrKeyResolverMismatch when multiple resolvers succeed with divergent fingerprint sets.
type FeatureFlag ¶
FeatureFlag is a function that registers flags on a cobra command.
type FeatureRegistry ¶
type FeatureRegistry struct {
// contains filtered or unexported fields
}
FeatureRegistry holds the registered initialisers, subcommands, flags, and checks for features. All access is serialised by registryMu so concurrent init() calls and parallel tests are race-free.
type InitOptions ¶
type InitOptions struct {
Dir string
Clean bool
SkipLogin bool
SkipKey bool
SkipAI bool
Initialisers []Initialiser
}
InitOptions holds the options for the Initialise function.
type Initialiser ¶
type Initialiser interface {
// Name returns a human-readable name for logging.
Name() string
// IsConfigured returns true if this initialiser's config is already present.
IsConfigured(cfg config.Containable) bool
// Configure runs the interactive config and writes values into cfg.
Configure(p *props.Props, cfg config.Containable) error
}
Initialiser is an optional config step that can check if it's already configured and, if not, interactively populate the shared viper config.
type InitialiserProvider ¶
type InitialiserProvider func(p *props.Props) Initialiser
InitialiserProvider is a function that creates an Initialiser.
type KeyResolver ¶ added in v0.12.0
type KeyResolver interface {
// Name returns a short identifier used in logs and diagnostics
// (e.g. "embedded", "wkd:openpgpkey.example.com", "composite").
Name() string
// Resolve returns the trust set for the current update attempt.
// Callers are responsible for caching where appropriate; Resolve
// may perform I/O on every call.
Resolve(ctx context.Context) (*TrustSet, error)
}
KeyResolver returns the TrustSet used to verify release signatures. Implementations may read embedded data, fetch over the network, or combine multiple sources with cross-checks. The interface separates "where the trust anchor comes from" from "how a signature is verified against it", so SelfUpdater can be wired with whichever resolver chain a tool needs without changing verification logic.
func BuildKeyResolver ¶ added in v0.12.0
func BuildKeyResolver(cfg KeyResolverConfig, embeddedKeys ...[]byte) (KeyResolver, error)
BuildKeyResolver maps a KeyResolverConfig and a set of embedded public keys onto a concrete KeyResolver:
- "embedded" → EmbeddedResolver(embeddedKeys). Errors without keys.
- "external" → WKDResolver(email). Errors without an email.
- "both" → CompositeResolver{Embedded, WKD} when both an email and keys are available; degrades to whichever single source is configured; errors when neither is.
Embedded keys are validated against the minimum-strength policy here (via the error-returning constructor) so a malformed or weak key is reported as an error rather than panicking mid-update.
Tool authors who want full control can call this directly and pass the result via WithKeyResolver; the convenience path is to supply raw keys via WithEmbeddedKeys and let SelfUpdater call this from NewUpdater.
func NewEmbeddedResolver ¶ added in v0.12.0
func NewEmbeddedResolver(armoredKeys ...[]byte) KeyResolver
NewEmbeddedResolver returns a KeyResolver backed by the supplied ASCII-armored public keys. The keys are parsed and validated against the minimum-strength policy at construction time; if any key is weak or any input fails to parse, the constructor panics. This matches the spec's "binary refuses to start" invariant for a weak or malformed embedded key: such a problem must surface at startup, not at the first update attempt.
Tool authors typically call this indirectly via an internal trustkeys helper that embeds the project's public keys with //go:embed and constructs the resolver at package init.
func NewWKDResolver ¶ added in v0.12.0
func NewWKDResolver(cfg WKDResolverConfig) (KeyResolver, error)
NewWKDResolver returns a KeyResolver that fetches a public key from the Web Key Directory derived from the supplied email. The hardened HTTPClient is mandatory: callers should construct it via pkg/http.NewClient so TLS 1.2+, certificate validation, the request timeout, and the HTTPS-downgrade redirect policy are enforced.
Resolve tries the advanced URL first and falls back to the direct URL only on HTTP 404 — any other failure (network, non-200, TLS, oversize, weak key) is returned to the caller and does not fall through to the direct URL.
type KeyResolverConfig ¶ added in v0.12.0
type KeyResolverConfig struct {
// KeySource is "embedded", "external", or "both". Empty defaults
// to "both".
KeySource string
// ExternalKeyEmail is the release email whose WKD directory holds
// the external key. Required for "external"; enables the WKD leg of
// "both" when set.
ExternalKeyEmail string
// RequireExternalCrosscheck maps to CompositeResolver.RequireAll:
// when true, a WKD fetch failure aborts the update instead of
// falling back to the embedded key.
RequireExternalCrosscheck bool
// HTTPClient is the hardened client used for WKD fetches. When nil,
// a default pkg/http.NewClient() is used.
HTTPClient *http.Client
// Logger receives CompositeResolver fail-open warnings. Optional.
Logger logger.Logger
}
KeyResolverConfig parameterises BuildKeyResolver. It is deliberately decoupled from Viper so tool authors and tests can construct it directly; SelfUpdater fills it from the resolved update.* config keys.
type Middleware ¶
type Middleware func(next func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error
Middleware wraps a cobra RunE function with additional behaviour. The middleware receives the next handler in the chain and returns a new handler that may execute logic before and/or after calling next.
func WithAuthCheck ¶
func WithAuthCheck(keys ...string) Middleware
WithAuthCheck returns middleware that validates the specified configuration keys are non-empty before allowing command execution. If any key is empty, a descriptive error is returned without executing the command.
func WithRecovery ¶
func WithRecovery(l logger.Logger) Middleware
WithRecovery returns middleware that catches panics in the command handler and converts them to errors. The panic value and stack trace are logged at Error level.
func WithTelemetry ¶
func WithTelemetry(p *props.Props) Middleware
WithTelemetry returns middleware that automatically tracks command invocations via the telemetry collector on Props. Records command name, duration, and exit code for every command execution. No-op when the collector is nil or telemetry is disabled (the collector is a noop in that case).
func WithTiming ¶
func WithTiming(l logger.Logger) Middleware
WithTiming returns middleware that logs command execution duration.
type SelfUpdater ¶
type SelfUpdater struct {
Tool props.Tool
CurrentVersion string
NextRelease release.Release
Fs afero.Fs
// contains filtered or unexported fields
}
SelfUpdater manages checking for and applying tool updates.
func NewOfflineUpdater ¶
func NewOfflineUpdater(tool props.Tool, log logger.Logger, fs afero.Fs, opts ...UpdaterOption) *SelfUpdater
NewOfflineUpdater creates a SelfUpdater configured for file-based updates that do not require a VCS client or network access.
func NewUpdater ¶
func NewUpdater(ctx context.Context, p *props.Props, version string, force bool, opts ...UpdaterOption) (*SelfUpdater, error)
NewUpdater creates a SelfUpdater configured with the tools release source. The context is forwarded to vcs.ResolveTokenContext for private-repository token resolution, so remote-store credential backends (Vault, SSM) honour the caller's deadline when fetching the release token.
func (*SelfUpdater) DownloadAsset ¶
func (s *SelfUpdater) DownloadAsset(ctx context.Context, asset release.ReleaseAsset) (bytes.Buffer, error)
DownloadAsset downloads the raw bytes of a release asset.
func (*SelfUpdater) GetCurrentVersion ¶
func (s *SelfUpdater) GetCurrentVersion() string
func (*SelfUpdater) GetLatestRelease ¶
func (*SelfUpdater) GetLatestVersionString ¶
func (s *SelfUpdater) GetLatestVersionString(ctx context.Context) (string, error)
func (*SelfUpdater) GetReleaseNotes ¶
GetReleaseNotes retrieves the release notes for releases between the specified 'from' and 'to' versions (inclusive).
func (*SelfUpdater) GetStructuredReleaseNotes ¶
func (s *SelfUpdater) GetStructuredReleaseNotes(ctx context.Context, from, to string, archive ...bytes.Buffer) (*changelog.Changelog, error)
GetStructuredReleaseNotes retrieves release notes between two versions and returns them as a parsed Changelog. If an archive buffer is provided, it attempts to extract a bundled CHANGELOG.md first, falling back to per-release API calls when the archive contains no changelog.
func (*SelfUpdater) IsLatestVersion ¶
IsLatestVersion checks if the current running binary is the latest version.
func (*SelfUpdater) SignatureAssetName ¶ added in v0.12.0
func (s *SelfUpdater) SignatureAssetName() string
SignatureAssetName returns the configured signature filename, or the GoReleaser default "checksums.txt.sig" when unset.
func (*SelfUpdater) Update ¶
func (s *SelfUpdater) Update(ctx context.Context) (string, error)
Update installs the latest version of the binary to the resolved target path.
func (*SelfUpdater) UpdateFromFile ¶
func (s *SelfUpdater) UpdateFromFile(filePath string) (string, error)
UpdateFromFile installs a binary from a local .tar.gz file. If a .sha256 sidecar file exists at filePath+".sha256", the checksum is verified before extraction. Returns the installation target path.
type SubcommandProvider ¶
SubcommandProvider is a function that creates a slice of cobra subcommands.
type TrustSet ¶ added in v0.12.0
type TrustSet struct {
// contains filtered or unexported fields
}
TrustSet is the collection of public keys that can validate update signatures. It is constructed by a KeyResolver per update attempt and is immutable once constructed: LoadTrustSet validates the strength policy at construction time so weak keys never enter the trust set even transiently.
func LoadTrustSet ¶ added in v0.12.0
LoadTrustSet parses one or more ASCII-armored public-key blobs and enforces the minimum-strength policy: Ed25519 keys are accepted, RSA keys are accepted at 3072 bits or stronger, everything else is rejected with ErrWeakKey. Any weak key in the input aborts the load, so weak keys cannot enter the trust set even transiently.
func (*TrustSet) Fingerprints ¶ added in v0.12.0
Fingerprints returns the 40-char uppercase hex fingerprints of every key in the trust set, sorted ascending so two TrustSets can be compared for equality by their fingerprint slices.
func (*TrustSet) VerifyManifestSignature ¶ added in v0.12.0
VerifyManifestSignature verifies an ASCII-armored detached signature against the checksums manifest using any key in the trust set.
Returns nil on the first successful verification. Returns ErrSignatureInvalid (via errors.Is) for an empty, malformed, or non-validating signature; the underlying parser error is wrapped for diagnostics but the sentinel is the contract the caller matches.
The error returned for a failed signature deliberately does not name the keys tried, so a caller that logs only the sentinel does not leak which key in the set rejected the signature.
type UpdaterOption ¶
type UpdaterOption func(*SelfUpdater)
UpdaterOption configures a SelfUpdater.
func WithEmbeddedKeys ¶ added in v0.12.0
func WithEmbeddedKeys(armoredKeys ...[]byte) UpdaterOption
WithEmbeddedKeys supplies the tool's embedded release public keys (in ASCII-armored form). NewUpdater builds the default resolver from these keys and the resolved update.key_source / external_key_email / require_external_crosscheck config. Ignored when WithKeyResolver is also supplied.
func WithExecLookPath ¶
func WithExecLookPath(fn func(string) (string, error)) UpdaterOption
WithExecLookPath overrides exec.LookPath for testing.
func WithKeyResolver ¶ added in v0.12.0
func WithKeyResolver(r KeyResolver) UpdaterOption
WithKeyResolver overrides the default key resolver used for signature verification. When set, the config-driven default (built from WithEmbeddedKeys and the update.key_source family) is bypassed entirely — the tool author owns the resolver chain.
func WithOsExecutable ¶
func WithOsExecutable(fn func() (string, error)) UpdaterOption
WithOsExecutable overrides os.Executable for testing.
type WKDResolverConfig ¶ added in v0.12.0
WKDResolverConfig parameterises NewWKDResolver. Email and HTTPClient are required; URLOverride is for tests pointing at a local TLS server (the canonical scheme+host is replaced, the WKD path+query from Email are preserved).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package ai provides factory functions that construct chat.ChatClient instances from Props configuration, resolving the configured provider (Claude, OpenAI, Gemini) and wiring API keys, model selection, and token limits for use in documentation generation and agentic verification loops.
|
Package ai provides factory functions that construct chat.ChatClient instances from Props configuration, resolving the configured provider (Claude, OpenAI, Gemini) and wiring API keys, model selection, and token limits for use in documentation generation and agentic verification loops. |
|
Package bitbucket implements the interactive setup wizard for Bitbucket Cloud authentication.
|
Package bitbucket implements the interactive setup wizard for Bitbucket Cloud authentication. |
|
Package github provides GitHub-specific setup helpers including token resolution from configuration and environment, and authenticated HTTP client construction for use with the GitHub API.
|
Package github provides GitHub-specific setup helpers including token resolution from configuration and environment, and authenticated HTTP client construction for use with the GitHub API. |
|
Package telemetry registers the telemetry initialiser with the setup system.
|
Package telemetry registers the telemetry initialiser with the setup system. |