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 AuthorType
- type BranchProtection
- type CodeScanningAlert
- type ComplianceCheck
- type ComplianceReport
- type ComplianceStatus
- type DependabotAlert
- type FailedStep
- type ImagePackage
- type ImageVersion
- type JobResult
- type OtherCheck
- type PR
- type RepoSettings
- type Report
- type Review
- type ReviewComment
- type ReviewThread
- type RunInfo
- type RunningJob
- type SecretLocation
- type SecretScanningAlert
- type SecurityReport
- type SecuritySeverity
- type SecuritySource
- type SettingsSource
- 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 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 BranchProtection ¶ added in v0.4.0
type BranchProtection struct {
Branch string `json:"branch"`
Protected bool `json:"protected"`
RequiredPullRequestReviews bool `json:"required_pull_request_reviews"`
RequiredApprovingReviewCount int `json:"required_approving_review_count"`
DismissStaleReviews bool `json:"dismiss_stale_reviews"`
RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"`
RequireLastPushApproval bool `json:"require_last_push_approval"`
RequiredStatusChecks []string `json:"required_status_checks,omitempty"`
StrictStatusChecks bool `json:"strict_status_checks"`
EnforceAdmins bool `json:"enforce_admins"`
RequireLinearHistory bool `json:"required_linear_history"`
AllowForcePushes bool `json:"allow_force_pushes"`
AllowDeletions bool `json:"allow_deletions"`
RequireConversationResolution bool `json:"required_conversation_resolution"`
RequiredSignatures bool `json:"required_signatures"`
}
BranchProtection is the normalized branch-protection state shuck checks. When Protected is false the branch has no protection rule (or does not exist), so every asserted protection is reported as not satisfied.
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 ComplianceCheck ¶ added in v0.4.0
type ComplianceCheck struct {
Category string `json:"category"` // repository | security | branch_protection
Setting string `json:"setting"` // e.g. allow_merge_commit, main.required_approving_review_count
Expected string `json:"expected"`
Actual string `json:"actual,omitempty"`
Status ComplianceStatus `json:"status"`
Message string `json:"message,omitempty"` // why a check was skipped or errored
}
ComplianceCheck records one asserted setting: what the config wanted, what the repository actually has, and whether they agree.
type ComplianceReport ¶ added in v0.4.0
type ComplianceReport struct {
Owner string `json:"owner"`
Repo string `json:"repo"`
ConfigSource string `json:"config_source"` // where the config came from (a path or a github: ref)
Checks []ComplianceCheck `json:"checks"`
CheckedAt time.Time `json:"checked_at"`
}
ComplianceReport is the assembled compliance posture for one repository: every setting the config asserted, paired with the repo's actual value.
func (*ComplianceReport) Compliant ¶ added in v0.4.0
func (r *ComplianceReport) Compliant() bool
Compliant reports whether the repository fully matches its config: at least one check ran and none failed or errored.
func (*ComplianceReport) Count ¶ added in v0.4.0
func (r *ComplianceReport) Count(status ComplianceStatus) int
Count tallies the checks in the given status.
func (*ComplianceReport) HasFailures ¶ added in v0.4.0
func (r *ComplianceReport) HasFailures() bool
HasFailures reports whether any check drifted from the asserted value. A skipped check (one that could not be read) is not a failure on its own.
type ComplianceStatus ¶ added in v0.4.0
type ComplianceStatus string
ComplianceStatus is the outcome of a single compliance check: whether the repository's actual setting matched the value the config asserted.
const ( CompliancePass ComplianceStatus = "pass" // actual matches the asserted value ComplianceFail ComplianceStatus = "fail" // actual differs from the asserted value (drift) ComplianceSkipped ComplianceStatus = "skipped" // the actual value could not be read (no access) ComplianceError ComplianceStatus = "error" // a genuine error evaluating the check )
Per-check outcomes.
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"`
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 ImagePackage ¶ added in v0.4.0
type ImagePackage struct {
Owner string `json:"owner"`
Name string `json:"name"`
Versions []ImageVersion `json:"versions"`
}
ImagePackage is a single container package (image) under an owner and the versions published for it, newest first as assembled by the caller.
type ImageVersion ¶ added in v0.4.0
type ImageVersion struct {
Tags []string `json:"tags"`
Digest string `json:"digest"` // sha256:...
UpdatedAt time.Time `json:"updated_at"`
}
ImageVersion is one published version of a container image: the immutable manifest digest (sha256:...) and the tags that currently point at it, with the time the version was last updated. shuck uses it to pin an image reference to its digest.
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"`
Inspected bool `json:"inspected"` // logs were drilled for this (id, attempt)
}
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
}
PR identifies a pull request and its head commit.
type RepoSettings ¶ added in v0.4.0
type RepoSettings struct {
Visibility string `json:"visibility"`
DefaultBranch string `json:"default_branch"`
AllowMergeCommit bool `json:"allow_merge_commit"`
AllowSquashMerge bool `json:"allow_squash_merge"`
AllowRebaseMerge bool `json:"allow_rebase_merge"`
AllowAutoMerge bool `json:"allow_auto_merge"`
AllowUpdateBranch bool `json:"allow_update_branch"`
DeleteBranchOnMerge bool `json:"delete_branch_on_merge"`
HasIssues bool `json:"has_issues"`
HasWiki bool `json:"has_wiki"`
HasProjects bool `json:"has_projects"`
HasDiscussions bool `json:"has_discussions"`
WebCommitSignoffRequired bool `json:"web_commit_signoff_required"`
Archived bool `json:"archived"`
// security_and_analysis status strings ("enabled"/"disabled"), empty when
// the section was not returned (the token is not an admin).
SecretScanning string `json:"secret_scanning,omitempty"`
SecretScanningPushProtection string `json:"secret_scanning_push_protection,omitempty"`
DependabotSecurityUpdates string `json:"dependabot_security_updates,omitempty"`
SecuritySource SettingsSource `json:"security_source"`
}
RepoSettings is the normalized subset of a repository's settings shuck checks for compliance. The security_and_analysis fields are empty strings when the token cannot see them (SecuritySource then reports why).
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"`
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
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"`
}
RunningJob is a job not yet in a terminal state.
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 SettingsSource ¶ added in v0.4.0
type SettingsSource struct {
Status SourceStatus `json:"status"`
Message string `json:"message,omitempty"`
}
SettingsSource records whether a group of repository settings could be read, so a check can distinguish "matched" from "could not read it" (e.g. the token lacks the admin access required to see security or branch-protection state).
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.