gofmt
This commit is contained in:
parent
2bb6d24546
commit
734eab3cfd
3 changed files with 129 additions and 130 deletions
|
@ -1,26 +1,26 @@
|
|||
package action
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Action struct {
|
||||
Build struct {
|
||||
Cmd string `yaml:"cmd"`
|
||||
} `yaml:"build,omitempty"`
|
||||
Deploy struct {
|
||||
Hosts []string `yaml:"hosts"`
|
||||
Artifacts map[string][]string `yaml:"artifacts"`
|
||||
Before map[string]string `yaml:"before,omitempty"`
|
||||
After map[string]string `yaml:"after,omitempty"`
|
||||
} `yaml:"deploy,omitempty"`
|
||||
Build struct {
|
||||
Cmd string `yaml:"cmd"`
|
||||
} `yaml:"build,omitempty"`
|
||||
Deploy struct {
|
||||
Hosts []string `yaml:"hosts"`
|
||||
Artifacts map[string][]string `yaml:"artifacts"`
|
||||
Before map[string]string `yaml:"before,omitempty"`
|
||||
After map[string]string `yaml:"after,omitempty"`
|
||||
} `yaml:"deploy,omitempty"`
|
||||
}
|
||||
|
||||
func Read(filename string) (*Action, error) {
|
||||
b, err := os.ReadFile(filename)
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading action: %w", err)
|
||||
}
|
||||
|
@ -31,4 +31,4 @@ func Read(filename string) (*Action, error) {
|
|||
}
|
||||
|
||||
return &a, nil
|
||||
}
|
||||
}
|
||||
|
|
225
main.go
225
main.go
|
@ -1,136 +1,135 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"os"
|
||||
"os/exec"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"hacklab.nilfm.cc/quartzgun/renderer"
|
||||
"hacklab.nilfm.cc/quartzgun/router"
|
||||
. "hacklab.nilfm.cc/quartzgun/util"
|
||||
|
||||
"hacklab.nilfm.cc/quartzgun/renderer"
|
||||
"hacklab.nilfm.cc/quartzgun/router"
|
||||
. "hacklab.nilfm.cc/quartzgun/util"
|
||||
|
||||
"forge.lightcrystal.systems/lightcrystal/memnarch/action"
|
||||
"forge.lightcrystal.systems/lightcrystal/memnarch/webhook"
|
||||
"forge.lightcrystal.systems/lightcrystal/memnarch/action"
|
||||
"forge.lightcrystal.systems/lightcrystal/memnarch/webhook"
|
||||
)
|
||||
|
||||
func decode(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
data := make(map[string]interface{})
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&data)
|
||||
|
||||
if err == nil {
|
||||
AddContextValue(req, "data", data)
|
||||
} else {
|
||||
AddContextValue(req, "data", err.Error())
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
data := make(map[string]interface{})
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&data)
|
||||
|
||||
if err == nil {
|
||||
AddContextValue(req, "data", data)
|
||||
} else {
|
||||
AddContextValue(req, "data", err.Error())
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
||||
|
||||
func runJob(secret string, next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
// validate signature
|
||||
_, err := webhook.Verify([]byte(secret), req)
|
||||
if err != nil {
|
||||
w.WriteHeader(422)
|
||||
return
|
||||
}
|
||||
// get repo from data
|
||||
data := req.Context().Value("data").(map[string]interface{})
|
||||
if data != nil {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
repoUrl := data["repository"].(map[string]interface{})["clone_url"].(string)
|
||||
owner := data["owner"].(map[string]interface{})["login"].(string)
|
||||
repo := data["repository"].(map[string]interface{})["name"].(string)
|
||||
obj := data["head_commit"].(map[string]interface{})["id"].(string)
|
||||
|
||||
// create working dir
|
||||
workingDir := filepath.Join("working", owner, repo, obj)
|
||||
if (os.MkdirAll(workingDir, 0750) != nil) {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
|
||||
// from this point on we can tell the client they succeeded
|
||||
|
||||
// so we run the rest in a goroutine...
|
||||
go func() {
|
||||
// cd and checkout repo
|
||||
clone := exec.Command("git", "clone", repoUrl)
|
||||
clone.Dir = workingDir
|
||||
|
||||
err := clone.Run()
|
||||
if err != nil {
|
||||
// clone error - log it and quit
|
||||
return
|
||||
}
|
||||
// read memnarch action file
|
||||
urlParams := req.Context().Value("params").(map[string]string)
|
||||
jobName := urlParams["job"]
|
||||
|
||||
jobFile := filepath.Join(workingDir, repo, jobName + ".yml")
|
||||
a, err := action.Read(jobFile)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
|
||||
// decode and perform action
|
||||
// build
|
||||
buildCmd := exec.Command(a.Build.Cmd)
|
||||
buildCmd.Dir = filepath.Join(workingDir, repo)
|
||||
|
||||
// pre-deploy
|
||||
// deploy
|
||||
// post-deploy
|
||||
}()
|
||||
|
||||
AddContextValue(req, "data", "job submitted")
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
// validate signature
|
||||
_, err := webhook.Verify([]byte(secret), req)
|
||||
if err != nil {
|
||||
w.WriteHeader(422)
|
||||
return
|
||||
}
|
||||
// get repo from data
|
||||
data := req.Context().Value("data").(map[string]interface{})
|
||||
if data != nil {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
repoUrl := data["repository"].(map[string]interface{})["clone_url"].(string)
|
||||
owner := data["owner"].(map[string]interface{})["login"].(string)
|
||||
repo := data["repository"].(map[string]interface{})["name"].(string)
|
||||
obj := data["head_commit"].(map[string]interface{})["id"].(string)
|
||||
|
||||
// create working dir
|
||||
workingDir := filepath.Join("working", owner, repo, obj)
|
||||
if os.MkdirAll(workingDir, 0750) != nil {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
|
||||
// from this point on we can tell the client they succeeded
|
||||
|
||||
// so we run the rest in a goroutine...
|
||||
go func() {
|
||||
// cd and checkout repo
|
||||
clone := exec.Command("git", "clone", repoUrl)
|
||||
clone.Dir = workingDir
|
||||
|
||||
err := clone.Run()
|
||||
if err != nil {
|
||||
// clone error - log it and quit
|
||||
return
|
||||
}
|
||||
// read memnarch action file
|
||||
urlParams := req.Context().Value("params").(map[string]string)
|
||||
jobName := urlParams["job"]
|
||||
|
||||
jobFile := filepath.Join(workingDir, repo, jobName+".yml")
|
||||
a, err := action.Read(jobFile)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
|
||||
// decode and perform action
|
||||
// build
|
||||
buildCmd := exec.Command(a.Build.Cmd)
|
||||
buildCmd.Dir = filepath.Join(workingDir, repo)
|
||||
|
||||
// pre-deploy
|
||||
// deploy
|
||||
// post-deploy
|
||||
}()
|
||||
|
||||
AddContextValue(req, "data", "job submitted")
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
||||
|
||||
func seeJobsForRepo(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
})
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
func seeJobsForObject(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
})
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
func run(args []string) error {
|
||||
secret := args[1]
|
||||
secret := args[1]
|
||||
|
||||
rtr := &router.Router{
|
||||
Fallback: *template.Must(template.ParseFiles("templates/error.html")),
|
||||
}
|
||||
|
||||
rtr.Post("/echo", decode(renderer.JSON("data")))
|
||||
rtr.Post(`/do/(?P<job>\S+)`, decode(runJob(secret, renderer.JSON("data"))))
|
||||
rtr.Get(`/status/(?P<owner>[^/]+)/(?P<repo>\S+)`, seeJobsForRepo(renderer.JSON("data")))
|
||||
rtr.Get(`/status/(?P<owner>[^/]+)/(?P<repo>[^/]+)/(?P<object>\S+)`, seeJobsForObject(renderer.JSON("data")))
|
||||
|
||||
http.ListenAndServe(":9999", rtr);
|
||||
return nil
|
||||
rtr := &router.Router{
|
||||
Fallback: *template.Must(template.ParseFiles("templates/error.html")),
|
||||
}
|
||||
|
||||
rtr.Post("/echo", decode(renderer.JSON("data")))
|
||||
rtr.Post(`/do/(?P<job>\S+)`, decode(runJob(secret, renderer.JSON("data"))))
|
||||
rtr.Get(`/status/(?P<owner>[^/]+)/(?P<repo>\S+)`, seeJobsForRepo(renderer.JSON("data")))
|
||||
rtr.Get(`/status/(?P<owner>[^/]+)/(?P<repo>[^/]+)/(?P<object>\S+)`, seeJobsForObject(renderer.JSON("data")))
|
||||
|
||||
http.ListenAndServe(":9999", rtr)
|
||||
return nil
|
||||
}
|
||||
|
||||
func main () {
|
||||
err := run(os.Args)
|
||||
if err == nil {
|
||||
os.Exit(0)
|
||||
} else {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
func main() {
|
||||
err := run(os.Args)
|
||||
if err == nil {
|
||||
os.Exit(0)
|
||||
} else {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
|
||||
type Hook struct {
|
||||
Signature string
|
||||
Payload []byte
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
const signaturePrefix = ""
|
||||
const signatureLength = len(signaturePrefix) + 64
|
||||
const signatureLength = len(signaturePrefix) + 64
|
||||
|
||||
func signBody(secret, body []byte) []byte {
|
||||
computed := hmac.New(sha256.New, secret)
|
||||
|
@ -62,4 +62,4 @@ func Verify(secret []byte, req *http.Request) (hook *Hook, err error) {
|
|||
err = errors.New("Invalid signature")
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue