featurehub

package
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package featurehub is the hub's half of running a feature on an executor that isolates from the hub's filesystem (Task 20367).

A feature (pkg/feature) is a linked git worktree of a project's repository, on the hub, on a branch of its own. A sandbox cannot use that worktree: its .git names the parent repository by an absolute host path, and handing the sandbox the parent's .git to make it resolve would let hooks and configuration written there run on the hub at the next git command anything here runs in that repository. So a feature travels as a branch instead:

  • Ship turns the feature's branch into a size-capped git bundle that the executor builds a standalone checkout from — the commits on top of an upstream clone when the parent's upstream already holds the feature's base, otherwise the whole branch, shallow when the whole branch is too large;
  • Land takes the write-back bundle the run returns, vets it in quarantine (pkg/writeback), and fast-forwards the hub's worktree onto it when the worktree is clean and the work builds on its HEAD — and otherwise parks it on a branch of its own and reports a conflict, never forcing anything;
  • Create, Remove, OpenPR and RefreshPR are pkg/featureops's operations, run here, in hub mode, for a project whose executor cannot see the hub's worktrees and so cannot run them itself.

Why the hub runs git at all

The source of truth for a feature is the branch in the hub's copy of the repository, and only something that can read the hub's filesystem can ship it or land work onto it. Every executor that could is, by construction, not the one the feature runs on — the point of the exercise is that the run happens somewhere the hub's files are not. So this package is part of the executor boundary (tests/security treats pkg/executor/... as the sanctioned place a process may be started from): it runs git, and only git, with fixed subcommands, in the hub's own repositories, and never a harness or anything a repository can name. Every invocation runs with a closed environment — no system or global configuration — and with executor.HardenedGitConfig, so a hook, a filter, an fsmonitor or a signing program configured in the repository does not run. That matters because the repository is not always only the hub's to write: a project bound to a container executor has its directory, .git included, mounted into its own sandbox.

Index

Constants

View Source
const ReturnedBranchPrefix = "cloop/returned/"

ReturnedBranchPrefix is where work that could not be fast-forwarded is kept, under the feature's slug. Not under feature.BranchPrefix: a branch there would read as another feature's.

Variables

View Source
var ErrNoCredential = errors.New("no credential for the project's repository")

ErrNoCredential reports a pull request the hub has no credential to open.

Functions

func Create

Create makes a feature of opts.ProjectDir.

func HubEnv

func HubEnv(ctx context.Context, dir string) (func(extra ...[2]string) []string, error)

HubEnv returns the environment renderer for pkg/featureops's hub mode (featureops.WithHubEnv), for the repository at dir.

func OpenPR

OpenPR pushes a feature's branch and opens its pull request. opts.Token is the only credential used — the project's grant, or the hub's own token where policy allows it; the caller decides which.

func Origin

func Origin(ctx context.Context, dir string) (featureops.Remote, error)

Origin returns the forge repository behind the feature's origin remote, read with hub-mode git: what a pull request would be opened against.

func RefreshPR

func RefreshPR(ctx context.Context, dir, token, apiURL string) (*feature.PR, error)

RefreshPR re-reads a feature's pull request state from the forge.

func Remove

Remove removes a feature of opts.ProjectDir.

func TrackingCommit

func TrackingCommit(ctx context.Context, dir, branch string) (string, error)

TrackingCommit returns the commit the repository at dir records for origin/<branch> — the origin's tip as the hub last fetched it — for a run whose work is pushed back and measured from it (Task 20390). The hub's own git, hardened as every invocation here is: the repository's configuration runs nothing.

Types

type LandOutcome

type LandOutcome string

LandOutcome is what became of a feature run's returned work.

const (
	// LandNothing: the run returned no commits.
	LandNothing LandOutcome = "nothing"
	// LandFastForwarded: the feature's branch and worktree moved onto the
	// returned work.
	LandFastForwarded LandOutcome = "fast_forwarded"
	// LandConflict: the work was vetted and kept on a branch of its own,
	// because moving the feature onto it would have been more than a
	// fast-forward of a clean worktree.
	LandConflict LandOutcome = "conflict"
)

type LandRequest

