mirror of
https://github.com/lukaszraczylo/ghtracker.git
synced 2026-10-12 00:45:38 +00:00
ghtracker authenticates as a GitHub App and scans a configured list of repositories on a schedule. It serves a dashboard, a JSON state endpoint, a health probe and Prometheus metrics. The dashboard lists only items that need attention: failing workflows, pull requests that wait too long or fail their checks, stale issues and projects that failed to scan. It has search, dynamic filters and a button that rescans on demand. The Vue app is embedded in the Go binary. The client protects the GitHub rate limit with conditional requests, a request reserve and Retry-After handling.
147 lines
2.9 KiB
Go
147 lines
2.9 KiB
Go
// Package model holds the data shapes shared by the collector, metrics and web layers.
|
|
package model
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
// ErrRateLimited means GitHub limits were hit or are about to be; callers must stop issuing requests.
|
|
var ErrRateLimited = errors.New("github rate limit reached")
|
|
|
|
type Severity int
|
|
|
|
const (
|
|
OK Severity = iota
|
|
Warn
|
|
Crit
|
|
)
|
|
|
|
func (s Severity) String() string {
|
|
switch s {
|
|
case Warn:
|
|
return "warn"
|
|
case Crit:
|
|
return "crit"
|
|
default:
|
|
return "ok"
|
|
}
|
|
}
|
|
|
|
type CheckState string
|
|
|
|
const (
|
|
ChecksNone CheckState = "none"
|
|
ChecksPending CheckState = "pending"
|
|
ChecksPass CheckState = "success"
|
|
ChecksFail CheckState = "failure"
|
|
ChecksUnknown CheckState = "unknown"
|
|
)
|
|
|
|
type Repo struct {
|
|
RefreshedAt time.Time
|
|
Release *Release
|
|
Description string
|
|
FullName string
|
|
DefaultBranch string
|
|
ReleasesURL string
|
|
// Err is set when the last refresh failed entirely; the other fields hold the last good data.
|
|
Err string
|
|
URL string
|
|
Issues []Issue
|
|
PRs []PullRequest
|
|
Workflows []Workflow
|
|
// Warnings lists sections that failed to load while the rest succeeded.
|
|
Warnings []string
|
|
Health Severity
|
|
Archived bool
|
|
Up bool
|
|
}
|
|
|
|
type Release struct {
|
|
PublishedAt time.Time
|
|
Tag string
|
|
Name string
|
|
URL string
|
|
Prerelease bool
|
|
// FromTag marks a version taken from tags because the repo has no releases.
|
|
FromTag bool
|
|
}
|
|
|
|
type Issue struct {
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
Title string
|
|
URL string
|
|
Author string
|
|
Labels []string
|
|
Number int
|
|
Comments int
|
|
}
|
|
|
|
type PullRequest struct {
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
Title string
|
|
URL string
|
|
Author string
|
|
HeadSHA string
|
|
Labels []string
|
|
Checks CheckSummary
|
|
Number int
|
|
Draft bool
|
|
}
|
|
|
|
type CheckSummary struct {
|
|
State CheckState
|
|
Failing []string
|
|
Total int
|
|
Failed int
|
|
Pending int
|
|
}
|
|
|
|
type Workflow struct {
|
|
// LastDone is the newest completed run; nil when no run has completed yet.
|
|
LastDone *Run
|
|
Name string
|
|
URL string
|
|
Latest Run
|
|
Background bool
|
|
}
|
|
|
|
type Run struct {
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
URL string
|
|
Event string
|
|
Branch string
|
|
Status string
|
|
Conclusion string
|
|
ID int64
|
|
}
|
|
|
|
// Running reports whether the run has not completed.
|
|
func (r Run) Running() bool { return r.Status != "completed" }
|
|
|
|
// Failed reports whether a completed run ended in a failing conclusion.
|
|
func (r Run) Failed() bool {
|
|
switch r.Conclusion {
|
|
case "failure", "timed_out", "startup_failure", "action_required":
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
type Alert struct {
|
|
Since time.Time
|
|
Repo string
|
|
Kind string
|
|
Subject string
|
|
Detail string
|
|
URL string
|
|
Severity Severity
|
|
}
|
|
|
|
// Message renders the alert as one line for logs and the JSON API.
|
|
func (a Alert) Message() string { return a.Subject + ": " + a.Detail }
|