autogits/prjgit-updater/main.go

165 lines
4.5 KiB
Go
Raw Normal View History

2024-07-07 21:08:41 +02:00
package main
import (
"errors"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"src.opensuse.org/autogits/common"
)
const (
GitAuthor = "GiteaBot - AutoDevel"
BotName = "prjgit-updater"
)
var GiteaToken string
type ClonedRepository struct {
}
type RequestHandler struct {
r *common.RequestHandler
}
func (rw *RequestHandler) processRepositoryAction() {
h := rw.r
if h.HasError() {
return
}
action := h.Request.Data.(common.RepositoryAction)
if action.Repository.Name == "_ObsPrj" {
h.Log("repository event %s for _ObsPrj. Ignoring", action.Action)
return
}
h.CreateRepositoryIfNotExist(action.Organization, common.DefaultGitPrj)
if stat, err := os.Stat(filepath.Join(h.GitPath, common.DefaultGitPrj)); err != nil || !stat.IsDir() {
if errors.Is(err, os.ErrNotExist) {
h.GitExec("", "clone", "--depth", "1", action.PrjGit, common.DefaultGitPrj)
}
}
switch action.Action {
case "created":
h.GitExec(common.DefaultGitPrj, "submodule", "--quiet", "add", "--depth", "1", action.Repository.Clone_Url)
h.GitExec(common.DefaultGitPrj, "commit", "-m", "Automatic package inclusion")
h.GitExec(common.DefaultGitPrj, "push")
case "deleted":
if stat, err := os.Stat(filepath.Join(h.GitPath, common.DefaultGitPrj, action.Repository.Name)); err != nil || !stat.IsDir() {
h.Log("delete event for %s -- not in project. Ignoring", action.Repository.Name)
return
}
h.GitExec(common.DefaultGitPrj, "rm", action.Repository.Name)
h.GitExec(common.DefaultGitPrj, "commit", "-m", "Automatic package removal")
h.GitExec(common.DefaultGitPrj, "push")
default:
h.LogError("%s: %s", "Unknown action type", action.Action)
}
}
func (rw *RequestHandler) processPushAction() {
h := rw.r
if h.HasError() {
return
}
action := h.Request.Data.(common.PushRequest)
if action.Repository.Name == "_ObsPrj" {
h.Log("push to _ObsPrj -- ignoring")
return
}
h.GitExec("", "clone", "--depth", "1", h.PrjGit, common.DefaultGitPrj)
if stat, err := os.Stat(filepath.Join(h.GitPath, common.DefaultGitPrj, action.Repository.Name)); err != nil || !stat.IsDir() {
h.Error = fmt.Errorf("Pushed to package that is not part of the project. Ignoring.")
h.LogError("%v: %v", h.Error, err)
return
}
h.GitExec(common.DefaultGitPrj, "submodule", "update", "--init", "--depth", "1", "--checkout", action.Repository.Name)
id, _ := h.GitBranchHead(filepath.Join(common.DefaultGitPrj, action.Repository.Name), action.Repository.Default_Branch)
for _, commitId := range action.Commits {
if commitId.Id == id {
h.GitExec(filepath.Join(common.DefaultGitPrj, action.Repository.Name), "fetch", "--depth", "1", "origin", id)
h.GitExec(filepath.Join(common.DefaultGitPrj, action.Repository.Name), "checkout", id)
h.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", "Automatic update via push")
h.GitExec(common.DefaultGitPrj, "push")
return
}
}
h.Log("push of refs not on the main branch. ignoring.")
}
func createListenServer() {
http.HandleFunc("/" + BotName, func(res http.ResponseWriter, req *http.Request) {
var h RequestHandler;
h.r = common.CreateRequestHandler(GitAuthor, BotName)
// defer h.Close()
if len(req.Header.Get("Content-Type")) == 0 ||
req.Header["Content-Type"][0] != "application/json" ||
req.Method != "POST" {
h.r.WriteError()
res.WriteHeader(http.StatusInternalServerError)
return
}
hdr := req.Header[common.GiteaRequestHeader]
if len(hdr) != 1 {
h.r.LogError("Unsupported number of %s headers: %d: %#v\n", common.GiteaRequestHeader, len(hdr), hdr)
h.r.WriteError()
res.WriteHeader(http.StatusInternalServerError)
return
}
reqType := hdr[0]
switch reqType {
case "repository":
h.r.ParseRepositoryRequest(req.Body)
h.processRepositoryAction()
case "push":
h.r.ParsePushRequest(req.Body)
h.processPushAction()
default:
h.r.LogError("Unsupported request type: %s", reqType)
res.WriteHeader(http.StatusInternalServerError)
}
if h.r.HasError() {
h.r.WriteError()
res.WriteHeader(http.StatusInternalServerError)
return
}
res.Header().Add("Content-Type", "application/json")
res.WriteHeader(http.StatusOK)
})
log.Fatal(http.ListenAndServe("[::1]:8000", nil))
}
func parseGiteaSecretToken() error {
GiteaToken = os.Getenv(common.GiteaTokenEnv)
if len(GiteaToken) < 10 {
return errors.New(common.GiteaTokenEnv + " not provided")
}
err := os.Setenv(common.GiteaTokenEnv, "")
if err != nil {
return fmt.Errorf("%s: %v", "Cannot reset "+common.GiteaTokenEnv, err)
}
return nil
}
func main() {
parseGiteaSecretToken()
createListenServer()
}