release.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package version
  2. import (
  3. "encoding/json"
  4. "io"
  5. "net/http"
  6. "time"
  7. "github.com/pkg/errors"
  8. )
  9. const (
  10. GithubLatestReleaseAPI = "https://api.github.com/repos/0xJacky/nginx-ui/releases/latest"
  11. GithubReleasesListAPI = "https://api.github.com/repos/0xJacky/nginx-ui/releases"
  12. )
  13. type TReleaseAsset struct {
  14. Name string `json:"name"`
  15. BrowserDownloadUrl string `json:"browser_download_url"`
  16. Size uint `json:"size"`
  17. }
  18. type TRelease struct {
  19. TagName string `json:"tag_name"`
  20. Name string `json:"name"`
  21. PublishedAt time.Time `json:"published_at"`
  22. Body string `json:"body"`
  23. Prerelease bool `json:"prerelease"`
  24. Assets []TReleaseAsset `json:"assets"`
  25. }
  26. func (t *TRelease) GetAssetsMap() (m map[string]TReleaseAsset) {
  27. m = make(map[string]TReleaseAsset)
  28. for _, v := range t.Assets {
  29. m[v.Name] = v
  30. }
  31. return
  32. }
  33. func getLatestRelease() (data TRelease, err error) {
  34. resp, err := http.Get(GithubLatestReleaseAPI)
  35. if err != nil {
  36. err = errors.Wrap(err, "service.getLatestRelease http.Get err")
  37. return
  38. }
  39. body, err := io.ReadAll(resp.Body)
  40. if err != nil {
  41. err = errors.Wrap(err, "service.getLatestRelease io.ReadAll err")
  42. return
  43. }
  44. defer resp.Body.Close()
  45. if resp.StatusCode != 200 {
  46. err = errors.New(string(body))
  47. return
  48. }
  49. err = json.Unmarshal(body, &data)
  50. if err != nil {
  51. err = errors.Wrap(err, "service.getLatestRelease json.Unmarshal err")
  52. return
  53. }
  54. return
  55. }
  56. func getLatestPrerelease() (data TRelease, err error) {
  57. resp, err := http.Get(GithubReleasesListAPI)
  58. if err != nil {
  59. err = errors.Wrap(err, "service.getLatestPrerelease http.Get err")
  60. return
  61. }
  62. body, err := io.ReadAll(resp.Body)
  63. if err != nil {
  64. err = errors.Wrap(err, "service.getLatestPrerelease io.ReadAll err")
  65. return
  66. }
  67. defer resp.Body.Close()
  68. if resp.StatusCode != 200 {
  69. err = errors.New(string(body))
  70. return
  71. }
  72. var releaseList []TRelease
  73. err = json.Unmarshal(body, &releaseList)
  74. if err != nil {
  75. err = errors.Wrap(err, "service.getLatestPrerelease json.Unmarshal err")
  76. return
  77. }
  78. latestDate := time.Time{}
  79. for _, release := range releaseList {
  80. if release.Prerelease && release.PublishedAt.After(latestDate) {
  81. data = release
  82. latestDate = release.PublishedAt
  83. }
  84. }
  85. return
  86. }
  87. func GetRelease(channel string) (data TRelease, err error) {
  88. stableRelease, err := getLatestRelease()
  89. if err != nil {
  90. return TRelease{}, err
  91. }
  92. switch channel {
  93. default:
  94. fallthrough
  95. case "stable":
  96. return stableRelease, nil
  97. case "prerelease":
  98. preRelease, err := getLatestPrerelease()
  99. if err != nil {
  100. return TRelease{}, err
  101. }
  102. // if preRelease is newer than stableRelease, return preRelease
  103. // otherwise return stableRelease
  104. if preRelease.PublishedAt.After(stableRelease.PublishedAt) {
  105. return preRelease, nil
  106. }
  107. return stableRelease, nil
  108. }
  109. }