/
handler_download.go
65 lines (57 loc) · 2 KB
/
handler_download.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package server
import (
"context"
"fmt"
"net/http"
"strings"
"time"
"github.com/go-chi/chi/v5"
"github.com/go-semantic-release/plugin-registry/internal/metrics"
"github.com/google/go-github/v50/github"
"go.opencensus.io/stats"
"go.opencensus.io/tag"
)
func (s *Server) getLatestSemRelRelease(ctx context.Context) (*github.RepositoryRelease, error) {
semrelCacheKey := s.getCacheKeyWithPrefix(cacheKeyPrefixGitHub, "semantic-release/latest")
cachedLatestRelease, ok := s.getFromCache(ctx, semrelCacheKey)
if ok {
return cachedLatestRelease.(*github.RepositoryRelease), nil
}
err := s.ghSemaphore.Acquire(ctx, 1)
if err != nil {
return nil, fmt.Errorf("could not acquire semaphore")
}
defer s.ghSemaphore.Release(1)
latestRelease, _, err := s.ghClient.Repositories.GetLatestRelease(ctx, "go-semantic-release", "semantic-release")
if err != nil {
return nil, err
}
s.setInCache(ctx, semrelCacheKey, latestRelease, time.Minute*30)
return latestRelease, nil
}
func (s *Server) downloadLatestSemRelBinary(w http.ResponseWriter, r *http.Request) {
os := chi.URLParam(r, "os")
arch := chi.URLParam(r, "arch")
if os == "" || arch == "" {
s.writeJSONError(w, r, http.StatusBadRequest, fmt.Errorf("missing os or arch"))
return
}
latestRelease, err := s.getLatestSemRelRelease(r.Context())
if err != nil {
s.writeJSONError(w, r, http.StatusInternalServerError, err, "could not get latest release")
return
}
osArchIdentifier := strings.ToLower(fmt.Sprintf("%s_%s", os, arch))
for _, asset := range latestRelease.Assets {
if strings.Contains(asset.GetName(), osArchIdentifier) {
ctx, err := tag.New(r.Context(), tag.Upsert(metrics.TagOSArch, osArchIdentifier))
if err != nil {
s.log.Errorf("could not create context with tag: %v", err)
}
stats.Record(ctx, metrics.CounterSemRelDownloads.M(1))
http.Redirect(w, r, asset.GetBrowserDownloadURL(), http.StatusFound)
return
}
}
s.writeJSONError(w, r, http.StatusNotFound, fmt.Errorf("could not find binary for %s/%s", os, arch))
}