type LandRequest struct {
	// FeatureDir is the feature's worktree on the hub.
	FeatureDir string
	// Reported is what the executor said the sandbox produced.
	Reported executor.WriteBackResult
	// Bundle is the bundle the executor returned.
	Bundle []byte
	// ShippedHead is the commit the run's tree was built at — the head of
	// the branch Ship produced. Work built on anything else is refused: the
	// hub sent that commit, and a run claiming another base is describing
	// history that did not come from here.
	ShippedHead string
	// Label names the run, for the branch conflicting work is kept on; a
	// timestamp is used when it is empty.
	Label string
	// MaxBytes caps the returned bundle — the same cap the sandbox was told
	// to stay under, enforced again here because the sandbox is the party it
	// constrains. 0 is executor.DefaultWriteBackBundleBytes.
	MaxBytes int64
	// Emit receives progress. May be nil.
	Emit func(string)
}

LandRequest is one feature run's returned work.

type LandResult

type LandResult struct {
	Outcome LandOutcome
	// Branch is the feature's branch.
	Branch string
	// CommitSHA is the returned tip.
	CommitSHA    string
	Commits      int
	FilesChanged int
	// KeptOn is the branch conflicting work was kept on.
	KeptOn string
	// Reason says why the work was kept rather than fast-forwarded.
	Reason string
}

LandResult reports what Land did.

func Land

func Land(ctx context.Context, req LandRequest) (LandResult, error)

Land vets a feature run's returned bundle and moves the feature onto it, or parks it when that would take more than a fast-forward of a clean worktree.

Refusals — a bundle that is not what the run was sent, or that fails the write-back content policy — return an error and leave nothing behind. A conflict is not an error: the work exists, vetted, on its own branch, and the result says where and why.

func (LandResult) Describe

func (r LandResult) Describe() string

Describe renders the result for the feature's journal.

type ShipMode

type ShipMode string

ShipMode says how a feature's branch travels to its sandbox.

const (
	// ShipOverlay: the executor clones the parent's upstream at the feature's
	// base, and the bundle carries only the commits the feature added.
	ShipOverlay ShipMode = "overlay"
	// ShipFull: the bundle carries the whole branch.
	ShipFull ShipMode = "full"
	// ShipShallow: the bundle carries the newest commits of the branch, its
	// lower edge recorded as a shallow boundary.
	ShipShallow ShipMode = "shallow"
)

type ShipRequest

type ShipRequest struct {
	// FeatureDir is the feature's worktree on the hub.
	FeatureDir string
	// Upstream is the parent repository's https upstream, normalised, when the
	// executor the feature runs on can fetch it; empty ships the whole branch.
	// The caller decides — it knows the executor and the project's grants.
	Upstream string
	// MaxBytes caps the bundle. 0 is executor.DefaultBranchBundleBytes; a
	// value over executor.MaxBranchBundleBytes is refused.
	MaxBytes int64
}

ShipRequest asks for a feature's branch as a bundle.

type Shipment

type Shipment struct {
	Mode ShipMode
	// Branch and Head are the feature's branch and the commit it is at.
	Branch string
	Head   string
	// Base and Upstream are, for an overlay, the commit the executor's clone
	// is pinned at and the repository it clones.
	Base     string
	Upstream string
	// Shallow is a shallow slice's lower edge.
	Shallow []string
	// File is the bundle, owned by the caller (see Remove); empty when the
	// overlay ships no commits.
	File   string
	Bytes  int64
	SHA256 string
}

Shipment is a feature's branch, ready to travel.

func Ship

func Ship(ctx context.Context, req ShipRequest) (*Shipment, error)

Ship produces the bundle a feature's sandbox is built from.

func (*Shipment) BranchBundle

func (s *Shipment) BranchBundle() *executor.BranchBundle

BranchBundle is the shipment's metadata as a Spec carries it.

func (*Shipment) Describe

func (s *Shipment) Describe() string

Describe renders the shipment for the run's journal.

func (*Shipment) Remove

func (s *Shipment) Remove()

Remove deletes the bundle file. Idempotent and nil-safe.

func (*Shipment) Workspace

func (s *Shipment) Workspace(sizeLimitMB int, grant string) executor.Workspace

Workspace is the workspace a Spec carries for this shipment: a git workspace pinned at the base with the branch on top for an overlay, a bundle workspace otherwise. grant names the credential the overlay's clone is fetched with.

type TooLargeError

type TooLargeError struct {
	Branch string
	// Smallest is the smallest bundle that could be built.
	Smallest int64
	Limit    int64
}

TooLargeError reports a branch that does not fit under the cap even as a single commit.

func (*TooLargeError) Error

func (e *TooLargeError) Error() string

func (*TooLargeError) Is

func (e *TooLargeError) Is(target error) bool

Is lets callers match executor.ErrWorkspaceUnavailable.

Jump to

Keyboard shortcuts

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