releases.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package feed
  2. import (
  3. "errors"
  4. "fmt"
  5. "log/slog"
  6. )
  7. type ReleaseSource string
  8. const (
  9. ReleaseSourceGithub ReleaseSource = "github"
  10. ReleaseSourceGitlab ReleaseSource = "gitlab"
  11. ReleaseSourceDockerHub ReleaseSource = "dockerhub"
  12. )
  13. type ReleaseRequest struct {
  14. Source ReleaseSource
  15. Repository string
  16. Token *string
  17. }
  18. func FetchLatestReleases(requests []*ReleaseRequest) (AppReleases, error) {
  19. job := newJob(fetchLatestReleaseTask, requests).withWorkers(20)
  20. results, errs, err := workerPoolDo(job)
  21. if err != nil {
  22. return nil, err
  23. }
  24. var failed int
  25. releases := make(AppReleases, 0, len(requests))
  26. for i := range results {
  27. if errs[i] != nil {
  28. failed++
  29. slog.Error("Failed to fetch release", "source", requests[i].Source, "repository", requests[i].Repository, "error", errs[i])
  30. continue
  31. }
  32. releases = append(releases, *results[i])
  33. }
  34. if failed == len(requests) {
  35. return nil, ErrNoContent
  36. }
  37. releases.SortByNewest()
  38. if failed > 0 {
  39. return releases, fmt.Errorf("%w: could not get %d releases", ErrPartialContent, failed)
  40. }
  41. return releases, nil
  42. }
  43. func fetchLatestReleaseTask(request *ReleaseRequest) (*AppRelease, error) {
  44. switch request.Source {
  45. case ReleaseSourceGithub:
  46. return fetchLatestGithubRelease(request)
  47. case ReleaseSourceGitlab:
  48. return fetchLatestGitLabRelease(request)
  49. case ReleaseSourceDockerHub:
  50. return fetchLatestDockerHubRelease(request)
  51. }
  52. return nil, errors.New("unsupported source")
  53. }