58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
package webhook
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
var (
|
|
closesRe = regexp.MustCompile(`(?i)\b(?:closes|fixes|resolves|close|fix|resolve)\s+#(\d+)`)
|
|
branchRe = regexp.MustCompile(`(?:^|[-/])(\d+)(?:[-/]|$)`)
|
|
nonceRe = regexp.MustCompile(`(?i)<!--\s*spx:nonce=([0-9a-f-]+)\s*-->`)
|
|
reviewRe = regexp.MustCompile(`(?i)<!--\s*spx:review=1\s*-->`)
|
|
)
|
|
|
|
// ResolveIssueNumber resolves the issue number in priority order:
|
|
// 1. PR body keyword (Closes/Fixes/Resolves #N)
|
|
// 2. Branch name containing a number
|
|
// 3. Legacy path number
|
|
func ResolveIssueNumber(prBody, branch string, legacyNumber int) (int, bool) {
|
|
if m := closesRe.FindStringSubmatch(prBody); m != nil {
|
|
n, _ := strconv.Atoi(m[1])
|
|
return n, true
|
|
}
|
|
if branch != "" {
|
|
if m := branchRe.FindStringSubmatch(branch); m != nil {
|
|
n, _ := strconv.Atoi(m[1])
|
|
return n, true
|
|
}
|
|
}
|
|
if legacyNumber > 0 {
|
|
return legacyNumber, true
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
// ShouldAutoReview returns the effective auto-review flag.
|
|
// The per-issue stateJSON "autoReview" bool takes precedence over globalAutoReview.
|
|
func ShouldAutoReview(stateJSON map[string]any, globalAutoReview bool) bool {
|
|
if v, ok := stateJSON["autoReview"].(bool); ok {
|
|
return v
|
|
}
|
|
return globalAutoReview
|
|
}
|
|
|
|
// ExtractNonce extracts the nonce value from a <!-- spx:nonce=... --> marker.
|
|
func ExtractNonce(issueBody string) (string, bool) {
|
|
m := nonceRe.FindStringSubmatch(issueBody)
|
|
if m == nil || m[1] == "" {
|
|
return "", false
|
|
}
|
|
return m[1], true
|
|
}
|
|
|
|
// IsReviewMarker reports whether commentBody contains <!-- spx:review=1 -->.
|
|
func IsReviewMarker(commentBody string) bool {
|
|
return reviewRe.MatchString(commentBody)
|
|
}
|