fix webhook

This commit is contained in:
pavel 2026-05-15 00:26:57 +02:00
commit b7d4b8b182

View file

@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"net/url"
@ -21,7 +22,7 @@ func (a *App) handleDeployWebhook(w http.ResponseWriter, r *http.Request) {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
path := strings.TrimPrefix(r.URL.Path, "/api/webhooks/deploy/")
path := strings.Trim(strings.TrimPrefix(r.URL.Path, "/api/webhooks/deploy/"), "/")
parts := strings.Split(path, "/")
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
http.Error(w, "bad path", http.StatusBadRequest)
@ -37,17 +38,22 @@ func (a *App) handleDeployWebhook(w http.ResponseWriter, r *http.Request) {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
var payload struct {
Ref string `json:"ref"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "invalid json", http.StatusBadRequest)
ref, err := parseWebhookRef(r)
if err != nil {
http.Error(w, "invalid webhook payload", http.StatusBadRequest)
return
}
if payload.Ref != "refs/heads/main" {
ref = strings.TrimSpace(ref)
if ref == "" {
writeJSON(w, http.StatusAccepted, map[string]string{"status": "ignored", "reason": "no ref in payload"})
return
}
if ref != "refs/heads/main" && ref != "main" {
log.Printf("webhook ignored project_id=%d ref=%q", p.ID, ref)
writeJSON(w, http.StatusAccepted, map[string]string{"status": "ignored", "reason": "not main branch"})
return
}
log.Printf("webhook deploy accepted project_id=%d ref=%q", p.ID, ref)
if err := a.deployProjectFromMain(r.Context(), p); err != nil {
log.Printf("deploy failed project_id=%d err=%v", p.ID, err)
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -56,6 +62,31 @@ func (a *App) handleDeployWebhook(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]string{"status": "deployed"})
}
func parseWebhookRef(r *http.Request) (string, error) {
rawBody, err := io.ReadAll(r.Body)
if err != nil {
return "", err
}
var payload struct {
Ref string `json:"ref"`
}
if err := json.Unmarshal(rawBody, &payload); err == nil {
return payload.Ref, nil
}
formVals, err := url.ParseQuery(string(rawBody))
if err != nil {
return "", err
}
raw := strings.TrimSpace(formVals.Get("payload"))
if raw == "" {
return "", nil
}
if err := json.Unmarshal([]byte(raw), &payload); err != nil {
return "", err
}
return payload.Ref, nil
}
func (a *App) getProjectForWebhook(ctx context.Context, projectID int64, token string) (Project, error) {
var p Project
err := a.db.QueryRowContext(ctx, `SELECT p.id, p.user_id, p.name, p.slug, p.description, p.repo_url, p.service_name, p.route_host, p.workspace_id, w.name, w.unix_user, p.deploy_token, p.created_at