release.go 3.2 KB

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