Documentation
¶
Index ¶
- Constants
- func IsRollbackRef(ref string) bool
- func NewCommand() *cobra.Command
- type AncestorFunc
- type CleanReleasesRequest
- type EnvPromotion
- type FinalizeOption
- type Finalizer
- func (f *Finalizer) CommitAndPush() error
- func (f *Finalizer) Run() error
- func (f *Finalizer) SetActor(actor string)
- func (f *Finalizer) SetDeployResult(name, result string)
- func (f *Finalizer) SetHeadSHA(sha string)
- func (f *Finalizer) SetPromotionResult(pr *PromotionResult)
- func (f *Finalizer) WriteConfig() error
- type LifecycleCleaner
- type Option
- type PreflightResult
- type Preflighter
- type PreflighterOptions
- type Promoter
- type PromoterOptions
- type PromotionMode
- type PromotionResult
- type ReleaseData
Constants ¶
const RollbackRefPrefix = "rollback/"
RollbackRefPrefix marks an environment whose state was set by a manual rollback rather than a hotfix integration branch. A rollback points an environment back at a prior known-good SHA and records the prior pointer in state.<env>.ref using this prefix, so the divergence guards treat the env as off-trunk (blocking forward promotion until it rejoins) without implying a hotfix integration branch, tags, or release drafts exist.
Variables ¶
This section is empty.
Functions ¶
func IsRollbackRef ¶ added in v0.2.0
IsRollbackRef reports whether ref is a rollback-divergence ref (set by a manual rollback) rather than a hotfix integration ref. The rejoin cleanup uses this to skip integration-branch and hotfix-release deletion for an env that diverged via rollback, since no such objects were created.
func NewCommand ¶
NewCommand creates the promote parent command with subcommands.
Types ¶
type AncestorFunc ¶ added in v0.2.0
AncestorFunc reports whether ancestor is contained in (is an ancestor of) descendant. It mirrors git.IsAncestor and exists so the divergence guards can be exercised deterministically in tests without a real object store.
type CleanReleasesRequest ¶ added in v0.2.0
CleanReleasesRequest describes the hotfix release objects to remove when an environment rejoins trunk. BaseVersion is the version the environment held while diverged; its rc base identifies the hotfix tags (vX.Y.Z-rc.N.hotfix.M) and drafts that the RC-shaped cleanup deliberately cannot see.
type EnvPromotion ¶
type EnvPromotion struct {
Environment string `json:"environment"`
SourceEnv string `json:"source_env"`
SHA string `json:"sha"`
Version string `json:"version"`
NeedsDeploy bool `json:"needs_deploy"`
}
EnvPromotion describes what should happen for a single environment
type FinalizeOption ¶ added in v0.2.0
type FinalizeOption func(*Finalizer)
FinalizeOption customizes optional, additive Finalizer behavior. Required inputs stay positional on the constructor; cross-cutting concerns such as the divergence-end cleanup are threaded through options so existing callers and signatures are unaffected.
func WithLifecycleCleaner ¶ added in v0.2.0
func WithLifecycleCleaner(c LifecycleCleaner) FinalizeOption
WithLifecycleCleaner injects the divergence-end cleanup performed when a promotion rejoins a diverged environment to trunk. The default is a no-op, so promotions into non-diverged environments incur no cleanup behavior.
type Finalizer ¶
type Finalizer struct {
// contains filtered or unexported fields
}
Finalizer handles post-deployment state updates after a promotion completes. It updates the manifest state based on: - Deploy job results (from GitHub Actions) - Promotion result (from preflight output) - Release publishing status
func NewFinalizer ¶
func NewFinalizer(configPath, targetEnv string, opts ...FinalizeOption) (*Finalizer, error)
NewFinalizer creates a new Finalizer instance. It loads the manifest from configPath and prepares for state updates. The manifest must have the ci: key at the top level.
Optional, additive behavior (such as the divergence-end lifecycle cleanup) is supplied through functional options so the required inputs stay positional.
func NewFinalizerWithKey ¶
func NewFinalizerWithKey(configPath, targetEnv, manifestKey string, opts ...FinalizeOption) (*Finalizer, error)
NewFinalizerWithKey creates a Finalizer with a custom manifest key.
func (*Finalizer) CommitAndPush ¶
CommitAndPush persists the manifest changes back to the trunk branch.
On real GitHub the write goes through the Contents REST API (via the gh CLI): API-created commits are signed by GitHub (shown as Verified) and, when made with a bypass-capable token, update the trunk even when a required status check protects the branch. In the act/gitea e2e environment there is no GitHub API, so the change is committed and pushed with plain git. The environment is detected exactly as the generated dispatch steps do, by GITHUB_SERVER_URL != https://github.com.
Note: We skip git pull because the workflow just checked out the repo, so it should already be at the latest state. The finalize job runs after all deploy jobs complete, and they don't modify the manifest.
func (*Finalizer) Run ¶
Run executes the finalization logic: 1. Updates environment state for all promoted environments 2. Updates per-deploy state for successful deploys only 3. Updates latest_release state if publishing a release 4. Writes the updated manifest back to disk
Note: This updates the in-memory state and writes to disk. Call this only when you want to persist changes.
func (*Finalizer) SetDeployResult ¶
SetDeployResult records the result of a deploy job. Valid results: "success", "failure", "skipped", "cancelled"
func (*Finalizer) SetHeadSHA ¶ added in v0.2.0
SetHeadSHA overrides the SHA written to state.<env>.sha during finalization. Call this when one or more callbacks declared auto_commits: true, meaning they pushed additional commits after the workflow started. Passing the post-callback HEAD ensures the recorded state matches what was actually built/deployed rather than the triggering commit.
When sha is empty (the default) the SHA from the promotion result is used unchanged, preserving existing behavior for runs without auto-committing callbacks.
func (*Finalizer) SetPromotionResult ¶
func (f *Finalizer) SetPromotionResult(pr *PromotionResult)
SetPromotionResult sets the promotion result from preflight output. This contains information about which environments to update and release actions.
func (*Finalizer) WriteConfig ¶
WriteConfig writes the updated manifest back to disk. The output is wrapped in the manifest key (default: "ci") to match the expected format.
type LifecycleCleaner ¶ added in v0.2.0
type LifecycleCleaner interface {
// DeleteEnvBranch deletes the env/<env> integration branch.
DeleteEnvBranch(env string) error
// CleanHotfixReleases deletes the hotfix tags and release drafts for the
// rejoining environment's prior base version.
CleanHotfixReleases(req CleanReleasesRequest) error
}
LifecycleCleaner performs the side effects of ending a divergence: deleting the per-environment integration branch and removing the hotfix tags and release objects minted for that base. It is a small interface with a no-op default so a normal promotion into a non-diverged environment is never forced to provide one; the production implementation is wired only when finalize runs in a repository with GitHub context.
type Option ¶ added in v0.2.0
type Option func(*guardConfig)
Option customizes optional, additive behavior on a Promoter or Preflighter. Required inputs stay positional on the constructor; cross-cutting concerns (such as the git-ancestry checker) are threaded through options so new capability never changes an existing signature.
func WithAncestorFunc ¶ added in v0.2.0
func WithAncestorFunc(fn AncestorFunc) Option
WithAncestorFunc overrides the git-ancestry checker used by the promotion divergence guards. The default is git.IsAncestor; tests inject a stub so the patch-containment rule can be exercised without a populated repository.
type PreflightResult ¶
type PreflightResult struct {
// Mode and configuration
Mode PromotionMode `json:"mode"`
Target string `json:"target,omitempty"` // For cascade mode
Force bool `json:"force,omitempty"` // For default mode
RollbackOnFailure bool `json:"rollback_on_failure,omitempty"` // Revert successful deploys if any fails
// Source/target info
SourceEnv string `json:"source_env"`
TargetEnv string `json:"target_env"`
SourceSHA string `json:"source_sha"`
SourceVersion string `json:"source_version"`
// SourceImageDigest is an immutable artifact identifier (e.g. a Docker image
// content digest) for the source env, threaded alongside the mutable
// SourceVersion so operators can pin deploys to immutable content. It is
// sourced from the source env's build state: cascade treats artifact_id as an
// opaque immutable id, so this is only a real content digest if the operator's
// build populates artifact_id with one. When the source env has multiple
// builds, the first build (by sorted build name) with a non-empty artifact_id
// is used; when none has one, this stays empty and the deploy input is omitted.
SourceImageDigest string `json:"source_image_digest,omitempty"`
// Rollback SHA (target env's current SHA before promotion - what we revert to on failure)
RollbackSHA string `json:"rollback_sha,omitempty"`
// Changelog comparison point (SHA of first target env before promotion)
ChangelogBaseSHA string `json:"changelog_base_sha"`
// Environments to update
EnvsToUpdate []string `json:"envs_to_update"`
SkippedEnvs []string `json:"skipped_envs"`
// Deploy decisions
DeploysToRun []string `json:"deploys_to_run"` // Local deploys to run
ExternalDeploysToRun []string `json:"external_deploys_to_run"` // External deploys to run
// Release info
IsPrereleaseEnv bool `json:"is_prerelease_env"`
IsFinalEnv bool `json:"is_final_env"`
IsCascade bool `json:"is_cascade"`
ReleaseAction string `json:"release_action"`
// Full-pass prod deployment (separate from cascade)
HasProdDeployment bool `json:"has_prod_deployment"`
ProdSHA string `json:"prod_sha"`
ProdVersion string `json:"prod_version"`
// Breaking changes
HasBreaking bool `json:"has_breaking"`
CanProceed bool `json:"can_proceed"`
BreakingBlockedAt string `json:"breaking_blocked_at,omitempty"` // The transition that was blocked
// Warnings carries non-fatal advisories surfaced during preflight, for
// example a forced override of the diverged-env patch-containment guard.
Warnings []string `json:"warnings,omitempty"`
// Full promotion result for downstream use
PromotionResult *PromotionResult `json:"promotion_result"`
}
PreflightResult contains all outputs needed by the workflow
type Preflighter ¶
type Preflighter struct {
// contains filtered or unexported fields
}
Preflighter handles preflight validation and planning
func NewPreflighter ¶
func NewPreflighter(opts PreflighterOptions, options ...Option) *Preflighter
NewPreflighter creates a new Preflighter instance. Optional behavior (such as the git-ancestry checker used by the divergence guards) is supplied through functional options so the required inputs stay positional.
func (*Preflighter) Run ¶
func (p *Preflighter) Run() (*PreflightResult, error)
Run executes the preflight checks and returns the result
func (*Preflighter) SetDeployCheck ¶
func (p *Preflighter) SetDeployCheck(name string, include bool)
SetDeployCheck sets whether a deploy should be included
type PreflighterOptions ¶
type PreflighterOptions struct {
Config *config.CICDFile
Mode PromotionMode
Target string // For cascade mode (e.g., "dev-to-prod")
Force bool // For default mode
BaseDir string
DeploysFilter []string // Specific deploys to include (empty = all)
RollbackOnFailure bool // Revert successful deploys if any fails
AllowDowngrade bool // Permit promoting an older version onto an env
}
PreflighterOptions configures the Preflighter
type Promoter ¶
type Promoter struct {
// contains filtered or unexported fields
}
Promoter handles promotion logic
func NewPromoter ¶
func NewPromoter(opts PromoterOptions, options ...Option) (*Promoter, error)
NewPromoter creates a new Promoter. Optional behavior (such as the git-ancestry checker used by the divergence guards) is supplied through functional options so the required inputs stay positional.
func (*Promoter) CommitAndPush ¶
CommitAndPush commits the state change and pushes to remote. It delegates to the shared git rebase-retry helper so promote and hotfix finalize write manifest state identically.
func (*Promoter) Promote ¶
func (p *Promoter) Promote(mode PromotionMode, target string) (*PromotionResult, error)
Promote executes a promotion and returns the result mode: "default" for sequential single-step, "cascade" for atomic multi-step target: for cascade mode, the target (e.g., "dev-to-prod")
type PromoterOptions ¶
type PromoterOptions struct {
ConfigPath string
DryRun bool
Actor string
Force bool // For default mode: continue on failure
}
PromoterOptions configures the Promoter
type PromotionMode ¶
type PromotionMode string
PromotionMode defines how the promotion operates
const ( // ModeDefault promotes each environment to its immediate next (sequential) // Supports force flag to continue on failure ModeDefault PromotionMode = "default" // ModeCascade promotes source through all intermediate envs to target (atomic) // Bails entirely on any failure - no partial state updates ModeCascade PromotionMode = "cascade" )
type PromotionResult ¶
type PromotionResult struct {
Success bool `json:"success"`
Mode PromotionMode `json:"mode"`
Target string `json:"target,omitempty"` // Target for cascade mode (e.g., "dev-to-prod")
Force bool `json:"force,omitempty"` // Force flag for default mode
IsCascade bool `json:"is_cascade"` // True for cascade mode
Promotions []EnvPromotion `json:"promotions"` // Successful promotions
FailedEnvs []string `json:"failed_envs,omitempty"` // Envs that failed (default+force)
SkippedEnvs []string `json:"skipped_envs,omitempty"` // Envs skipped due to no-op
FinalEnv string `json:"final_env,omitempty"`
ReleaseAction string `json:"release_action,omitempty"` // "prerelease", "publish", or ""
ReleaseData *ReleaseData `json:"release_data,omitempty"`
ProdDeployment *EnvPromotion `json:"prod_deployment,omitempty"`
Error string `json:"error,omitempty"`
}
PromotionResult is the output of a promotion operation
func (*PromotionResult) ToJSON ¶
func (r *PromotionResult) ToJSON() string
ToJSON returns the result as JSON
type ReleaseData ¶
type ReleaseData struct {
SHA string `json:"sha"`
RCVersion string `json:"rc_version"` // e.g., v1.0.0-rc.0
SemVersion string `json:"sem_version"` // e.g., v1.0.0
}
ReleaseData contains info for release management