2287a8238c
CI / test (pull_request) Successful in 14s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 19s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m27s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m42s
When reviewer-name is set, prepend "# Security Review" / "# Sonnet Review" etc. as a top-level header. Makes it immediately obvious which role each review represents in the Gitea UI, especially when multiple reviews come from the same bot account.
56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
package review
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// FormatMarkdown formats a ReviewResult into the markdown body for a Gitea review.
|
|
func FormatMarkdown(result *ReviewResult, reviewerName string) string {
|
|
var sb strings.Builder
|
|
|
|
if reviewerName != "" {
|
|
title := strings.ToUpper(reviewerName[:1]) + reviewerName[1:]
|
|
sb.WriteString(fmt.Sprintf("# %s Review\n\n", title))
|
|
}
|
|
|
|
sb.WriteString("## Summary\n\n")
|
|
sb.WriteString(result.Summary)
|
|
sb.WriteString("\n\n")
|
|
|
|
if len(result.Findings) > 0 {
|
|
sb.WriteString("## Findings\n\n")
|
|
sb.WriteString("| # | Severity | File | Line | Finding |\n")
|
|
sb.WriteString("|---|----------|------|------|--------|\n")
|
|
|
|
for i, f := range result.Findings {
|
|
sb.WriteString(fmt.Sprintf("| %d | [%s] | `%s` | %d | %s |\n",
|
|
i+1, f.Severity, f.File, f.Line, f.Finding))
|
|
}
|
|
sb.WriteString("\n")
|
|
}
|
|
|
|
sb.WriteString("## Recommendation\n\n")
|
|
sb.WriteString(fmt.Sprintf("**%s** — %s\n", result.Verdict, result.Recommendation))
|
|
|
|
if reviewerName != "" {
|
|
sb.WriteString(fmt.Sprintf("\n---\n*Review by %s*\n", reviewerName))
|
|
// Hidden sentinel for identifying this bot's reviews during cleanup
|
|
sb.WriteString(fmt.Sprintf("\n<!-- review-bot:%s -->\n", reviewerName))
|
|
}
|
|
|
|
return sb.String()
|
|
}
|
|
|
|
// GiteaEvent converts the verdict to the Gitea API event string.
|
|
func GiteaEvent(verdict string) string {
|
|
switch verdict {
|
|
case "APPROVE":
|
|
return "APPROVED"
|
|
case "REQUEST_CHANGES":
|
|
return "REQUEST_CHANGES"
|
|
default:
|
|
return "COMMENT"
|
|
}
|
|
}
|