Documentation
¶
Overview ¶
Package release builds immutable Release records from a pinned composition, compares two releases, and moves one release between coordination repositories as a portable document.
The invariant the whole package exists to protect: a Release must be reproducible. Given the same component commits it must produce byte-identical content, and it must be impossible for a later change in a component repository or a coordination override to alter a Release that already exists.
Index ¶
- Variables
- func AssetIndex(ctx context.Context, tree *gitops.Tree, storageDomainID string) (domain.AssetIndex, []domain.AssetIndexEntry, error)
- func AssetRoot(ctx context.Context, tree *gitops.Tree, storageDomainID string) (string, domain.AssetIndex, error)
- func Export(ctx context.Context, repo *gitops.Repo, name string) (domain.Release, []byte, string, error)
- func Notes(cs ChangeSet, next domain.Release) string
- func Pointers(ctx context.Context, tree *gitops.Tree, storageDomainID string) (map[string]pointer.Pointer, error)
- func TagName(release, repositoryID string) string
- type ChangeSet
- type ComponentChange
- type ComponentReport
- type ComponentTag
- type CreateInput
- type CreateResult
- type ImportResult
- type NotReleasableError
- type ObjectChecker
- type ObjectReport
- type Pin
- type ResourceChange
Constants ¶
This section is empty.
Variables ¶
var ErrAssetIndex = errors.New("release: cannot build the asset index")
ErrAssetIndex marks a tree whose FXVCS content cannot be described.
var ErrNotReleasable = errors.New("release: composition is not releasable")
ErrNotReleasable aggregates everything that stopped a release.
Functions ¶
func AssetIndex ¶
func AssetIndex(ctx context.Context, tree *gitops.Tree, storageDomainID string) (domain.AssetIndex, []domain.AssetIndexEntry, error)
AssetIndex derives the canonical asset index of a pinned component tree.
An entry is any regular blob whose content is an FXVCS pointer. Deriving membership from the bytes rather than from `.gitattributes` is deliberate: the attributes file says what *should* be filtered from now on, while the asset root has to describe what the pinned commit actually contains. A path that someone committed as a real file before it was tracked is honestly not an asset, and a path whose tracking rule was removed after the fact still is one while its blob is a pointer.
Blobs larger than a pointer can be are never read.
func AssetRoot ¶
func AssetRoot(ctx context.Context, tree *gitops.Tree, storageDomainID string) (string, domain.AssetIndex, error)
AssetRoot computes the asset-root digest of a pinned component tree.
func Export ¶
func Export(ctx context.Context, repo *gitops.Repo, name string) (domain.Release, []byte, string, error)
Export returns one release as a portable YAML document and its digest. The caller decides where the bytes go; this package never touches stdout.
func Notes ¶
Notes renders a reviewable Markdown draft from a change set. The draft is a starting point for a human, not a published artifact, and it is written separately from the release so editing it cannot alter release identity.
Types ¶
type ChangeSet ¶
type ChangeSet struct {
From string `json:"from"`
To string `json:"to"`
// SameSource reports equal sourceSetDigest: identical component commits,
// assets, mounts, and portable non-component requirements. Two releases
// that differ only in activation are same-source.
SameSource bool `json:"sameSource"`
Components []ComponentChange `json:"components"`
Resources []ResourceChange `json:"resources"`
// Enabled/Disabled are the resource counts of the new release.
Enabled int `json:"enabled"`
Disabled int `json:"disabled"`
}
ChangeSet compares a base release with a new one.
type ComponentChange ¶
type ComponentChange struct {
RepositoryID string `json:"repositoryID"`
RepositoryName string `json:"repositoryName"`
// Change is added | removed | updated | unchanged.
Change string `json:"change"`
FromCommit string `json:"fromCommit,omitempty"`
ToCommit string `json:"toCommit,omitempty"`
// AssetsChanged reports that the component's asset root moved, so its
// tracked content is different (not only its source).
AssetsChanged bool `json:"assetsChanged,omitempty"`
// MountChanged reports a realization-shape change.
MountChanged bool `json:"mountChanged,omitempty"`
FromMount string `json:"fromMount,omitempty"`
ToMount string `json:"toMount,omitempty"`
}
ComponentChange is one component's difference between two releases.
type ComponentReport ¶
type ComponentReport struct {
RepositoryID string `json:"repositoryID"`
RepositoryName string `json:"repositoryName"`
Remote string `json:"remote"`
Ref string `json:"ref,omitempty"`
Commit string `json:"commit"`
AssetRoot string `json:"assetRoot"`
Assets int `json:"assets"`
Mount string `json:"mount"`
DescriptorFrom string `json:"descriptorFrom"`
Resources int `json:"resources"`
Objects ObjectReport `json:"objects,omitzero"`
// DurablePin reports whether the component's remote still advertises a ref
// at this commit.
DurablePin *bool `json:"durablePin,omitempty"`
}
ComponentReport is what one component contributed.
type ComponentTag ¶
type ComponentTag struct {
RepositoryID string `json:"repositoryID"`
Remote string `json:"remote"`
Tag string `json:"tag"`
Commit string `json:"commit"`
}
ComponentTag is the durable ref `--tag-components` plans for one component.
func PlanComponentTags ¶
func PlanComponentTags(rel domain.Release) []ComponentTag
PlanComponentTags lists the tags `--tag-components` would create.
func TagComponents ¶
func TagComponents(ctx context.Context, repo *gitops.Repo, rel domain.Release) ([]ComponentTag, error)
TagComponents creates and pushes every planned tag. A failure anywhere aborts with an error and the caller must not write the release: a partially tagged release would advertise durable pins it does not have.
type CreateInput ¶
type CreateInput struct {
Name string
// Pins override the stack ref per component.
Pins []Pin
// Enable and Disable are release-only activation overrides, selected by
// resource name, "<repositoryID>:<path>", or a runtime/external ID.
Enable, Disable []string
// VariantOf groups this release with another for humans; it never affects
// identity or source equality.
VariantOf string
// CreatedBy is recorded in the release metadata.
CreatedBy string
// Now is the creation timestamp.
Now time.Time
// MinimumFXVCSVersion is recorded on the release; empty computes the
// maximum requirement across the stack and pinned components.
MinimumFXVCSVersion string
// Objects verifies storage availability; nil skips the check.
Objects ObjectChecker
// AllowUnverifiedObjects keeps going when a required remote cannot be
// reached from this machine.
AllowUnverifiedObjects bool
}
CreateInput describes the release to build.
type CreateResult ¶
type CreateResult struct {
Release domain.Release `json:"release"`
Components []ComponentReport `json:"components"`
Plan stack.Plan `json:"-"`
Warnings []string `json:"warnings,omitempty"`
Problems []stack.Problem `json:"problems,omitempty"`
}
CreateResult is the built release plus everything worth reviewing.
func Create ¶
func Create(ctx context.Context, repo *gitops.Repo, in CreateInput) (*CreateResult, error)
Create resolves the composition and builds an immutable release record. It does not write, commit, or tag anything.
type ImportResult ¶
type ImportResult struct {
Release domain.Release `json:"release"`
Digest string `json:"digest"`
Path string `json:"path"`
// Written is false when an identical record was already present.
Written bool `json:"written"`
// Warnings name components the importing stack does not register.
Warnings []string `json:"warnings,omitempty"`
}
ImportResult reports what an import did.
type NotReleasableError ¶
NotReleasableError carries every problem found in one pass.
func (*NotReleasableError) Error ¶
func (e *NotReleasableError) Error() string
func (*NotReleasableError) Is ¶
func (e *NotReleasableError) Is(target error) bool
type ObjectChecker ¶
type ObjectChecker interface {
CheckComponent(ctx context.Context, cfg *domain.Repository, pointers map[string]pointer.Pointer) (ObjectReport, error)
}
ObjectChecker verifies that the objects a pinned component references are already durable in storage. Release creation checks this independently of the pre-push barrier, because a user can bypass Git client hooks and a release whose assets exist only on a laptop is not deployable.
type ObjectReport ¶
type ObjectReport struct {
// Remotes are the remote names required for publication.
Remotes []string `json:"remotes"`
// Assets is how many placeholder paths were checked.
Assets int `json:"assets"`
// Missing describes assets absent from a required remote.
Missing []string `json:"missing,omitempty"`
// Unverifiable names required remotes this machine cannot reach, with the
// reason. A release is not written on an unverifiable remote unless the
// caller explicitly allows it.
Unverifiable []string `json:"unverifiable,omitempty"`
}
ObjectReport is one component's object-availability result.
type Pin ¶
type Pin struct {
RepositoryID string
// Ref is a branch, tag, or full commit id. Empty uses the stack ref.
Ref string
}
Pin selects the commit for one component.
type ResourceChange ¶
type ResourceChange struct {
Name string `json:"name"`
// Change is added | removed | activation | order | provenance.
Change string `json:"change"`
Source string `json:"source"`
RepositoryName string `json:"repositoryName,omitempty"`
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
}
ResourceChange is one resource's difference between two releases.