model

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 1, 2026 License: MIT Imports: 1 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsCancelledConclusion added in v0.3.0

func IsCancelledConclusion(conclusion string) bool

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

func IsDrillableConclusion(conclusion string) bool

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

func IsFailureConclusion(conclusion string) bool

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

type ActionTag struct {
	Name string `json:"name"`
	SHA  string `json:"sha"`
}

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

func (r *Report) HasFailures() bool

HasFailures reports whether any failing checks were found.

func (*Report) IsTerminal

func (r *Report) IsTerminal() bool

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.

type StepKind

type StepKind string

StepKind classifies how a step ran, derived from its log group header.

const (
	KindAction  StepKind = "action" // uses: owner/action@ref
	KindBash    StepKind = "bash"   // run: shell command
	KindUnknown StepKind = ""
)

Step command kinds, derived from a step's log group header.

type StepOverview

type StepOverview struct {
	Number     int    `json:"number"`
	Name       string `json:"name"`
	Status     string `json:"status"`
	Conclusion string `json:"conclusion"`
}

StepOverview is one entry in a job's authoritative ordered step list.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL