166 lines
4.3 KiB
Go
166 lines
4.3 KiB
Go
package platforms
|
|
|
|
import (
|
|
"code-review/services/types"
|
|
"code-review/utils"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
)
|
|
|
|
// GiteeEvent Gitee 平台的 webhook 事件
|
|
type GiteeEvent struct {
|
|
apiBase string
|
|
auth *AuthConfig
|
|
Event string
|
|
client *httpClient
|
|
Action string `json:"action"`
|
|
ActionDesc string `json:"action_desc"`
|
|
Hook struct {
|
|
Password string `json:"password"` // webhook 密码
|
|
} `json:"hook"`
|
|
Password string `json:"password"` // 兼容旧版本
|
|
Project struct {
|
|
ID int `json:"id"`
|
|
Name string `json:"name"`
|
|
Path string `json:"path"`
|
|
FullName string `json:"full_name"`
|
|
WebURL string `json:"web_url"`
|
|
Description string `json:"description"`
|
|
} `json:"project"`
|
|
PullRequest struct {
|
|
ID int `json:"id"`
|
|
Number int `json:"number"`
|
|
State string `json:"state"`
|
|
Title string `json:"title"`
|
|
Body string `json:"body"`
|
|
SourceBranch string `json:"source_branch"`
|
|
TargetBranch string `json:"target_branch"`
|
|
Commits []struct {
|
|
ID string `json:"id"`
|
|
Message string `json:"message"`
|
|
} `json:"commits"`
|
|
Changes []struct {
|
|
Path string `json:"path"`
|
|
Content string `json:"content"`
|
|
Type string `json:"type"` // added, modified, deleted, renamed
|
|
OldPath string `json:"old_path,omitempty"`
|
|
} `json:"changes"`
|
|
} `json:"pull_request"`
|
|
}
|
|
|
|
func NewGiteeEvent(baseURL string, auth *AuthConfig) *GiteeEvent {
|
|
return &GiteeEvent{
|
|
apiBase: baseURL,
|
|
auth: auth,
|
|
client: newHTTPClient(baseURL, auth),
|
|
}
|
|
}
|
|
|
|
func (e *GiteeEvent) ExtractChanges() (*types.CodeChanges, error) {
|
|
changes := &types.CodeChanges{
|
|
Repository: e.Project.FullName,
|
|
Branch: e.PullRequest.SourceBranch,
|
|
CommitID: e.PullRequest.Commits[len(e.PullRequest.Commits)-1].ID,
|
|
Files: make([]types.FileChange, 0, len(e.PullRequest.Changes)),
|
|
PullRequest: &types.PullRequest{
|
|
ID: e.PullRequest.ID,
|
|
Title: e.PullRequest.Title,
|
|
Description: e.PullRequest.Body,
|
|
SourceBranch: e.PullRequest.SourceBranch,
|
|
TargetBranch: e.PullRequest.TargetBranch,
|
|
},
|
|
}
|
|
|
|
// 过滤合并提交
|
|
validCommits := make([]struct {
|
|
ID string `json:"id"`
|
|
Message string `json:"message"`
|
|
}, 0)
|
|
|
|
for _, commit := range e.PullRequest.Commits {
|
|
if strings.HasPrefix(commit.Message, "Merge remote-tracking branch") ||
|
|
strings.HasPrefix(commit.Message, "Merge branch") {
|
|
log.Printf("跳过合并提交: commit=%s", commit.ID)
|
|
continue
|
|
}
|
|
validCommits = append(validCommits, commit)
|
|
}
|
|
|
|
if len(validCommits) == 0 {
|
|
log.Printf("没有有效的提交记录(所有提交都是合并提交),跳过代码审查")
|
|
return nil, nil
|
|
}
|
|
|
|
// 更新最后的提交ID
|
|
if len(validCommits) > 0 {
|
|
changes.CommitID = validCommits[len(validCommits)-1].ID
|
|
}
|
|
|
|
for _, change := range e.PullRequest.Changes {
|
|
fileChange := types.FileChange{
|
|
Path: change.Path,
|
|
Content: change.Content,
|
|
OldPath: change.OldPath,
|
|
}
|
|
|
|
fileChange.Type = utils.ParseFileType(change.Type)
|
|
|
|
changes.Files = append(changes.Files, fileChange)
|
|
}
|
|
|
|
return changes, nil
|
|
}
|
|
|
|
func (e *GiteeEvent) PostComments(result *types.ReviewResult) error {
|
|
if e.client == nil {
|
|
e.client = newHTTPClient(e.apiBase, e.auth)
|
|
}
|
|
|
|
for _, comment := range result.Comments {
|
|
body := map[string]interface{}{
|
|
"access_token": e.auth.Token,
|
|
"body": fmt.Sprintf("**Code Review Comment**\n\nFile: %s\nLine: %d\nSeverity: %s\n\n%s",
|
|
comment.Path,
|
|
comment.Line,
|
|
comment.Severity,
|
|
comment.Content,
|
|
),
|
|
"position_line": comment.Line,
|
|
"path": comment.Path,
|
|
}
|
|
|
|
path := fmt.Sprintf("/v5/repos/%s/pulls/%d/comments",
|
|
e.Project.FullName,
|
|
e.PullRequest.Number,
|
|
)
|
|
|
|
if err := e.client.post(path, body); err != nil {
|
|
return fmt.Errorf("post comment failed: %w", err)
|
|
}
|
|
}
|
|
|
|
// 发送总结评论
|
|
if result.Summary != "" {
|
|
body := map[string]interface{}{
|
|
"access_token": e.auth.Token,
|
|
"body": fmt.Sprintf("**Code Review Summary**\n\n%s", result.Summary),
|
|
}
|
|
|
|
path := fmt.Sprintf("/v5/repos/%s/pulls/%d/comments",
|
|
e.Project.FullName,
|
|
e.PullRequest.Number,
|
|
)
|
|
|
|
if err := e.client.post(path, body); err != nil {
|
|
return fmt.Errorf("post summary failed: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (e *GiteeEvent) GetPlatform() string {
|
|
return "gitee"
|
|
}
|