Documentation
¶
Overview ¶
Package feature defines a feature's metadata (feature.json, stored on refs/ghostbranch/features/<name> in the shadow repo) and computes its state. State is never stored.
Index ¶
Constants ¶
const ( SchemaVersion = "0.12" MetaFile = "feature.json" )
const ( ChecksPassed = "passed" ChecksFailed = "failed" ChecksNoCI = "no_ci" ChecksTimeout = "timeout" ChecksNotRun = "not_run" ChecksPending = "pending" LeakClean = "clean" LeakFound = "found" LeakNotRun = "not_run" )
Gate check and leak outcomes.
const ArchiveRefPrefix = "refs/ghostbranch/archive/"
ArchiveRefPrefix holds the archive refs in the shadow repo: a feature handed off to the public repo (6.5) keeps its shadow branch's head there.
const MainParent = "main"
MainParent is the parent of a feature that isn't stacked on another: a placeholder for the pair's base branch on every pair, never a GitHub branch name. "Is this feature at the bottom?" compares a parent with it; a PR base (Promoted.Base, a plan's prs[].base) holds the real name instead, and display code names the base branch for it.
Variables ¶
var States = []State{ StateDraft, StateInReview, StateGatePassed, StatePublished, StateMerged, StateMergedMoved, StatePRClosed, StateBranchGone, StateAbandoned, StateUnreadable, StateParentStale, StatePublicPRNeedsUpdate, StatePRBehind, StateArchived, }
States is every State, in the order they are declared above, which is the order of the state enum in schemas/v0/feature-report.schema.json. The guide's Lifecycle list is tested against it, so a new state can't be left out of the guide.
Functions ¶
func ArchiveRef ¶
ArchiveRef is feature name's archive ref in the shadow repo.
func ValidateName ¶
ValidateName checks a feature or public branch name. field names the input in the error. base is the pair's base branch, reserved like main: a feature of that name would collide with the shadow's copy of it. Callers with no pair yet pass main.
Types ¶
type AdoptedCommit ¶
type AdoptedCommit struct {
SHA string `json:"sha"`
Author string `json:"author"`
Subject string `json:"subject"`
Folded bool `json:"folded,omitempty"`
}
AdoptedCommit is one public PR commit feature pull adopted. Folded: a squash or curated update folded it into its own commits, which keep its content (and credit its author); it is no longer on the PR by itself.
type Archived ¶
Archived records a feature handed off to the public repo: its shadow branch was moved to Ref, at Head, at At. Its PR is fixed by pushing to the PR's branch. promote, gate, feature pull and waivers add refuse it, and so do feature start --from and feature restack --onto: nothing is stacked on it.
type Gate ¶
type Gate struct {
FeatureHead string `json:"feature_head"`
PublicMain string `json:"public_main"`
Overlay string `json:"overlay"`
Candidate string `json:"candidate"`
PublishedTree string `json:"published_tree"`
Commits []GateCommit `json:"commits"`
Checks string `json:"checks"`
Leak string `json:"leak"`
At time.Time `json:"at"`
// ScannedAs is the mode the gate's leak scan covered; empty in a gate
// recorded before it was stored, which promote does not reuse.
ScannedAs string `json:"scanned_as,omitempty"`
// FailedChecks names the checks that failed; absent before 0.7.
FailedChecks []string `json:"failed_checks,omitempty"`
// ShadowPR is the gate's draft PR in the shadow repo; 0 before 0.7.
ShadowPR int `json:"shadow_pr,omitempty"`
// StartedAt is when the gate pushed its candidate. CI time budgets
// count from it, so a wait in another process keeps the same budget.
// Zero before 0.7.
StartedAt time.Time `json:"started_at,omitzero"`
// Parent is the feature the gate stacked on; empty when it built on
// public main.
Parent string `json:"parent,omitempty"`
// ForkedAt is the fork point the gate replayed the feature's own
// commits from; empty when unstacked.
ForkedAt string `json:"forked_at,omitempty"`
// Base is the commit the feature's own commits were replayed onto: R,
// the rebased tip of the features below, or, for an append to the
// feature's open PR (Update), that PR's head H; empty otherwise (public
// main).
Base string `json:"base,omitempty"`
// BaseTree is Base's published tree: what the leak scan compared the
// feature's own commits with. Empty when unstacked.
BaseTree string `json:"base_tree,omitempty"`
// Below lists every feature under this one with the head the gate
// built on, bottom first; nil when unstacked.
Below []StackHead `json:"below,omitempty"`
// Update is how the gate built the update of the feature's open PR;
// nil for a first publish and in a gate recorded before 0.12. An append
// gate's Base is the PR's head H, and its Commits map the new feature
// commits to the public commits appended on H.
Update *GateUpdate `json:"update,omitempty"`
}
Gate is the last gate result, pinned to the inputs it was computed from.
func (*Gate) Pending ¶
Pending reports a gate whose CI wait hasn't finished: a job. A pending record without its shadow PR was rewritten by an older binary and is no job: gate it again.
func (*Gate) StackFreshFor ¶
StackFreshFor reports whether the gate built on the stack as it is now: the same parent ("" for main) and fork point ("" when unstacked), and every feature below (below maps each to its head now) at the head it recorded. An unstacked gate of an unstacked feature is fresh; FreshFor checks the feature's own inputs.
type GateCommit ¶
GateCommit maps one commit of the gate's rebased chain to the feature branch commit it replays.
type GateUpdate ¶
type GateUpdate struct {
PR int `json:"pr"`
Head string `json:"head"`
Base string `json:"base"`
Style string `json:"style"` // append | replace
Reason string `json:"replace_reason,omitempty"`
}
GateUpdate is how a gate built the update of a feature's open PR: on its head H, by appending the new commits or replacing the branch.
type Meta ¶
type Meta struct {
SchemaVersion string `json:"schema_version"`
Name string `json:"name"`
Branch string `json:"branch"`
CreatedBy string `json:"created_by"`
CreatedAt time.Time `json:"created_at"`
Base string `json:"base"`
Abandoned bool `json:"abandoned"`
Gate *Gate `json:"gate"`
Promoted *Promoted `json:"promoted"`
// Parent is the feature this one is stacked on; "" (or MainParent)
// means the pair's base branch, as in every record before 0.11, whatever
// that branch's real name. ParentName reads it.
Parent string `json:"parent,omitempty"`
// ForkedAt is the parent's commit the feature was branched from or last
// restacked onto: the feature's own commits are ForkedAt..head. Empty
// for a feature started from main.
ForkedAt string `json:"forked_at,omitempty"`
// Archived is set once the feature was handed off to the public repo
// (6.5); nil otherwise. It is optional, so records stay at 0.12: an
// older binary ignores it and reads the feature as branch_gone.
Archived *Archived `json:"archived,omitempty"`
}
Meta is feature.json.
func (Meta) ParentName ¶
ParentName is the feature's parent: a feature name, or MainParent.
type Promoted ¶
type Promoted struct {
PublicPR int `json:"public_pr"`
PlanID string `json:"plan_id"`
// FeatureHead is the head the publish was planned from; empty in a
// record written before 0.6. A feature has moved when its branch head
// is no longer FeatureHead.
FeatureHead string `json:"feature_head,omitempty"`
// Branch is the public branch it was published to; empty in a record
// written before 0.11 (the feature's name then, unless --branch named one).
Branch string `json:"branch,omitempty"`
// Base is its PR's base branch, a real GitHub branch name: the pair's
// base branch (main on most pairs, but master or trunk on others), or
// the public branch of the feature below it in a stack. It is compared
// with the base GitHub reports, never with MainParent. Sync records
// GitHub's retargeting.
Base string `json:"base,omitempty"`
// PublishedHead is the public branch's head as Ghostbranch last knew it:
// the plan's tip at publish, and GitHub's restack of it once sync saw
// one with the same patch-ids.
PublishedHead string `json:"published_head,omitempty"`
// PatchIDs are the published commits' stable patch-ids, oldest first.
PatchIDs []string `json:"patch_ids,omitempty"`
// Stack is the native GitHub stack its PR is in; 0 when none.
Stack int `json:"stack,omitempty"`
// NeedsUpdate: the PR below it merged by squash or rebase while the PRs
// were plain chained PRs (no native stack), so its open public PR still
// carries that parent's old commits. Republishing it is 6.1a-2.
NeedsUpdate bool `json:"needs_update,omitempty"`
// Adopted are commits someone made on the public PR's branch on GitHub
// that feature pull brought into the feature: they came from the public
// PR, not from Ghostbranch. Absent when none.
Adopted []AdoptedCommit `json:"adopted,omitempty"`
}
Promoted records the public PR a feature was published as.
type State ¶
type State string
State is a feature's computed lifecycle state.
const ( StateDraft State = "draft" StateInReview State = "in_review" StateGatePassed State = "gate_passed" StatePublished State = "published" StateMerged State = "merged" StateMergedMoved State = "merged_moved" StatePRClosed State = "pr_closed" StateBranchGone State = "branch_gone" StateAbandoned State = "abandoned" // StateUnreadable is a feature whose record couldn't be read: the survey // reports it with an error, and only a console close removes it. StateUnreadable State = "unreadable" // StateParentStale is a stacked feature where a feature below moved // since the feature above it forked from it, or is gone; feature // restack on the lowest one fixes it. StateParentStale State = "parent_stale" // StatePublicPRNeedsUpdate is a feature published as a plain chained PR // (not a native stack) whose PR below was squash- or rebase-merged: its // public branch still carries the old parent commits. StatePublicPRNeedsUpdate State = "public_pr_needs_update" // StatePRBehind is a published feature whose PR is open and whose // branch has commits the PR doesn't: gate it, then promote updates the // PR. StatePRBehind State = "pr_behind" // StateArchived is a published feature handed off to the public repo: // its shadow branch is archived and its open PR is fixed by pushing to // it. Merged reads merged (or merged_moved), closed reads pr_closed. StateArchived State = "archived" )
func StateOf ¶
func StateOf(in StateInput) State
StateOf computes state. The first matching rule wins.
type StateInput ¶
type StateInput struct {
Meta Meta
BranchExists bool
Head string
PublicMain string
Overlay string
// PRState is the forge's view of the published PR: "", "open",
// "merged", "closed" or "unknown".
PRState string
// Moved reports that the branch has moved since it was published.
Moved bool
// ParentMoved reports that a feature below moved since the feature
// above it forked from it, or is gone; false when unstacked.
ParentMoved bool
// StackStale reports that the gate built on a stack that has changed
// since (Gate.StackFreshFor is false); false when unstacked.
StackStale bool
// Behind counts the branch's commits since it was published that its
// open PR doesn't have; 0 when it isn't published or the PR isn't open.
Behind int
}
StateInput is everything state depends on.