gogs_runner/main.go
2022-06-26 10:40:11 +08:00

138 lines
3.0 KiB
Go

package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"strings"
"sync"
)
const (
path = "/"
logDir = ".log/"
perm = 0770
)
var (
configs = []Config{}
configsLock = &sync.RWMutex{}
home = os.Getenv("HOME") + "/"
logFile *os.File
)
func main() {
addr := flag.String("a", ":3001", "Address to listen on")
flag.Parse()
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
// 解析Payload
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Printf("Error reading request body: %v\n", err)
w.Write([]byte(fmt.Sprintf("Read body error: %s", err)))
return
}
var payload GogsPayload
err = json.Unmarshal(reqBody, &payload)
if err != nil {
log.Printf("Error unmarshalling request body: %v\n", err)
w.Write([]byte(fmt.Sprintf("Unmarshal body error: %s", err)))
return
}
log.Printf("Received: [Name] %s [Sender] %s", payload.Repository.FullName, payload.Sender.FullName)
// 寻找包含Signal的commit
for _, commit := range payload.Commits {
// 寻找配置
c := Config{
Path: home,
Script: "deploy.py",
Signal: "{D}",
}
for _, config := range configs {
if config.Repo == payload.Repository.FullName {
c.Repo = config.Repo
if config.Path != "" {
c.Path = config.Path
}
if config.Script != "" {
c.Script = config.Script
}
if config.Signal != "" {
c.Signal = config.Signal
}
break
}
}
// 包含部署信号
if strings.Contains(commit.Message, c.Signal) {
log.Printf("Commit: [SHA] %s [Message] %s", commit.ID, commit.Message)
log.Println("Ready to deploy")
if c.Repo == "" {
log.Println("Using default config")
}
projectPath := func() string {
hasPrefix := strings.HasPrefix(c.Path, "/")
hasSuffix := strings.HasSuffix(c.Path, "/")
base := ""
// 如果路径以/开头,则认为是绝对路径
if hasPrefix {
base = c.Path
} else {
base = home + c.Path
}
repoFmt := ""
if hasSuffix {
repoFmt = "%s/"
} else {
repoFmt = "/%s/"
}
return fmt.Sprintf(base+repoFmt, payload.Repository.Name)
}()
scriptPath := projectPath + c.Script
log.Printf("Running script: %s\n", scriptPath)
// 开始执行脚本
cmd := exec.Command(scriptPath)
cmd.Stdout = logFile
cmd.Stderr = logFile
cmd.Dir = projectPath
err = cmd.Run()
if err != nil {
log.Printf("Error running deploy script: %v\n", err)
w.Write([]byte(fmt.Sprintf("Deploy script error: %s", err)))
} else {
log.Print("Deploy finished\n\n")
w.Write([]byte("Deploy finished"))
}
return
}
}
log.Print("No deploy commit found\n\n")
w.Write([]byte("No deploy commit found. Skip."))
})
log.Println("Webhook service started at " + *addr)
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Println("Error starting webhook service: " + err.Error())
}
}