gitver

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2026 License: AGPL-3.0, AGPL-3.0-only Imports: 15 Imported by: 0

Documentation

Overview

Package gitver provides git-based version detection and tag template resolution. It is the shared foundation used by both the docker build pipeline and the release management system.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractDockerTagNames

func ExtractDockerTagNames(values []string) []string

ExtractDockerTagNames scans strings for {docker.tag.TAGNAME.FIELD} patterns and returns deduplicated tag names. Uses the same suffix-anchored parsing as resolveTagTemplates.

func FetchTagInfo

func FetchTagInfo(client *http.Client, namespace, repo string, tags []string) map[string]TagInfo

FetchTagInfo retrieves metadata for specific tags from Docker Hub. Best-effort: tags that 404 or error are silently skipped.

func ResolveDockerTemplates

func ResolveDockerTemplates(s string, info *DockerHubInfo) string

ResolveDockerTemplates replaces {docker.*} templates with values from Docker Hub. Returns s unchanged if info is nil or no {docker.} templates are present.

func ResolveTags

func ResolveTags(templates []string, v *VersionInfo) []string

ResolveTags expands tag templates against version info.

func ResolveTemplate

func ResolveTemplate(tmpl string, v *VersionInfo) string

func ResolveTemplateWithDir

func ResolveTemplateWithDir(tmpl string, v *VersionInfo, rootDir string) string

ResolveTemplateWithDir expands template variables with scoped version support. rootDir is needed to resolve scoped versions via git; pass "" to skip scoped resolution.

func ResolveTemplateWithDirAndVars

func ResolveTemplateWithDirAndVars(tmpl string, v *VersionInfo, rootDir string, vars map[string]string) string

ResolveTemplateWithDirAndVars expands template variables with scoped version support and user-defined {var:name} variables from config.

func ResolveVars

func ResolveVars(s string, vars map[string]string) string

ResolveTemplate expands template variables in a single string against version info and environment. Works on any part of an image reference — registry URL, path, tag, or a fully composed image name.

Supported templates:

Simple variables:
  {version}          → "1.2.3" or "1.2.3-alpha.1" (full version)
  {base}             → "1.2.3" (semver base, no prerelease)
  {major}            → "1"
  {minor}            → "2"
  {patch}            → "3"
  {prerelease}       → "alpha.1" or "" (empty for stable)
  {branch}           → "main", "develop"

Width-controlled variables — {name:N} truncates or pads to N:
  {sha}              → "abc1234" (default 7)
  {sha:12}           → "abc1234def01" (first 12 chars)
  {sha:4}            → "abc1" (first 4 chars)

Counters — resolved by the channel/tag manager at bump time:
  {n}                → "42" (decimal counter, no padding)
  {n:5}              → "00042" (zero-padded to 5 digits)
  {hex:4}            → "002a" (sequential hex counter, padded to 4 chars)
  {hex:8}            → "0000002a" (same counter, wider pad)

Random generators — fresh value each resolution:
  {rand:6}           → "084721" (random digits, exactly N chars)
  {rand:4}           → "3819"
  {randhex:8}        → "a3f7c012" (random hex, exactly N chars)
  {randhex:4}        → "b7e2"

Environment variables:
  {env:VAR_NAME}     → value of environment variable

Scoped version variables — {field:SCOPE} resolves from SCOPE-v* tags:
  {version:component}  → "1.0.3" (from component-v1.0.3 tag)
  {base:component}     → "1.0.3"
  {major:component}    → "1"
  {minor:component}    → "0"
  {patch:component}    → "3"
  {prerelease:component} → "" or "beta.1"

Time variables:
  {date}               → "2026-02-24" (ISO date, UTC)
  {date:FORMAT}        → custom Go time layout (e.g. {date:20060102}, {date:Jan 2, 2006})
  {datetime}           → "2026-02-24T15:04:05Z" (RFC3339)
  {timestamp}          → "1740412800" (unix epoch)
  {commit.date}        → "2026-02-24" (HEAD commit author date, UTC)

CI context variables (portable across GitLab/GitHub/Jenkins/Bitbucket):
  {ci.pipeline}        → pipeline/run ID
  {ci.runner}          → runner/agent name
  {ci.job}             → job name
  {ci.url}             → link to pipeline/run

Project metadata (auto-detected from git/filesystem):
  {project.name}       → repo name from git remote origin
  {project.url}        → repo URL (SSH remotes converted to HTTPS)
  {project.license}    → SPDX identifier from LICENSE file
  {project.language}   → auto-detected from lockfiles (go, rust, node, etc.)
  {project.description} → from SetProjectDescription (config-sourced)

Literals pass through as-is:
  "latest"           → "latest"

Templates compose freely in any position:

"{env:REGISTRY}/myorg/myapp:{version}"
"version-{base}.{env:BUILD_NUM}"
"{branch}-{sha:10}"
"dev-{n:5}"
"build-{randhex:8}"
"nightly-{hex:4}"

ResolveVars expands {var:name} templates from the vars map. Supports recursive resolution (a var value can reference other vars) with cycle detection to prevent infinite loops.

func ResolveVarsShields

func ResolveVarsShields(s string, vars map[string]string) string

