85 lines
2.0 KiB
Go
85 lines
2.0 KiB
Go
package forgejo
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"github.com/mattnite/cairn/internal/models"
|
|
)
|
|
|
|
// Sync handles bidirectional state synchronization between Cairn and Forgejo.
|
|
type Sync struct {
|
|
Client *Client
|
|
Pool *pgxpool.Pool
|
|
}
|
|
|
|
// CreateIssueForCrashGroup creates a Forgejo issue for a new crash group.
|
|
func (s *Sync) CreateIssueForCrashGroup(ctx context.Context, group *models.CrashGroup, sampleTrace string) error {
|
|
if s.Client == nil {
|
|
return nil
|
|
}
|
|
|
|
repo, err := models.GetRepositoryByID(ctx, s.Pool, group.RepositoryID)
|
|
if err != nil {
|
|
return fmt.Errorf("getting repository: %w", err)
|
|
}
|
|
|
|
body := fmt.Sprintf(`## Crash Group
|
|
|
|
**Fingerprint:** `+"`%s`"+`
|
|
**First seen:** %s
|
|
**Type:** %s
|
|
|
|
### Sample Stack Trace
|
|
|
|
`+"```"+`
|
|
%s
|
|
`+"```"+`
|
|
|
|
---
|
|
*Auto-created by [Cairn](/) — crash artifact aggregator*
|
|
`, group.Fingerprint, group.FirstSeenAt.Format("2006-01-02 15:04:05"), group.Title, sampleTrace)
|
|
|
|
issue, err := s.Client.CreateIssue(ctx, repo.Owner, repo.Name, CreateIssueRequest{
|
|
Title: "[Cairn] " + group.Title,
|
|
Body: body,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("creating issue: %w", err)
|
|
}
|
|
|
|
return models.UpdateCrashGroupIssue(ctx, s.Pool, group.ID, issue.Number, issue.HTMLURL)
|
|
}
|
|
|
|
// HandleIssueEvent processes a Forgejo issue webhook event for state sync.
|
|
func (s *Sync) HandleIssueEvent(ctx context.Context, event *WebhookEvent) error {
|
|
if event.Issue == nil {
|
|
return nil
|
|
}
|
|
|
|
// Only handle issues that start with [Cairn] prefix.
|
|
if !strings.HasPrefix(event.Issue.Title, "[Cairn] ") {
|
|
return nil
|
|
}
|
|
|
|
switch event.Action {
|
|
case "closed":
|
|
return models.ResolveCrashGroupByIssue(ctx, s.Pool, event.Issue.Number)
|
|
case "reopened":
|
|
return models.ReopenCrashGroupByIssue(ctx, s.Pool, event.Issue.Number)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandlePushEvent processes a push webhook event for commit enrichment.
|
|
func (s *Sync) HandlePushEvent(ctx context.Context, event *WebhookEvent) {
|
|
if event.Repo == nil || event.After == "" {
|
|
return
|
|
}
|
|
log.Printf("Push event: %s -> %s", event.Repo.FullName, event.After[:8])
|
|
}
|