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

retention

package
v0.9.2 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 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 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 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