release.go 3.3 KB

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