Skip to content

Repository files navigation

Go Reference CircleCI

gitsemver

Library and CLI tool for computing a semVer-compatible version from a git reference.

Version format

Situation Returned version
HEAD carries stable tag vX.Y.Z X.Y.Z
HEAD carries pre-release tag vX.Y.Z-rc.N X.Y.Z-rc.N
HEAD is untagged, stable ancestor vX.Y.Z reachable X.Y.(Z+1)-dev.<branch>.<YYYY-MM-DD>.<HH-MM-SS>.h<commit-sha>
HEAD is untagged, no stable ancestor reachable 0.0.0-dev.<branch>.<YYYY-MM-DD>.<HH-MM-SS>.h<commit-sha>

For untagged commits the base is the most recent stable ancestor tag reachable from the ref (RC and other pre-release tags are skipped). When no stable ancestor exists the version prefix is 0.0.0 with no patch increment. The trailing .h<commit-sha> is the 7-char git short hash of the resolved commit, for tag-to-commit traceability.

Length limit

Dev build versions are often used as Kubernetes attributes, so they are kept DNS/label-compatible (lowercased, [a-z0-9-] only) and bounded to a maximum length (default 63, configurable via GS_MAX_VERSION_LENGTH). Only the branch part is ever shortened to fit: when it would overflow, its middle is dropped and replaced with a -- marker, keeping the head and the more distinctive tail (e.g. renovate-up--s-to-latest). The version base, timestamp and commit hash are always kept intact, so the per-branch chronological sort order is never affected.

$ GS_BRANCH_NAME=renovate/update-all-dependencies-to-latest gitsemver get
1.2.4-dev.renovate-up--s-to-latest.2026-01-27.09-49-59.h1a2b3c4

Environment variables

Variable Effect
GS_BRANCH_NAME Override the branch name embedded in dev build versions. Defaults to the HEAD branch of the repo, then "unknown".
GS_GIT_TAG_PREFIX Monorepo support: only consider tags prefixed with "<value>/", e.g. module-a/v1.2.3.
GS_MAX_VERSION_LENGTH Maximum length of a generated dev build version. Defaults to 63. Only the branch part is shortened to fit.

CLI — gitsemver

go install github.com/giantswarm/gitsemver@latest
Usage:
  gitsemver get [--dir <path>] [--ref <ref>]
  gitsemver next <patch|minor|major|patch-rc|minor-rc|major-rc|rc|rc-release> [--last-tag <tag>]
  gitsemver validate [--type dev|rc|stable|any] <version>
  gitsemver completion <bash|zsh|fish|powershell>

get

Print the version for a git ref:

  --dir string   path inside the git repository (default ".", resolved to repo root)
  --ref string   git ref to resolve: branch name, tag, or commit SHA (default "HEAD")
$ GS_BRANCH_NAME=my-feature gitsemver get
1.2.4-dev.my-feature.2026-01-27.09-49-59.h1a2b3c4

$ gitsemver get --ref v1.2.3
1.2.3

next

Compute the next semver release tag after the highest-semver tag reachable from HEAD:

$ gitsemver next patch          # v1.2.3 ancestor → prints 1.2.4
$ gitsemver next minor-rc       # v1.2.3 ancestor → prints 1.3.0-rc.1
$ gitsemver next rc             # v1.3.0-rc.1 ancestor → prints 1.3.0-rc.2
$ gitsemver next rc-release     # v1.3.0-rc.1 ancestor → prints 1.3.0

Use --last-tag to supply the base explicitly — no git repository needed:

$ gitsemver next patch --last-tag v1.2.3
1.2.4

Valid bump types:

Base tag Bump type Result
Stable X.Y.Z patch X.Y.Z+1
Stable X.Y.Z minor X.Y+1.0
Stable X.Y.Z major X+1.0.0
Stable X.Y.Z patch-rc X.Y.Z+1-rc.1
Stable X.Y.Z minor-rc X.Y+1.0-rc.1
Stable X.Y.Z major-rc X+1.0.0-rc.1
RC X.Y.Z-rc.N rc X.Y.Z-rc.N+1
RC X.Y.Z-rc.N rc-release X.Y.Z

When no version tag is reachable from HEAD, 0.0.0 is used as the base. Note: rc and rc-release require an actual reachable RC tag and cannot be used from the implicit 0.0.0 base — start a new RC series with patch-rc, minor-rc, or major-rc instead.

Shell completion

Generate and load a completion script for your shell:

# bash — add to ~/.bashrc
source <(gitsemver completion bash)

# zsh — add to ~/.zshrc (requires compinit to be loaded)
source <(gitsemver completion zsh)

# fish
gitsemver completion fish | source

# PowerShell — add to $PROFILE
gitsemver completion powershell | Out-String | Invoke-Expression

Once loaded, gitsemver next <TAB> completes bump types and gitsemver validate --type <TAB> completes version types.

Go library

c := gitsemver.Config{
    Dir: "/path/to/some-repo",
    URL: "git@github.com:giantswarm/some-repo.git",
}
repo, err := gitsemver.New(c)
version, err := repo.ResolveVersion(ctx, "HEAD")
// e.g. "1.2.4-dev.my-feature.2026-01-27.09-49-59.h1a2b3c4"

About

Library to compute a project version given a git reference

Resources

Security policy

Stars

1 star

Watchers

6 watching

Forks

Releases

Used by

Contributors

Languages