1package preview
2
3import (
4 "fmt"
5 "path/filepath"
6 "strings"
7)
8
9// ExtractPreviewName strips the matched pattern prefix from a tag.
10// Only simple trailing-wildcard patterns like "preview-*" or "pr-*" are supported.
11// Complex globs (e.g., "pr-*-test", "*-preview") are not supported.
12// "preview-login-redesign" with pattern "preview-*" → "login-redesign"
13func ExtractPreviewName(tag string, patterns []string) string {
14 for _, pattern := range patterns {
15 matched, err := filepath.Match(pattern, tag)
16 if err != nil {
17 continue // skip malformed patterns
18 }
19 if matched {
20 prefix := strings.TrimSuffix(pattern, "*")
21 return strings.TrimPrefix(tag, prefix)
22 }
23 }
24 return tag
25}
26
27// GeneratePreviewDomain creates the preview domain from a base route domain.
28// "myapp.example.com" + "login" + "--" → "myapp--login.example.com"
29func GeneratePreviewDomain(baseRoute, previewName, separator string) (string, error) {
30 dot := strings.Index(baseRoute, ".")
31 if dot < 0 {
32 return "", fmt.Errorf("invalid base route domain: %s", baseRoute)
33 }
34 app := baseRoute[:dot]
35 rest := baseRoute[dot:] // includes leading dot
36 return app + separator + previewName + rest, nil
37}
38
39// SanitizeBranchName converts a git branch name to a valid DNS-safe preview name.
40// "feat/login-redesign" → "login-redesign"
41func SanitizeBranchName(branch string) string {
42 branch = strings.ToLower(branch)
43 for _, prefix := range []string{"feat/", "fix/", "feature/", "hotfix/", "release/", "chore/"} {
44 if strings.HasPrefix(branch, prefix) {
45 branch = strings.TrimPrefix(branch, prefix)
46 break
47 }
48 }
49 // Replace disallowed characters with dashes
50 branch = strings.ReplaceAll(branch, "/", "-")
51 branch = strings.ReplaceAll(branch, "_", "-")
52 branch = strings.ReplaceAll(branch, ".", "-")
53
54 // Remove any remaining non DNS-safe characters
55 var result strings.Builder
56 for _, c := range branch {
57 if (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' {
58 result.WriteRune(c)
59 }
60 }
61 branch = result.String()
62
63 // Collapse consecutive dashes and trim
64 for strings.Contains(branch, "--") {
65 branch = strings.ReplaceAll(branch, "--", "-")
66 }
67 branch = strings.Trim(branch, "-")
68
69 // Truncate to 63 chars (DNS label limit)
70 if len(branch) > 63 {
71 branch = branch[:63]
72 branch = strings.TrimRight(branch, "-")
73 }
74 return branch
75}