25.12. CI Debian Package Versions#

The Debian publishers on buildbot.gnunet.org derive their package versions from the highest eligible SemVer tag in the repository. The build still uses the commit scheduled by Buildbot; selecting a version tag does not change the source checkout.

This policy covers gnunet, exchange, merchant, donau, challenger, anastasis, sync, libeufin, taler-rust, depolymerization, taler-mailbox, taldir, and taler-typescript-core. All Debian packages produced by a repository use its shared version helper.

25.12.1. Tag selection#

Eligible tags have the form vX.Y.Z or vX.Y.Z-dev.K. Each numeric component is a nonnegative integer without leading zeroes, except for zero itself. Both annotated and lightweight tags are accepted. Optional SemVer build metadata, such as +build.001, is accepted but ignored in version comparisons and omitted from the generated versions.

Selection compares the numeric components according to SemVer precedence. For example, v1.2.3-dev.10 sorts after v1.2.3-dev.9, and v1.2.3 sorts after both. The highest eligible tag is selected across the whole repository, including tags whose commits are not ancestors of HEAD. Tag dates and proximity to HEAD do not determine the result.

When several tags have equal precedence, prefer the tag without build metadata. If there is still a tie, choose the lexicographically first tag name. Unsupported tags are reported and excluded. These include historical forms such as v0.9.4a, Debian-specific tags, and prereleases other than -dev.K. The generated snapshot forms below are reserved for CI output and are not eligible release tags. Version generation fails if no eligible tag exists.

25.12.2. Snapshot versions and ordering#

Let N be the result of git rev-list --count TAG..HEAD, where TAG is the selected tag. A build is an exact tagged release only when git rev-parse HEAD equals git rev-parse 'TAG^{commit}'. A count of zero alone does not establish an exact release: HEAD can be an ancestor of the tagged commit. Such a build still receives a snapshot suffix with N = 0.

Version mapping#

Selected tag and checkout

SemVer

Debian version

vX.Y.Z, exact commit

X.Y.Z

X.Y.Z

vX.Y.Z, different commit

X.Y.(Z+1)-0.N

X.Y.(Z+1)~0.N

vX.Y.Z-dev.K, exact commit

X.Y.Z-dev.K

X.Y.Z~devK

vX.Y.Z-dev.K, different commit

X.Y.Z-dev.K.N

X.Y.Z~devK.N

Z+1 means incrementing the patch component. For example, twelve commits beyond v1.6.43 produce SemVer 1.6.44-0.12 and Debian version 1.6.44~0.12. Twelve commits beyond v1.6.44-dev.9 produce 1.6.44-dev.9.12 and 1.6.44~dev9.12.

A snapshot sorts after its selected tag in both systems. A stable-tag snapshot sorts before the next patch’s dev.0 release; a development-tag snapshot sorts before the next development tag, with K incremented by one. For example, these sequences have matching order:

1.6.43 < 1.6.44-0.12 < 1.6.44-dev.0
1.6.43 < 1.6.44~0.12 < 1.6.44~dev0

1.6.44-dev.9 < 1.6.44-dev.9.12 < 1.6.44-dev.10 < 1.6.44
1.6.44~dev9  < 1.6.44~dev9.12  < 1.6.44~dev10  < 1.6.44

The mapping also preserves equality. Neither a commit hash nor build metadata is added to the Debian version to break a SemVer tie. Different commits can therefore receive the same version, for example when their counts relative to the selected tag are equal. Use the logged HEAD commit and the artifact path containing the CI commit reference to identify a particular build.

25.12.3. Buildbot checkout and packaging requirements#

The container factories in taler-deployment.git/buildbot/master.cfg retain full checkouts for these repositories. They use Git mode='full', method='fresh', shallow=False, and tags=True. The fresh checkout cleans build outputs while retaining Git history. The workspace preparation step replaces a previous shallow checkout once, then keeps the full checkout for subsequent builds.

Each repository provides contrib/ci/version.sh, backed by contrib/ci/debian-version.py. Existing job-local version.sh paths delegate to this entry point. Packaging containers must explicitly install Python 3, including architecture-specific Containerfiles and templates used to generate jobs.

The helper requires a full checkout and fetches all tags for the exact scheduled commit with:

git fetch --no-recurse-submodules --tags origin COMMIT

COMMIT is the full HEAD commit ID. Fetching by commit supports detached HEADs and avoids guessing a branch name. Do not introduce a fetch depth limit: incomplete history changes the commit count. A shallow checkout or a failed fetch causes version generation to fail.

Standard output contains only the Debian version. Standard error records the selected tag, HEAD commit, count, SemVer, and Debian version, as well as excluded tags and errors. Packaging jobs must stop on errors and reject empty output before changing the changelog or building packages. In a shell script with set -e, keep assignment separate from export:

VERSION="$(./contrib/ci/version.sh)"
export VERSION
: "${VERSION:?version generation returned an empty version}"

Using export VERSION="$(...)" can hide the helper’s failure status.

25.12.4. Maintaining and diagnosing the policy#

Keep contrib/ci/debian-version.py and contrib/ci/test_version.py identical across the affected repositories. Run the conformance suite in a Debian container with Git, Python 3, Bash, and dpkg installed:

python3 contrib/ci/test_version.py

The suite exercises tag selection, detached checkouts, tags on other branches, snapshot mapping, Debian ordering, compatibility entry points, and packaging callers’ error handling. The Debian ordering check is skipped when dpkg is unavailable. Changes to checkout caching should also run the Buildbot tests in taler-deployment.git/buildbot/test_container_steps.py.

When a package version looks unexpected, first inspect the helper’s selected-tag and HEAD diagnostics. Check the highest eligible tag across all branches, then compare the tagged commit to HEAD and inspect the TAG..HEAD count. For a shallow-checkout failure, check the builder’s cache policy and workspace migration. For a fetch failure, check access to origin and the scheduled commit. Fix the checkout or tag problem before retrying the package build.