feat(pi): update to the latest stable release by default

This commit is contained in:
2026-08-16 00:13:51 +02:00
parent 0cb6a3f915
commit 5a657a67e8
6 changed files with 586 additions and 55 deletions
+17 -4
View File
@@ -9,7 +9,6 @@ import (
"io"
"os"
"path/filepath"
"regexp"
"runtime"
"sort"
"strings"
@@ -24,7 +23,6 @@ var (
ErrActiveSessions = errors.New("active sessions must be drained before updating Pi; use --drain only after they are complete")
ErrInterruptedUpdate = errors.New("a previous Pi update is incomplete; run pi rollback --yes before starting another update")
ErrInvalidRequest = errors.New("invalid Pi lifecycle request")
versionPattern = regexp.MustCompile(`^[0-9]+(?:\.[0-9]+){1,3}(?:[-+][0-9A-Za-z.-]+)?$`)
)
// Source chooses whether the candidate is built from this checkout or pulled from an immutable image.
@@ -50,6 +48,7 @@ type Request struct {
type Result struct {
Phase Phase
StatePath string
Version string
}
type lifecycleHooks struct {
@@ -69,6 +68,20 @@ func Update(ctx context.Context, runner Runner, request Request) (result Result,
return updateWithHooks(ctx, runner, request, defaultLifecycleHooks)
}
// UpdateWithResolvedVersion resolves a requested version before Update obtains its lifecycle lock
// or contacts Docker. A registry failure therefore cannot drain sessions, write state, or mutate
// images and configuration.
func UpdateWithResolvedVersion(ctx context.Context, runner Runner, request Request, packageName string, registry RegistryClient) (Result, error) {
version, err := ResolveRequestedVersion(ctx, request.Version, packageName, registry)
if err != nil {
return Result{StatePath: request.StatePath}, err
}
request.Version = version
result, err := Update(ctx, runner, request)
result.Version = version
return result, err
}
func updateWithHooks(ctx context.Context, runner Runner, request Request, hooks lifecycleHooks) (result Result, retErr error) {
if request.StatePath == "" {
return Result{}, errors.New("update state path is required")
@@ -87,8 +100,8 @@ func updateWithHooks(ctx context.Context, runner Runner, request Request, hooks
if !request.Confirm {
return Result{StatePath: request.StatePath}, ErrConfirmationRequired
}
if !versionPattern.MatchString(request.Version) {
return Result{StatePath: request.StatePath}, fmt.Errorf("%w: Pi version must be an explicit pinned version", ErrInvalidRequest)
if _, err := parseSemanticVersion(request.Version); err != nil {
return Result{StatePath: request.StatePath}, fmt.Errorf("%w: %v", ErrInvalidRequest, err)
}
if request.Source == "" {
return Result{StatePath: request.StatePath}, fmt.Errorf("%w: Pi update requires an explicit source: build or pull", ErrInvalidRequest)