Documentation
¶
Overview ¶
Package shippable provides analysis and management of shippable work. It determines which stacks are ready to be merged to trunk based on PR approval status, CI checks, and combinability with other stacks.
Index ¶
- type AnalysisResult
- func (r *AnalysisResult) Blocked() []Stack
- func (r *AnalysisResult) FilterByAuthor(author string) *AnalysisResult
- func (r *AnalysisResult) HasShippable() bool
- func (r *AnalysisResult) Incomplete() []Stack
- func (r *AnalysisResult) Pending() []Stack
- func (r *AnalysisResult) Shippable() []Stack
- func (r *AnalysisResult) TotalStacks() int
- type Analyzer
- type BlockingPR
- type BlockingReason
- type CheckCombinationOptions
- type CombinationResult
- type Combiner
- type ExcludedStack
- type ExclusionReason
- type FindLargestCompatibleOptions
- type ShipOptions
- type ShipResult
- type Shipper
- type Stack
- type Status
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AnalysisResult ¶
type AnalysisResult struct {
Stacks []Stack // All analyzed stacks
ShippableCount int // Number of shippable stacks
PendingCount int // Number of pending stacks
BlockedCount int // Number of blocked stacks
IncompleteCount int // Number of incomplete stacks
}
AnalysisResult contains the result of analyzing all stacks.
func (*AnalysisResult) Blocked ¶ added in v0.30.1
func (r *AnalysisResult) Blocked() []Stack
Blocked returns only the stacks that are blocked.
func (*AnalysisResult) FilterByAuthor ¶
func (r *AnalysisResult) FilterByAuthor(author string) *AnalysisResult
FilterByAuthor returns a new AnalysisResult containing only stacks by the given author.
func (*AnalysisResult) HasShippable ¶
func (r *AnalysisResult) HasShippable() bool
HasShippable returns true if there are any shippable stacks.
func (*AnalysisResult) Incomplete ¶ added in v0.30.1
func (r *AnalysisResult) Incomplete() []Stack
Incomplete returns only the stacks that are incomplete.
func (*AnalysisResult) Pending ¶ added in v0.30.1
func (r *AnalysisResult) Pending() []Stack
Pending returns only the stacks that are pending.
func (*AnalysisResult) Shippable ¶ added in v0.30.1
func (r *AnalysisResult) Shippable() []Stack
Shippable returns only the stacks that are ready to ship.
func (*AnalysisResult) TotalStacks ¶
func (r *AnalysisResult) TotalStacks() int
TotalStacks returns the total number of stacks analyzed.
type Analyzer ¶
type Analyzer struct {
// contains filtered or unexported fields
}
Analyzer analyzes stacks for shippability.
func NewAnalyzer ¶
func NewAnalyzer(eng engine.StackView, client github.ChecksReader) *Analyzer
NewAnalyzer creates a new shippability analyzer.
func (*Analyzer) AnalyzeAll ¶
func (a *Analyzer) AnalyzeAll(ctx context.Context) (*AnalysisResult, error)
AnalyzeAll discovers and analyzes all stacks for shippability.
type BlockingPR ¶
type BlockingPR struct {
Branch string // Branch name
PRNumber git.PRNumber // PR number (0 if no PR)
Reason BlockingReason // Why this PR is blocking
}
BlockingPR describes a PR that is blocking a stack from being shippable.
type BlockingReason ¶
type BlockingReason string
BlockingReason describes why a PR is blocking shippability.
const ( // ReasonChangesRequested indicates a reviewer has requested changes. ReasonChangesRequested BlockingReason = "changes_requested" // ReasonCIFailing indicates CI checks are failing. ReasonCIFailing BlockingReason = "ci_failing" // ReasonCIPending indicates CI checks are still running. ReasonCIPending BlockingReason = "ci_pending" // ReasonDraft indicates the PR is still a draft. ReasonDraft BlockingReason = "draft" // ReasonNoPR indicates no PR exists for this branch. ReasonNoPR BlockingReason = "no_pr" // ReasonReviewRequired indicates the PR needs review approval. ReasonReviewRequired BlockingReason = "review_required" // ReasonNotPushed indicates the local branch differs from remote. ReasonNotPushed BlockingReason = "not_pushed" )
type CheckCombinationOptions ¶
type CheckCombinationOptions struct {
// RunLocalCI determines whether to run local CI validation after merge.
RunLocalCI bool
}
CheckCombinationOptions configures how combination checking is performed.
type CombinationResult ¶
type CombinationResult struct {
// Combinable indicates whether the selected stacks can be merged without conflicts.
Combinable bool
// WorkingStacks are stacks that can be merged together.
WorkingStacks []Stack
// ConflictingStacks are stacks that conflict and cannot be included.
ConflictingStacks []ExcludedStack
// LocalCIPassed indicates whether local CI passed on the combined code.
// nil means local CI was not run.
LocalCIPassed *bool
// LocalCIError contains the error if local CI failed.
LocalCIError error
}
CombinationResult contains the result of checking if stacks can be merged together.
func (*CombinationResult) AllCombined ¶
func (r *CombinationResult) AllCombined() bool
AllCombined returns true if all stacks could be combined.
func (*CombinationResult) ConflictingRoots ¶ added in v0.30.1
func (r *CombinationResult) ConflictingRoots() []string
ConflictingRoots returns the root branch names of conflicting stacks.
func (*CombinationResult) ExcludedCount ¶
func (r *CombinationResult) ExcludedCount() int
ExcludedCount returns the number of stacks that were excluded.
func (*CombinationResult) IncludedCount ¶
func (r *CombinationResult) IncludedCount() int
IncludedCount returns the number of stacks that can be combined.
func (*CombinationResult) WorkingRoots ¶ added in v0.30.1
func (r *CombinationResult) WorkingRoots() []string
WorkingRoots returns the root branch names of working stacks.
type Combiner ¶
type Combiner struct {
// contains filtered or unexported fields
}
Combiner analyzes whether multiple stacks can be merged together.
func NewCombiner ¶
NewCombiner creates a new stack combiner.
func (*Combiner) CheckCombination ¶
func (c *Combiner) CheckCombination(ctx context.Context, stacks []Stack, opts CheckCombinationOptions) (*CombinationResult, error)
CheckCombination checks if the given stacks can be merged together. It creates a temporary worktree, attempts to merge all stacks, and optionally runs local CI to verify the combined code compiles/passes tests.
func (*Combiner) FindLargestCompatible ¶
func (c *Combiner) FindLargestCompatible(ctx context.Context, stacks []Stack, opts FindLargestCompatibleOptions) (*CombinationResult, error)
FindLargestCompatible finds the largest subset of stacks that can be merged together. It uses a greedy approach: try adding stacks one by one, keeping those that merge cleanly. If RunLocalCI is true, it also validates that the combined code passes local CI.
type ExcludedStack ¶
type ExcludedStack struct {
Stack Stack // The excluded stack
Reason ExclusionReason // Why it was excluded
}
ExcludedStack represents a stack that was excluded from a combination.
type ExclusionReason ¶
type ExclusionReason string
ExclusionReason describes why a stack was excluded from a combination.
const ( // ReasonMergeConflict indicates the stack has merge conflicts with others. ReasonMergeConflict ExclusionReason = "merge_conflict" // ReasonLocalCIFailed indicates local CI failed when this stack was included. ReasonLocalCIFailed ExclusionReason = "local_ci_failed" )
type FindLargestCompatibleOptions ¶
type FindLargestCompatibleOptions struct {
// RunLocalCI determines whether to run local CI for each candidate set.
RunLocalCI bool
}
FindLargestCompatibleOptions configures how the search is performed.
type ShipOptions ¶
type ShipOptions struct {
// SkipLocalCI skips local CI validation.
SkipLocalCI bool
// Wait waits for CI and auto-merges the PR.
Wait bool
}
ShipOptions configures the ship operation.
type ShipResult ¶
type ShipResult struct {
// IncludedStacks are stacks that were successfully shipped.
IncludedStacks []Stack
// ExcludedStacks are stacks that were excluded due to conflicts.
ExcludedStacks []ExcludedStack
// PRNumber is the created PR number.
PRNumber git.PRNumber
// PRURL is the created PR URL.
PRURL string
// BranchName is the consolidation branch name.
BranchName string
}
ShipResult contains the result of a ship operation.
type Shipper ¶
type Shipper struct {
// contains filtered or unexported fields
}
Shipper handles shipping selected stacks to trunk.
func NewShipper ¶
NewShipper creates a new shipper that runs the multi-stack merge with deps.
func (*Shipper) Ship ¶
func (s *Shipper) Ship(ctx context.Context, stacks []Stack, opts ShipOptions) (*ShipResult, error)
Ship ships the selected stacks to trunk by creating a consolidated PR. It uses the existing multi-stack merge functionality.
type Stack ¶
type Stack struct {
Stack stackview.StackInfo // The underlying stack
Status Status // Overall shippability status
Author string // GitHub username of stack author (from first PR)
PRTitle string // PR title of the root branch (for display)
// Breakdown of shippability components
ApprovalOK bool // All PRs have been approved
GitHubCIOK bool // All GitHub CI checks are passing
LocalCIOK *bool // Local CI result (nil = not checked)
// Blocking details
BlockingPRs []BlockingPR // PRs blocking shippability
}
Stack represents a stack with its shippability analysis.
func (*Stack) BranchCount ¶
BranchCount returns the total number of branches in this stack.
func (*Stack) DisplayTitle ¶
DisplayTitle returns the best title for displaying this stack. The analyzer populates PRTitle with: PR title > commit subject > branch name. Falls back to branch name if PRTitle is empty (e.g., in tests).
func (*Stack) IsBlocked ¶
IsBlocked returns true if the stack has failed CI or has changes requested.
func (*Stack) IsIncomplete ¶
IsIncomplete returns true if the stack is missing PRs or has drafts.
func (*Stack) IsShippable ¶
IsShippable returns true if the stack is ready to ship.
func (*Stack) RootBranch ¶
RootBranch returns the root branch name of this stack.
type Status ¶
type Status string
Status represents the overall shippability state of a stack.
const ( // StatusShippable indicates the stack is ready to ship (all checks pass, approved). StatusShippable Status = "shippable" // StatusPending indicates the stack is waiting on CI or review. StatusPending Status = "pending" // StatusBlocked indicates the stack cannot ship (CI failed or changes requested). StatusBlocked Status = "blocked" // StatusIncomplete indicates the stack is missing PRs or has drafts. StatusIncomplete Status = "incomplete" )