cairn/internal/handler/regression.go

65 lines
1.7 KiB
Go

package handler
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/mattnite/cairn/internal/forgejo"
"github.com/mattnite/cairn/internal/models"
"github.com/mattnite/cairn/internal/regression"
)
type RegressionHandler struct {
Pool *pgxpool.Pool
ForgejoSync *forgejo.Sync
}
type RegressionCheckRequest struct {
Repository string `json:"repository" binding:"required"`
BaseSHA string `json:"base_sha" binding:"required"`
HeadSHA string `json:"head_sha" binding:"required"`
}
func (h *RegressionHandler) Check(c *gin.Context) {
var req RegressionCheckRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
ctx := c.Request.Context()
repo, err := models.GetRepositoryByName(ctx, h.Pool, req.Repository)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "repository not found"})
return
}
result, err := regression.Compare(ctx, h.Pool, repo.ID, req.BaseSHA, req.HeadSHA)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
result.RepoName = repo.Name
// Post commit status to Forgejo if integration is configured.
if h.ForgejoSync != nil && h.ForgejoSync.Client != nil {
state := "success"
description := "No new crash signatures"
if result.IsRegression {
state = "failure"
description = fmt.Sprintf("%d new crash signature(s) detected", len(result.New))
}
h.ForgejoSync.Client.CreateCommitStatus(ctx, repo.Owner, repo.Name, req.HeadSHA, forgejo.CommitStatus{
State: state,
Description: description,
Context: "cairn/regression",
})
}
c.JSON(http.StatusOK, result)
}