Help us shape the future of Go! Take the 2026 Go Developer Survey

retention

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: AGPL-3.0, AGPL-3.0-only Imports: 8 Imported by: 0

Documentation

Overview

Package retention implements a restic-style retention engine that works with any named+timestamped items (registry tags, forge releases, etc). Policies are additive — an item survives if ANY rule wants to keep it.

Index

Constants

This section is empty.

Variables

View Source
var DefaultIdentityVars = map[string]bool{
	"branch": true,
	"env":    true,
}

DefaultIdentityVars classifies a tag template's variables. IDENTITY vars name which independent series a tag belongs to — different values are separate lines that must never prune each other (a branch's tags never evict another branch's). Every other var is a SEQUENCE var: the axis a single series accumulates along (different values are points on one timeline). Only identity vars — these plus a per-policy `identity:` override — partition tags into groups.

Functions

func ApplyPolicies

func ApplyPolicies(candidates []Item, policy config.RetentionPolicy) []bool

ApplyPolicies evaluates all retention rules and returns a keep/prune decision for each candidate. candidates must be sorted newest-first. Policies are additive: an item is kept if ANY rule marks it.

func ApplyPoliciesScoped added in v0.10.0

func ApplyPoliciesScoped(candidates []Item, policy config.RetentionPolicy) []bool

ApplyPoliciesScoped partitions candidates by their governing policy (refs: scoped overrides via Effective) and evaluates each partition independently, so a `{match: go, keep_last: 4}` counts its 4 within the go-matched items only. candidates must be sorted newest-first. Falls through to ApplyPolicies when the policy declares no refs.

func ApplyTimeBucket

func ApplyTimeBucket(candidates []Item, keepSet []bool, count int, bucket BucketFn)

ApplyTimeBucket keeps the newest item in each of the last N distinct time buckets. candidates must be sorted newest-first.

func Effective added in v0.10.0

func Effective(policy config.RetentionPolicy, name string) config.RetentionPolicy

Effective resolves the policy governing one item name: the first refs: entry whose pattern matches wins, with unset ref fields inheriting the default policy; no match ⇒ the default itself. Protect/Identity/KeepBranches are policy-global (never per-ref) and always carry over. This is THE resolution point for scoped retention — every consumer of the grammar goes through it (directly or via Apply).

func TemplateToPattern

func TemplateToPattern(tmpl string) string

TemplateToPattern converts a single tag template to a regex pattern.

func TemplatesToPatterns

func TemplatesToPatterns(templates []string) []string

TemplatesToPatterns converts StageFreight tag templates into regex patterns suitable for config.MatchPatterns.

Template variables like {sha:8}, {version}, {branch} are replaced with regex wildcards (.+) so the pattern matches any resolved value.

Examples:

"dev-{sha:8}"    → "^dev-.+$"
"{version}"      → "^.+$"
"latest"         → "^latest$"
"!{branch}-rc"   → "!^.+-rc$"

func TruncateToDay

func TruncateToDay(t time.Time) time.Time

TruncateToDay truncates a time to the start of its day.

func TruncateToMonth

func TruncateToMonth(t time.Time) time.Time

TruncateToMonth truncates a time to the first day of its month.

func TruncateToWeek

func TruncateToWeek(t time.Time) time.Time

TruncateToWeek truncates a time to the start of its ISO week (Monday).

func TruncateToYear

func TruncateToYear(t time.Time) time.Time

TruncateToYear truncates a time to the first day of its year.

Types

type BucketFn

type BucketFn func(time.Time) time.Time

BucketFn truncates a time to the start of its bucket period.

type Item

type Item struct {
	Name      string
	CreatedAt time.Time
}

Item is a named, timestamped entity that can be pruned (tag, release, etc).

type Result

type Result struct {
	Matched int      // items matching the pattern set
	Kept    int      // items kept by policy
	Deleted []string // items successfully deleted
	Skipped []string // items skipped (digest shared with protected item)
	Blocked []string // items not attempted after a store-wide failure aborted the run
	Errors  []error  // errors from individual deletes
}

Result captures what the retention engine did.

func Apply

func Apply(ctx context.Context, store Store, templates []string, policy config.RetentionPolicy) (*Result, error)

Apply lists all items from the store, then prunes them PER SERIES rather than as one pool. Each tag is placed into a group keyed by (template, identity-values): its template plus the values of that template's identity vars ({branch}, {env}, …). The restic-style policy (keep_last + time buckets) is applied INDEPENDENTLY within each group, so a `keep_last: 6` keeps 6 of every series — one branch's tags never evict another's, and two accumulating templates never share slots.

Group taxonomy:

  • Accumulating (template has a sequence var like {sha}/{version}): keep_last / buckets prune along the sequence within the group.
  • Rolling (no sequence var, e.g. "latest-dev"): a single value overwritten in place — nothing to prune, so the whole group is kept.
  • keep_branches: N bounds the NUMBER of identity groups per template — the N most-recently-active are kept, older ones pruned wholesale (bounds retired branches). Groups with no identity var are unaffected (there is only one).

policy.Protect (and any this-run tags a caller injects into it) is an explicit, unconditional keep that overrides all of the above. A policy that keeps everything (0 / -1 / unset on every rule) is a graceful no-op.

templates uses the same syntax as branches/git_tags in the config; a "!"-prefixed template excludes from candidacy but never forms a group.

type Store

type Store interface {
	List(ctx context.Context) ([]Item, error)
	Delete(ctx context.Context, name string) error
}

Store abstracts listing and deleting items so the same engine works for registry tags, forge releases, or any other prunable resource.

Jump to

Keyboard shortcuts

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