pr-deployer/routers/routers.go

192 lines
3.9 KiB
Go

package routers
import (
"context"
"fmt"
"io"
"io/fs"
"net/http"
"path/filepath"
"strconv"
"gitea.com/gitea/pr-deployer/pkgs/services"
"gitea.com/gitea/pr-deployer/pkgs/settings"
"golang.org/x/oauth2"
"gitea.com/go-chi/session"
logger "github.com/chi-middleware/logrus-logger"
"github.com/go-chi/chi/v5"
"github.com/google/go-github/v39/github"
log "github.com/sirupsen/logrus"
"github.com/unrolled/render"
)
var rnd *render.Render
type tmplFS struct {
fs.FS
}
func (tfs tmplFS) Walk(root string, walkFn filepath.WalkFunc) error {
return fs.WalkDir(tfs, root, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
info, err := d.Info()
return walkFn(path, info, err)
})
}
func (tfs tmplFS) ReadFile(filename string) ([]byte, error) {
f, err := tfs.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
return io.ReadAll(f)
}
func convertFS(templateFS fs.FS) render.FileSystem {
return tmplFS{templateFS}
}
func Web(publicFS, templateFS fs.FS) {
rnd = render.New(render.Options{
Directory: ".",
IsDevelopment: true,
FileSystem: convertFS(templateFS),
})
c := chi.NewRouter()
c.Use(session.Sessioner())
c.Use(logger.Logger("router", log.StandardLogger()))
c.Get("/", Home)
c.Get("/callback", OAuth2Callback)
c.Get("/prs", ListPRs)
c.Post("/pr/{index}/run", RunPR)
c.Post("/pr/{index}/stop", StopPR)
c.Post("/webhook", Webhook)
fs := http.StripPrefix("/public", http.FileServer(http.FS(publicFS)))
c.Get("/public/*", func(w http.ResponseWriter, r *http.Request) {
fs.ServeHTTP(w, r)
})
http.ListenAndServe(":3001", c)
}
func ListPRs(w http.ResponseWriter, r *http.Request) {
sess := session.GetSession(r)
pToken := sess.Get("token")
if pToken == nil {
http.Redirect(w, r, "/", 302)
return
}
p, _ := strconv.Atoi(r.FormValue("p"))
if p < 1 {
p = 1
}
token := pToken.(*oauth2.Token)
fmt.Printf("%#v\n", token)
c, err := services.NewClient(token)
if err != nil {
log.Error(err)
return
}
pulls, err := c.GetPullRequests(p)
if err != nil {
log.Error(err)
return
}
user := sess.Get("user")
if err := rnd.HTML(w, http.StatusOK, "pulls", map[string]interface{}{
"pulls": pulls,
"user": user,
}); err != nil {
log.Error(err)
}
}
func RunPR(w http.ResponseWriter, r *http.Request) {
idx := chi.URLParam(r, "index")
i, _ := strconv.Atoi(idx)
if i <= 0 {
log.Errorf("start failed: %s is not a valid index", idx)
return
}
ctx := context.Background()
sess := session.GetSession(r)
pToken := sess.Get("token")
if pToken == nil {
http.Redirect(w, r, "/", 302)
return
}
token := pToken.(*oauth2.Token)
fmt.Printf("%#v\n", token)
client, err := services.NewClient(token)
if err != nil {
log.Error(err)
return
}
if err := services.UpdateAndStartPullRequest(ctx, client, i, ""); err != nil {
log.Error(err)
}
}
func StopPR(w http.ResponseWriter, r *http.Request) {
idx := chi.URLParam(r, "index")
i, _ := strconv.Atoi(idx)
if i <= 0 {
log.Error("stop failed")
return
}
if err := services.StopPullRequest(i); err != nil {
log.Error("stop failed")
}
}
func Webhook(w http.ResponseWriter, r *http.Request) {
payload, err := github.ValidatePayload(r, settings.WebhookSecretKey)
if err != nil {
log.Error(err)
return
}
event, err := github.ParseWebHook(github.WebHookType(r), payload)
if err != nil {
log.Error(err)
return
}
switch evt := event.(type) {
case *github.PullRequestEvent:
switch *evt.Action {
case "synchronize":
ctx := context.Background()
// FIXME: get token
client, err := services.NewClient(nil)
if err != nil {
log.Error(err)
return
}
if err := services.UpdateAndStartPullRequest(ctx, client, *evt.Number, *evt.After); err != nil {
log.Error(err)
}
default:
log.Trace("pull request %d is %s", *evt.Number, *evt.Action)
}
default:
log.Warn("received %v type event, ignored", event)
}
}