talos-upgrade/pkg/release/list.go
2023-10-20 17:28:58 -04:00

91 lines
2.1 KiB
Go

package release
import (
"fmt"
"github.com/charmbracelet/bubbles/list"
"github.com/google/go-github/v55/github"
"golang.org/x/mod/semver"
)
// ImageFormat describes the format of the installer container image for the given release.
var ImageFormat = `ghcr.io/siderolabs/installer:%s`
type ListItem struct {
Release string
Note string
}
func (i *ListItem) Title() string {
return i.Release
}
func (i *ListItem) Description() string {
return i.Note
}
func (i *ListItem) FilterValue() string {
return i.Release
}
func (i *ListItem) Image() string {
return fmt.Sprintf(ImageFormat, i.Release)
}
func ToList(releases []*github.RepositoryRelease, lowestInstalled, highestInstalled string) list.Model {
items := make([]list.Item, len(releases))
nextRelease := FindNextRelease(releases, lowestInstalled, highestInstalled)
for i, r := range releases {
item := &ListItem{
Release: r.GetName(),
}
if semver.Compare(lowestInstalled, r.GetName()) == 0 {
item.Note = "lowest installed"
}
if semver.Compare(highestInstalled, r.GetName()) == 0 {
item.Note = "highest installed"
}
if semver.Compare(nextRelease, r.GetName()) == 0 {
item.Note = "recommended"
}
items[i] = item
}
return list.New(items, list.NewDefaultDelegate(), 0, 0)
}
func FindNextRelease(releases []*github.RepositoryRelease, lowestInstalled, highestInstalled string) string {
nextRelease := highestInstalled
// If we internally differ, we should upgrade everyone to the current highest installed release, first.
if lowestInstalled != highestInstalled {
return highestInstalled
}
for _, r := range releases {
if semver.Compare(highestInstalled, r.GetName()) > 0 { // if this release is older than or the same age as the current
// highest-installed release, ignore it
continue
}
// if we haven't selected a next-highest release yet, set us as it
if nextRelease == highestInstalled {
nextRelease = r.GetName()
continue
}
// If the "next" release is higher than this release, set this release to next, instead
if semver.Compare(nextRelease, r.GetName()) < 0 {
nextRelease = r.GetName()
}
}
return nextRelease
}