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 ¶
- Variables
- func ApplyPolicies(candidates []Item, policy config.RetentionPolicy) []bool
- func ApplyTimeBucket(candidates []Item, keepSet []bool, count int, bucket BucketFn)
- func TemplateToPattern(tmpl string) string
- func TemplatesToPatterns(templates []string) []string
- func TruncateToDay(t time.Time) time.Time
- func TruncateToMonth(t time.Time) time.Time
- func TruncateToWeek(t time.Time) time.Time
- func TruncateToYear(t time.Time) time.Time
- type BucketFn
- type Item
- type Result
- type Store
Constants ¶
This section is empty.
Variables ¶
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 ¶
ApplyTimeBucket keeps the newest item in each of the last N distinct time buckets. candidates must be sorted newest-first.
func TemplateToPattern ¶
TemplateToPattern converts a single tag template to a regex pattern.
func TemplatesToPatterns ¶
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 ¶
TruncateToDay truncates a time to the start of its day.
func TruncateToMonth ¶
TruncateToMonth truncates a time to the first day of its month.
func TruncateToWeek ¶
TruncateToWeek truncates a time to the start of its ISO week (Monday).
Types ¶
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.