89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package app
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"os/exec"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func validateEnvKey(key string) error {
|
|
if key == "" {
|
|
return fmt.Errorf("key is required")
|
|
}
|
|
if !regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`).MatchString(key) {
|
|
return fmt.Errorf("invalid env key format")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func isValidRepoURL(s string) bool {
|
|
return strings.HasPrefix(s, "https://") || strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "ssh://") || strings.HasPrefix(s, "git@")
|
|
}
|
|
|
|
func escapeEnvValue(v string) string { return strconv.Quote(v) }
|
|
|
|
func slugify(s string) string {
|
|
s = strings.ToLower(strings.TrimSpace(s))
|
|
s = regexp.MustCompile(`[^a-z0-9]+`).ReplaceAllString(s, "-")
|
|
return strings.Trim(s, "-")
|
|
}
|
|
|
|
func writeJSON(w http.ResponseWriter, status int, data any) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(status)
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
}
|
|
|
|
func mustJSONPretty(data any) string {
|
|
b, err := json.MarshalIndent(data, "", " ")
|
|
if err != nil {
|
|
return "{}"
|
|
}
|
|
return string(b)
|
|
}
|
|
|
|
func (a *App) deployWebhookURL(projectID int64, token, userToken string) string {
|
|
if token == "" || userToken == "" {
|
|
return ""
|
|
}
|
|
path := fmt.Sprintf("/api/webhooks/deploy/%d/%s?ut=%s", projectID, token, url.QueryEscape(userToken))
|
|
if a.cfg.WebhookBaseURL != "" {
|
|
return a.cfg.WebhookBaseURL + path
|
|
}
|
|
return path
|
|
}
|
|
|
|
func (a *App) appURL(routeHost string) string {
|
|
routeHost = strings.TrimSpace(routeHost)
|
|
if routeHost == "" {
|
|
return ""
|
|
}
|
|
return "https://" + routeHost
|
|
}
|
|
|
|
func newDeployToken() (string, error) {
|
|
buf := make([]byte, 24)
|
|
if _, err := rand.Read(buf); err != nil {
|
|
return "", err
|
|
}
|
|
return fmt.Sprintf("%x", buf), nil
|
|
}
|
|
|
|
func runCmd(name string, args ...string) error {
|
|
_, err := runCmdOut(name, args...)
|
|
return err
|
|
}
|
|
|
|
func runCmdOut(name string, args ...string) (string, error) {
|
|
out, err := exec.Command(name, args...).CombinedOutput()
|
|
if err != nil {
|
|
return "", fmt.Errorf("command failed: %s %s: %w output=%s", name, strings.Join(args, " "), err, strings.TrimSpace(string(out)))
|
|
}
|
|
return string(out), nil
|
|
}
|