Small HTTP server that redirects to artifacts from the latest github release for a project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package main
  2. import (
  3. "context"
  4. "flag"
  5. "fmt"
  6. "github.com/google/go-github/github"
  7. "log"
  8. "net/http"
  9. "os"
  10. "os/signal"
  11. "strings"
  12. "syscall"
  13. "time"
  14. )
  15. var (
  16. owner string
  17. repo string
  18. ctx context.Context
  19. client *github.Client
  20. release *github.RepositoryRelease
  21. )
  22. func fetchLatest() {
  23. latest, _, err := client.Repositories.GetLatestRelease(ctx, owner, repo)
  24. if err != nil {
  25. log.Println("Error retrieving latest release", err)
  26. return
  27. }
  28. release = latest
  29. }
  30. func serve(w http.ResponseWriter, request *http.Request) {
  31. if release == nil {
  32. w.WriteHeader(http.StatusInternalServerError)
  33. _, _ = fmt.Fprint(w, "Unknown release")
  34. return
  35. }
  36. for _, asset := range release.Assets {
  37. if "/" + *asset.Name == request.RequestURI {
  38. w.Header().Add("Location", *asset.BrowserDownloadURL)
  39. w.WriteHeader(http.StatusTemporaryRedirect)
  40. return
  41. }
  42. }
  43. w.WriteHeader(http.StatusNotFound)
  44. _, _ = fmt.Fprint(w, "Asset not found in release ", *release.Name)
  45. }
  46. func main() {
  47. var fullRepo = flag.String("repo", "", "the repository to redirect releases for, in user/repo format")
  48. var port = flag.Int("port", 8080, "the port to listen on for HTTP requests")
  49. flag.Parse()
  50. if strings.Count(*fullRepo, "/") != 1 {
  51. log.Println("Repository must be specified in user/repo format")
  52. return
  53. }
  54. repoParts := strings.Split(*fullRepo, "/")
  55. owner = repoParts[0]
  56. repo = repoParts[1]
  57. client = github.NewClient(nil)
  58. ticker := time.NewTicker(time.Hour)
  59. go func() {
  60. fetchLatest()
  61. for range ticker.C {
  62. fetchLatest()
  63. }
  64. }()
  65. var cancel context.CancelFunc
  66. ctx, cancel = context.WithCancel(context.Background())
  67. c := make(chan os.Signal, 1)
  68. signal.Notify(c, os.Interrupt)
  69. signal.Notify(c, syscall.SIGTERM)
  70. go func() {
  71. for sig := range c {
  72. cancel()
  73. ticker.Stop()
  74. log.Printf("Received %s, exiting.", sig.String())
  75. os.Exit(0)
  76. }
  77. }()
  78. log.Printf("Listing on :%d", *port)
  79. server := &http.Server{
  80. Addr: fmt.Sprintf(":%d", *port),
  81. Handler: http.HandlerFunc(serve),
  82. }
  83. err := server.ListenAndServe()
  84. if err != nil {
  85. log.Println("Error listening for requests on port ", port, err)
  86. }
  87. }