This commit is contained in:
Matthew Knight 2026-03-02 18:39:51 -08:00
parent 03df6a4c93
commit fe4c293adb
No known key found for this signature in database
10 changed files with 51 additions and 47 deletions

View File

@ -17,20 +17,20 @@ type Config struct {
S3SecretKey string
S3UseSSL bool
ForgejoURL string
ForgejoToken string
ForgejoURL string
ForgejoToken string
ForgejoWebhookSecret string
}
func Load() (*Config, error) {
c := &Config{
ListenAddr: envOr("CAIRN_LISTEN_ADDR", ":8080"),
DatabaseURL: envOr("CAIRN_DATABASE_URL", "postgres://cairn:cairn@localhost:5432/cairn?sslmode=disable"),
S3Endpoint: envOr("CAIRN_S3_ENDPOINT", "localhost:9000"),
S3Bucket: envOr("CAIRN_S3_BUCKET", "cairn-artifacts"),
S3AccessKey: envOr("CAIRN_S3_ACCESS_KEY", "minioadmin"),
S3SecretKey: envOr("CAIRN_S3_SECRET_KEY", "minioadmin"),
S3UseSSL: envBool("CAIRN_S3_USE_SSL", false),
ListenAddr: envOr("CAIRN_LISTEN_ADDR", ":8080"),
DatabaseURL: envOr("CAIRN_DATABASE_URL", "postgres://cairn:cairn@localhost:5432/cairn?sslmode=disable"),
S3Endpoint: envOr("CAIRN_S3_ENDPOINT", "localhost:9000"),
S3Bucket: envOr("CAIRN_S3_BUCKET", "cairn-artifacts"),
S3AccessKey: envOr("CAIRN_S3_ACCESS_KEY", "minioadmin"),
S3SecretKey: envOr("CAIRN_S3_SECRET_KEY", "minioadmin"),
S3UseSSL: envBool("CAIRN_S3_USE_SSL", false),
ForgejoURL: envOr("CAIRN_FORGEJO_URL", ""),
ForgejoToken: envOr("CAIRN_FORGEJO_TOKEN", ""),
ForgejoWebhookSecret: envOr("CAIRN_FORGEJO_WEBHOOK_SECRET", ""),

View File

@ -9,9 +9,9 @@ import (
const maxFrames = 8
var (
hexAddrRe = regexp.MustCompile(`0x[0-9a-fA-F]+`)
hexAddrRe = regexp.MustCompile(`0x[0-9a-fA-F]+`)
templateParamRe = regexp.MustCompile(`<[^>]*>`)
abiTagRe = regexp.MustCompile(`\[abi:[^\]]*\]`)
abiTagRe = regexp.MustCompile(`\[abi:[^\]]*\]`)
)
// runtimePrefixes are function prefixes for runtime/library frames to filter out.

View File

@ -7,15 +7,17 @@ import (
)
// ASan/MSan/TSan/UBSan frame patterns:
// #0 0x55a3b4 in function_name /path/to/file.c:42:13
// #0 0x55a3b4 in function_name (/path/to/binary+0x1234)
// #1 0x55a3b4 (/path/to/binary+0x1234)
//
// #0 0x55a3b4 in function_name /path/to/file.c:42:13
// #0 0x55a3b4 in function_name (/path/to/binary+0x1234)
// #1 0x55a3b4 (/path/to/binary+0x1234)
var asanFrameRe = regexp.MustCompile(
`^\s*#(\d+)\s+(0x[0-9a-fA-F]+)\s+(?:in\s+(\S+)\s+)?(.*)$`,
)
// ASan error header line, e.g.:
// ==12345==ERROR: AddressSanitizer: heap-buffer-overflow
//
// ==12345==ERROR: AddressSanitizer: heap-buffer-overflow
var asanHeaderRe = regexp.MustCompile(
`==\d+==ERROR:\s+(Address|Memory|Thread|Undefined)Sanitizer`,
)

View File

@ -7,9 +7,10 @@ import (
)
// GDB backtrace frame patterns:
// #0 function_name (args) at /path/to/file.c:42
// #0 0x00007fff in function_name () from /lib/libfoo.so
// #0 0x00007fff in ?? ()
//
// #0 function_name (args) at /path/to/file.c:42
// #0 0x00007fff in function_name () from /lib/libfoo.so
// #0 0x00007fff in ?? ()
var gdbFrameRe = regexp.MustCompile(
`^\s*#(\d+)\s+(?:(0x[0-9a-fA-F]+)\s+in\s+)?(\S+)\s*\(([^)]*)\)\s*(?:at\s+(\S+?)(?::(\d+))?)?(?:\s+from\s+(\S+))?`,
)

View File

@ -7,8 +7,9 @@ import (
)
// Zig panic/stack trace patterns:
// /path/to/file.zig:42:13: 0x1234 in function_name (module)
// ???:?:?: 0x1234 in ??? (???)
//
// /path/to/file.zig:42:13: 0x1234 in function_name (module)
// ???:?:?: 0x1234 in ??? (???)
var zigFrameRe = regexp.MustCompile(
`^\s*(.+?):(\d+):\d+:\s+(0x[0-9a-fA-F]+)\s+in\s+(\S+)\s+\(([^)]*)\)`,
)

View File

@ -38,9 +38,9 @@ type Issue struct {
// CreateIssueRequest is the body for creating a Forgejo issue.
type CreateIssueRequest struct {
Title string `json:"title"`
Body string `json:"body"`
Labels []int64 `json:"labels,omitempty"`
Title string `json:"title"`
Body string `json:"body"`
Labels []int64 `json:"labels,omitempty"`
}
// CommitStatus represents a Forgejo commit status.

View File

@ -12,13 +12,13 @@ import (
// WebhookEvent is the parsed payload from a Forgejo webhook.
type WebhookEvent struct {
Action string `json:"action"`
Issue *WebhookIssue `json:"issue,omitempty"`
Repo *WebhookRepo `json:"repository,omitempty"`
Sender *WebhookUser `json:"sender,omitempty"`
Ref string `json:"ref,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
Action string `json:"action"`
Issue *WebhookIssue `json:"issue,omitempty"`
Repo *WebhookRepo `json:"repository,omitempty"`
Sender *WebhookUser `json:"sender,omitempty"`
Ref string `json:"ref,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
}
type WebhookIssue struct {

View File

@ -6,12 +6,12 @@ import (
)
type Repository struct {
ID string `json:"id"`
Name string `json:"name"`
Owner string `json:"owner"`
ForgejoURL string `json:"forgejo_url,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID string `json:"id"`
Name string `json:"name"`
Owner string `json:"owner"`
ForgejoURL string `json:"forgejo_url,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Commit struct {

View File

@ -9,13 +9,13 @@ import (
// Result holds the regression comparison between two commits.
type Result struct {
BaseSHA string `json:"base_sha"`
HeadSHA string `json:"head_sha"`
RepoName string `json:"repo_name"`
New []string `json:"new"` // Fingerprints in head but not base.
Fixed []string `json:"fixed"` // Fingerprints in base but not head.
Recurring []string `json:"recurring"` // Fingerprints in both.
IsRegression bool `json:"is_regression"`
BaseSHA string `json:"base_sha"`
HeadSHA string `json:"head_sha"`
RepoName string `json:"repo_name"`
New []string `json:"new"` // Fingerprints in head but not base.
Fixed []string `json:"fixed"` // Fingerprints in base but not head.
Recurring []string `json:"recurring"` // Fingerprints in both.
IsRegression bool `json:"is_regression"`
}
// Compare computes the set difference of crash fingerprints between a base and head commit.

View File

@ -13,10 +13,10 @@ import (
)
type RouterConfig struct {
Pool *pgxpool.Pool
Store blob.Store
ForgejoClient *forgejo.Client
WebhookSecret string
Pool *pgxpool.Pool
Store blob.Store
ForgejoClient *forgejo.Client
WebhookSecret string
}
func NewRouter(cfg RouterConfig) (*gin.Engine, error) {