package main import ( "encoding/json" "fmt" "net/http" ) type GitHubVersionProvider struct { Repository string IncludeDrafts bool IncludePrereleases bool } type GitHubRelease struct { TagName string `json:"tag_name"` Draft bool `json:"draft"` Prerelease bool `json:"prerelease"` Body string `json:"body"` } func (g GitHubRelease) String() string { return g.TagName } func (g *GitHubVersionProvider) GetVersion() (Version, error) { url := fmt.Sprintf("https://api.github.com/repos/%s/releases", g.Repository) r, err := http.Get(url) if err != nil { return nil, fmt.Errorf("couldn't fetch release list for %s from GitHub: %w", g.Repository, err) } defer r.Body.Close() var releases []GitHubRelease err = json.NewDecoder(r.Body).Decode(&releases) if err != nil { return nil, fmt.Errorf("couldn't parse json: %w", err) } for _, release := range releases { if release.Draft && !g.IncludeDrafts { continue } if release.Prerelease && !g.IncludePrereleases { continue } return &release, nil } return nil, fmt.Errorf("couldn't find any suitable release on GitHub for project %s", g.Repository) }