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 ¶
- func ExtractDockerTagNames(values []string) []string
- func FetchTagInfo(client *http.Client, namespace, repo string, tags []string) map[string]TagInfo
- func ResolveDockerTemplates(s string, info *DockerHubInfo) string
- func ResolveTags(templates []string, v *VersionInfo) []string
- func ResolveTemplate(tmpl string, v *VersionInfo) string
- func ResolveTemplateWithDir(tmpl string, v *VersionInfo, rootDir string) string
- func ResolveTemplateWithDirAndVars(tmpl string, v *VersionInfo, rootDir string, vars map[string]string) string
- func ResolveVars(s string, vars map[string]string) string
- func ResolveVarsShields(s string, vars map[string]string) string
- func SetProjectDescription(desc string)
- type BranchRule
- type DockerHubInfo
- type ProjectMeta
- type TagInfo
- type TagSource
- type VersionInfo
- type VersioningOpts
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExtractDockerTagNames ¶
ExtractDockerTagNames scans strings for {docker.tag.TAGNAME.FIELD} patterns and returns deduplicated tag names. Uses the same suffix-anchored parsing as resolveTagTemplates.
func FetchTagInfo ¶
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 ¶
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 ¶
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 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.