ResolveVarsShields resolves {var:*} templates with shields.io escaping. Hyphens and underscores in resolved values are doubled (- -> --, _ -> __) for shields.io static badge path escaping.

func SetProjectDescription

func SetProjectDescription(desc string)

SetProjectDescription sets the project description for {project.description} template resolution. Call this before ResolveTemplateWithDir to inject config-sourced descriptions.

Types

type BranchRule added in v0.6.0

type BranchRule struct {
	ID          string         // entry id for errors and diagnostics
	IsDefault   bool           // true when this is the catch-all fallback rule
	Match       *regexp.Regexp // nil when IsDefault; compiled at opts-build time
	BaseFromIDs []string       // ordered fallback chain; required (len >= 1)
	Format      string         // version template: {base} {sha} {branch}
}

BranchRule selects a version for a matched branch.

A rule walks its BaseFromIDs search path; for each id it looks up the precompiled regex and scans tags in git's order. First match wins, then advance to next id if zero matches. See detectVersion for the full pipeline.

type DockerHubInfo

type DockerHubInfo struct {
	Pulls  int64              // total pull count
	Stars  int                // star count
	Size   int64              // compressed size of latest tag in bytes
	Latest string             // digest of latest tag (sha256:...)
	Tags   map[string]TagInfo // per-tag metadata
}

DockerHubInfo holds metadata fetched from the Docker Hub API.

func FetchDockerHubInfo

func FetchDockerHubInfo(namespace, repo string) (*DockerHubInfo, error)

FetchDockerHubInfo retrieves repository metadata from Docker Hub. namespace/repo format: "prplanit/stagefreight".

type ProjectMeta

type ProjectMeta struct {
	Name     string // repo name (last path component of git remote)
	URL      string // repo URL (git remote origin)
	License  string // SPDX identifier from LICENSE file
	Language string // auto-detected from lockfiles
}

ProjectMeta holds project-level metadata resolved from git and filesystem.

func DetectProject

func DetectProject(rootDir string) *ProjectMeta

DetectProject resolves project metadata from git remote, LICENSE file, and lockfiles.

type TagInfo

type TagInfo struct {
	Size        int64
	Digest      string
	LastUpdated time.Time
}

TagInfo holds metadata for a single Docker Hub tag.

type TagSource added in v0.6.0

type TagSource struct {
	ID      string // e.g. "stable", "prerelease"
	Pattern string // regex string — compiled once at detectVersion setup

	// StripPrefix, if non-empty, is removed from a matched tag before semver
	// parsing. Used for scope-prefixed tag lines like "component-v1.0.0",
	// where the pattern matches the full tag but semver parsing needs the
	// suffix. Optional — empty means no transform.
	StripPrefix string
}

TagSource is a named tag pattern: operators classify git tags into sources and branch rules reference those sources by id.

type VersionInfo

type VersionInfo struct {
	Version      string // full version: "1.2.3", "1.2.3-alpha.1", or branch_build format
	Base         string // semver base without prerelease: "1.2.3"
	Major        string
	Minor        string
	Patch        string
	Prerelease   string // "alpha.1", "beta.2", "rc.1", or "" for stable
	SHA          string
	Branch       string
	IsRelease    bool // true if HEAD is exactly at a tag
	IsPrerelease bool // true if tag has a prerelease suffix
}

VersionInfo holds resolved version metadata from git.

func DetectVersionWithOpts added in v0.6.0

func DetectVersionWithOpts(rootDir string, opts *VersioningOpts) (*VersionInfo, error)

DetectVersionWithOpts resolves version info for a repo using the given versioning configuration. opts must not be nil — callers are expected to build opts from config.Config via build.versioningOptsFromConfig.

INVARIANT — DO NOT VIOLATE (CRITICAL)

Versioning resolution is a SEARCH PATH, not a filter chain.

A branch defines an ORDERED list of tag_sources (base_from). This function walks that list and returns the FIRST matching tag.

There is NO:

  • global tag filtering
  • candidate set construction
  • ranking or prioritization
  • cached "eligible tags"

Any refactor that:

  • pre-filters tags
  • builds a global eligible set
  • caches "matching tags"
  • merges tag_sources to "simplify"

will BREAK determinism and reintroduce ambiguity.

If you think you need to do that, you are wrong. Fix the config, not the algorithm.

type VersioningOpts added in v0.6.0

type VersioningOpts struct {
	// TagSources is the ordered, declared list of named tag patterns.
	// Globally eligible for lineage candidates, but semantically flat:
	// priority lives on branch rules, not here.
	TagSources []TagSource

	// BranchRules is the ordered list of branch-specific rules. First match
	// wins in declaration order. The "default" id is the catch-all and
	// must appear last (validation enforces).
	BranchRules []BranchRule

	// NoLineageMode: "error" (default) or "explicit"
	NoLineageMode string

	// NoLineageVersion: template for explicit mode (must contain {sha} or {time})
	NoLineageVersion string
}

VersioningOpts provides versioning configuration to DetectVersionWithOpts. It is REQUIRED — nil is rejected with an error. The search-path model depends on declared intent (tag sources + branch rules); there is no legacy "just guess from git" path anymore.

Jump to

Keyboard shortcuts

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