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 }