dockerhub.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package feed
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. )
  7. type dockerHubRepositoryTagsResponse struct {
  8. Results []struct {
  9. Name string `json:"name"`
  10. LastPushed string `json:"tag_last_pushed"`
  11. } `json:"results"`
  12. }
  13. const dockerHubReleaseNotesURLFormat = "https://hub.docker.com/r/%s/tags?name=%s"
  14. func fetchLatestDockerHubRelease(request *ReleaseRequest) (*AppRelease, error) {
  15. parts := strings.Split(request.Repository, "/")
  16. if len(parts) != 2 {
  17. return nil, fmt.Errorf("invalid repository name: %s", request.Repository)
  18. }
  19. httpRequest, err := http.NewRequest(
  20. "GET",
  21. fmt.Sprintf("https://hub.docker.com/v2/namespaces/%s/repositories/%s/tags", parts[0], parts[1]),
  22. nil,
  23. )
  24. if err != nil {
  25. return nil, err
  26. }
  27. if request.Token != nil {
  28. httpRequest.Header.Add("Authorization", "Bearer "+(*request.Token))
  29. }
  30. response, err := decodeJsonFromRequest[dockerHubRepositoryTagsResponse](defaultClient, httpRequest)
  31. if err != nil {
  32. return nil, err
  33. }
  34. if len(response.Results) == 0 {
  35. return nil, fmt.Errorf("no tags found for repository: %s", request.Repository)
  36. }
  37. tag := response.Results[0]
  38. return &AppRelease{
  39. Source: ReleaseSourceDockerHub,
  40. NotesUrl: fmt.Sprintf(dockerHubReleaseNotesURLFormat, request.Repository, tag.Name),
  41. Name: request.Repository,
  42. Version: tag.Name,
  43. TimeReleased: parseRFC3339Time(tag.LastPushed),
  44. }, nil
  45. }