// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. package lib import ( "encoding/json" "errors" "fmt" "io" "net/http" "path" ) type WebhookCFG struct { Forgejo PageDir string GitDir string GitUser string GitPass string ch chan<- repoSpec } type webhookPayload struct { Ref string `json:"ref"` Repository struct { FullName string `json:"full_name"` } `json:"repository"` } func (c *WebhookCFG) handle(w http.ResponseWriter, r *http.Request) { fmt.Println("Received webhook event") ev := r.Header.Get("X-GitHub-Event") if ev != "push" { // skip non-push events fmt.Println("Skip non-push event: ", ev) return } defer r.Body.Close() data, err := io.ReadAll(r.Body) if err != nil { fmt.Println("Failed to read request body: ", err) return } var payload webhookPayload err = json.Unmarshal(data, &payload) if err != nil { fmt.Println("Failed to parse request body: ", err) fmt.Println("=========== Dump body: ============") fmt.Println(string(data)) fmt.Println("===================================") return } if payload.Ref != "refs/heads/"+c.Branch { // skip non-branch events fmt.Println("Skip different branch: ", payload.Ref) return } user, repo := path.Split(payload.Repository.FullName) user = user[:len(user)-1] go func() { c.ch <- repoSpec{user: user, name: repo} }() } func UseWebhook(bind string, cfg *WebhookCFG) (*http.Server, *GitRunner, error) { if cfg == nil { return nil, nil, errors.New("webhook config is nil") } s := &http.Server{ Addr: bind, Handler: http.HandlerFunc(cfg.handle), } ch := make(chan repoSpec, 5) cfg.ch = ch return s, &GitRunner{ch: ch, cfg: cfg}, nil }