Documentation
¶
Overview ¶
Package model holds the domain types shared across shuck's packages: the GitHub data we collect, the failure detail we render, and the shape we persist to the cache. It imports nothing internal to avoid import cycles.
Index ¶
- func IsCancelledConclusion(conclusion string) bool
- func IsDrillableConclusion(conclusion string) bool
- func IsFailureConclusion(conclusion string) bool
- func SeverityRank(s SecuritySeverity) int
- type ActionTag
- type Annotation
- type Artifact
- type AuthorType
- type CodeScanningAlert
- type DependabotAlert
- type FailedStep
- type FailureClass
- type JobResult
- type OtherCheck
- type PR
- type Report
- type Review
- type ReviewComment
- type ReviewThread
- type RunInfo
- type RunningJob
- type SecretLocation
- type SecretScanningAlert
- type SecurityReport
- type SecuritySeverity
- type SecuritySource
- type SourceStatus
- type StepKind
- type StepOverview
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsCancelledConclusion ¶ added in v0.3.0
IsCancelledConclusion reports whether a terminal conclusion is a cancellation. shuck surfaces cancelled jobs and drills their logs best-effort (to show what was interrupted), but cancellation alone never makes the exit code non-zero.
func IsDrillableConclusion ¶ added in v0.4.0
IsDrillableConclusion reports whether a step's conclusion is worth pairing with the log's error sections: a genuine failure, or the cancellation marker GitHub puts on the step that was running when its job was cancelled.
func IsFailureConclusion ¶
IsFailureConclusion reports whether a terminal conclusion counts as a CI failure worth drilling into or listing.
func SeverityRank ¶ added in v0.3.6
func SeverityRank(s SecuritySeverity) int
SeverityRank orders severities for sorting (higher is more severe). Unknown sorts last.
Types ¶
type ActionTag ¶ added in v0.3.5
ActionTag is a tag in a GitHub Actions repository paired with the commit SHA it resolves to. shuck uses it to pin a workflow `uses:` reference to an immutable SHA. The SHA is the peeled commit a checkout would land on, even for annotated tags.
type Annotation ¶ added in v0.4.1
type Annotation struct {
Path string `json:"path"`
StartLine int `json:"start_line"`
EndLine int `json:"end_line"`
StartColumn int `json:"start_column,omitempty"`
EndColumn int `json:"end_column,omitempty"`
Level string `json:"level"` // notice | warning | failure
Title string `json:"title,omitempty"`
Message string `json:"message"`
}
Annotation is a GitHub check-run annotation: a structured file:line message attached to a job by a problem matcher (golangci-lint, go test, tsc, eslint, compilers, …). It points straight at the offending location, so shuck surfaces these alongside the scraped log excerpt.
type Artifact ¶ added in v0.4.2
type Artifact struct {
ID int64 `json:"id"`
RunID int64 `json:"run_id"`
Name string `json:"name"`
SizeBytes int64 `json:"size_bytes"`
Expired bool `json:"expired"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
Path string `json:"path,omitempty"`
}
Artifact is a file bundle a workflow run uploaded (actions/upload-artifact). shuck lists a run target's artifacts alongside its jobs; Path is set only when a download was requested, to the local directory the artifact's archive was extracted into.
type AuthorType ¶ added in v0.3.4
type AuthorType string
AuthorType classifies who wrote a review or comment, so the output can flag non-human reviewers.
const ( AuthorHuman AuthorType = "human" AuthorBot AuthorType = "bot" AuthorAI AuthorType = "ai" )
Author classifications.
type CodeScanningAlert ¶ added in v0.3.6
type CodeScanningAlert struct {
Number int `json:"number"`
State string `json:"state"`
Severity SecuritySeverity `json:"severity"`
RuleID string `json:"rule_id"`
Description string `json:"description,omitempty"`
Tool string `json:"tool,omitempty"`
Path string `json:"path,omitempty"`
StartLine int `json:"start_line,omitempty"`
EndLine int `json:"end_line,omitempty"`
Message string `json:"message,omitempty"`
HTMLURL string `json:"html_url,omitempty"`
}
CodeScanningAlert is a single code scanning (e.g. CodeQL) finding.
type DependabotAlert ¶ added in v0.3.6
type DependabotAlert struct {
Number int `json:"number"`
State string `json:"state"`
Severity SecuritySeverity `json:"severity"`
Ecosystem string `json:"ecosystem,omitempty"`
Package string `json:"package,omitempty"`
ManifestPath string `json:"manifest_path,omitempty"`
VulnerableVersions string `json:"vulnerable_version_range,omitempty"`
FixedVersion string `json:"first_patched_version,omitempty"`
GHSAID string `json:"ghsa_id,omitempty"`
CVEID string `json:"cve_id,omitempty"`
Summary string `json:"summary,omitempty"`
HTMLURL string `json:"html_url,omitempty"`
}
DependabotAlert is a single vulnerable-dependency finding. GitHub's npm "malware" advisories surface here too; there is no separate malware endpoint.
type FailedStep ¶
type FailedStep struct {
Number int `json:"number"`
Name string `json:"name"`
Command string `json:"command"`
Kind StepKind `json:"kind"`
Class FailureClass `json:"class,omitempty"`
Excerpt string `json:"excerpt"`
}
FailedStep is the high-signal detail for a step that failed: what it ran and the extracted error excerpt from its logs.
type FailureClass ¶ added in v0.4.1
type FailureClass string
FailureClass is a coarse, heuristic category for why a step failed, so an agent or script can route a failure (fix code vs. re-run) without re-parsing the excerpt. It is a hint, never authoritative.
const ( ClassUnknown FailureClass = "" ClassLint FailureClass = "lint" // linters / formatters / static analysis ClassTest FailureClass = "test" // a test suite reported failures ClassBuild FailureClass = "build" // compilation / build step ClassTimeout FailureClass = "timeout" // step or job timed out ClassOOM FailureClass = "oom" // killed for running out of memory ClassInfra FailureClass = "infra" // runner / network / registry trouble )
Failure classes. The operational classes (timeout/oom/infra) signal a likely re-run; the rest point at code or config to fix. Empty means unclassified.
type JobResult ¶
type JobResult struct {
ID int64 `json:"id"`
RunID int64 `json:"run_id"`
Name string `json:"name"`
Status string `json:"status"`
Conclusion string `json:"conclusion"`
RunAttempt int `json:"run_attempt"`
WorkflowName string `json:"workflow_name"`
WorkflowPath string `json:"workflow_path"`
Steps []StepOverview `json:"steps"`
FailedSteps []FailedStep `json:"failed_steps"`
// CheckRunID is the job's corresponding check-run ID, used to fetch the
// job's annotations. 0 when it could not be resolved.
CheckRunID int64 `json:"check_run_id,omitempty"`
// Annotations are the job's check-run annotations (file:line messages from
// problem matchers), fetched as cheap metadata when the job is drilled.
Annotations []Annotation `json:"annotations,omitempty"`
Inspected bool `json:"inspected"` // logs were drilled for this (id, attempt)
// CompletedAt and RunStartedAt time the job against its run. The monitor
// batches a run's failures until the run finishes, and the exception to
// that is a job that failed early enough to be worth interrupting for; the
// only way to tell is how far into the run it went red. Both are zero when
// the API did not say, which reads as "not an early failure" — the
// conservative direction, since it costs promptness rather than accuracy.
CompletedAt time.Time `json:"completed_at,omitzero"`
RunStartedAt time.Time `json:"run_started_at,omitzero"`
}
JobResult is a single GitHub Actions job, including its step overview and (for failed jobs that were drilled) the per-step failure detail.
type OtherCheck ¶
type OtherCheck struct {
Name string `json:"name"`
Conclusion string `json:"conclusion"`
URL string `json:"url"`
}
OtherCheck is a non-Actions check (external app check run or legacy commit status). We list these by name/conclusion/url; no logs are available.
type PR ¶
type PR struct {
Owner string `json:"owner"`
Repo string `json:"repo"`
Number int `json:"number"`
Title string `json:"title"`
HeadSHA string `json:"head_sha"`
HeadBranch string `json:"head_branch"`
UpdatedAt time.Time `json:"updated_at"` // PR's last-updated time; feeds the cheap reviews-changed check
// State, Draft, and Merged carry the PR's lifecycle. They exist for the
// background monitor, which has to notice a PR being merged or closed to
// stop watching it; the one-shot report paths ignore them.
State string `json:"state,omitempty"` // "open" or "closed"
Draft bool `json:"draft,omitempty"`
Merged bool `json:"merged,omitempty"`
}
PR identifies a pull request and its head commit.
type Report ¶
type Report struct {
PR PR `json:"pr"`
Run *RunInfo `json:"run,omitempty"`
FailedJobs []JobResult `json:"failed_jobs"`
// CancelledJobs are jobs whose run was cancelled. Their logs are drilled
// best-effort (a cancelled job's log shows what was running when it was
// interrupted), but cancellation alone never flips the exit code.
CancelledJobs []JobResult `json:"cancelled_jobs"`
RunningJobs []RunningJob `json:"running_jobs"`
OtherChecks []OtherCheck `json:"other_checks"`
// Artifacts are the file bundles attached to the inspected workflow run.
// They are listed only for run/job targets (Run non-nil), where the run is
// unambiguous.
Artifacts []Artifact `json:"artifacts,omitempty"`
Reviews []Review `json:"reviews,omitempty"`
// ReviewsFingerprint is a cheap signature of the PR's review state, persisted
// so a later run can skip the full review pull when nothing changed.
ReviewsFingerprint string `json:"reviews_fingerprint,omitempty"`
// ReviewsOnly is a presentation hint (not persisted): CI was not inspected,
// so render shows only the reviews and omits the CI verdict.
ReviewsOnly bool `json:"-"`
CheckedAt time.Time `json:"checked_at"`
}
Report is the full inspection result for a target: what we render and (for PR targets) what we cache. Exactly one of PR / Run is meaningful: Run is non-nil for run/job URL targets, otherwise the report is PR-anchored.
func (*Report) HasFailures ¶
HasFailures reports whether any failing checks were found.
func (*Report) IsTerminal ¶
IsTerminal reports whether every check has finished (no jobs still running).
type Review ¶ added in v0.3.4
type Review struct {
Author string `json:"author"`
AuthorType AuthorType `json:"author_type"`
State string `json:"state"` // approved|changes_requested|commented|dismissed
Body string `json:"body,omitempty"`
SubmittedAt time.Time `json:"submitted_at"`
Threads []ReviewThread `json:"threads,omitempty"`
}
Review is a submitted PR review: its author, verdict, top-level body, and the inline comment threads that originated in it.
type ReviewComment ¶ added in v0.3.4
type ReviewComment struct {
Author string `json:"author"`
AuthorType AuthorType `json:"author_type"`
Body string `json:"body"`
}
ReviewComment is a single comment within a thread.
type ReviewThread ¶ added in v0.3.4
type ReviewThread struct {
Path string `json:"path"`
Line int `json:"line"`
Resolved bool `json:"resolved"`
Outdated bool `json:"outdated"`
Collapsed bool `json:"collapsed"` // resolved || outdated
CollapseReason string `json:"collapse_reason,omitempty"`
TotalComments int `json:"total_comments"`
HiddenComments int `json:"hidden_comments,omitempty"` // comments hidden by the per-thread limit
Comments []ReviewComment `json:"comments,omitempty"` // empty when collapsed
}
ReviewThread is a conversation anchored to a code location. Resolved or outdated threads are collapsed: we report only why, not their contents.
type RunInfo ¶ added in v0.3.0
type RunInfo struct {
Owner string `json:"owner"`
Repo string `json:"repo"`
RunID int64 `json:"run_id"`
JobID int64 `json:"job_id,omitempty"` // 0 when the whole run was targeted
Attempt int `json:"attempt,omitempty"` // 0 when the latest attempt was used
Title string `json:"title"`
HeadSHA string `json:"head_sha"`
HeadBranch string `json:"head_branch"`
WorkflowName string `json:"workflow_name"`
}
RunInfo identifies a workflow-run inspection: shuck was pointed at a run URL (the whole run) or a single-job URL rather than a PR. When a Report's Run is non-nil, render and jsonout show a run-oriented header in place of the PR line and there is no associated PR number.
type RunningJob ¶
type RunningJob struct {
Name string `json:"name"`
Status string `json:"status"`
WorkflowName string `json:"workflow_name"`
RunID int64 `json:"run_id,omitempty"`
RunAttempt int `json:"run_attempt,omitempty"`
RunStartedAt time.Time `json:"run_started_at,omitzero"`
}
RunningJob is a job not yet in a terminal state.
RunID and RunAttempt are what let the monitor ask "is this run finished?" rather than only "is anything finished?": a run's failures are held until none of its own jobs are still going, so a slow unrelated workflow cannot sit on them.
type SecretLocation ¶ added in v0.3.6
type SecretLocation struct {
Path string `json:"path,omitempty"`
StartLine int `json:"start_line,omitempty"`
EndLine int `json:"end_line,omitempty"`
}
SecretLocation is one place a leaked secret was found. Only file locations are surfaced (commit/PR-comment locations are skipped).
type SecretScanningAlert ¶ added in v0.3.6
type SecretScanningAlert struct {
Number int `json:"number"`
State string `json:"state"`
SecretType string `json:"secret_type"`
DisplayName string `json:"secret_type_display_name,omitempty"`
Resolution string `json:"resolution,omitempty"`
Locations []SecretLocation `json:"locations,omitempty"`
HTMLURL string `json:"html_url,omitempty"`
}
SecretScanningAlert is a single secret scanning finding. It deliberately has no field for the raw secret value: shuck never reads it from the API, so the secret cannot leak into output, JSON, or the cache.
type SecurityReport ¶ added in v0.3.6
type SecurityReport struct {
Owner string `json:"owner"`
Repo string `json:"repo"`
State string `json:"state"` // the requested state filter (open|all|...)
CodeScanning SecuritySource `json:"code_scanning"`
SecretScanning SecuritySource `json:"secret_scanning"`
Dependabot SecuritySource `json:"dependabot"`
CodeScanningAlerts []CodeScanningAlert `json:"code_scanning_alerts"`
SecretScanningAlerts []SecretScanningAlert `json:"secret_scanning_alerts"`
DependabotAlerts []DependabotAlert `json:"dependabot_alerts"`
CheckedAt time.Time `json:"checked_at"`
}
SecurityReport is the assembled security posture for one repository: the per-source fetch outcome plus the alerts each returned.
func (*SecurityReport) TotalAlerts ¶ added in v0.3.6
func (r *SecurityReport) TotalAlerts() int
TotalAlerts reports how many alerts were collected across all sources.
type SecuritySeverity ¶ added in v0.3.6
type SecuritySeverity string
SecuritySeverity is the normalized severity scale shuck sorts security alerts on. Code scanning's note/warning/error and the GHAS critical/high/medium/low levels are both mapped onto it so every source ranks consistently.
const ( SeverityCritical SecuritySeverity = "critical" SeverityHigh SecuritySeverity = "high" SeverityMedium SecuritySeverity = "medium" SeverityLow SecuritySeverity = "low" SeverityWarning SecuritySeverity = "warning" SeverityNote SecuritySeverity = "note" SeverityUnknown SecuritySeverity = "unknown" )
Normalized severities, highest first.
type SecuritySource ¶ added in v0.3.6
type SecuritySource struct {
Status SourceStatus `json:"status"`
Message string `json:"message,omitempty"`
}
SecuritySource records how a single source responded.
type SourceStatus ¶ added in v0.3.6
type SourceStatus string
SourceStatus is the outcome of querying one security-alert source, so the output can distinguish "enabled and clean" from "not enabled" or "no access".
const ( StatusOK SourceStatus = "ok" // queried successfully (alerts may be empty) StatusDisabled SourceStatus = "disabled" // feature not enabled, or state N/A for this source StatusForbidden SourceStatus = "forbidden" // token lacks the required access StatusError SourceStatus = "error" // a genuine error reaching the source )
Per-source fetch outcomes.