From a9d7b67929d778ed13600a729234aa60a560575f Mon Sep 17 00:00:00 2001 From: Markus Hilger Date: Mon, 27 Jul 2026 19:45:14 +0200 Subject: [PATCH] Derive build versions from a tracked VERSION file Release tags do not live on master: 3.15.2 through 3.15.6 were tagged on branch 3.15, so git describe reaches only 3.15.1 and dev builds were stamped 3.15.2.dev. Besides being confusing, rpm and dpkg both rank the released 3.15.6 above that, so a dev package will not install over a released one. Add a top-level VERSION file naming the release the branch is working toward (4.0.0 on master) and a mkversion helper that stamps packages from it, keeping the tag-derived value as a floor so a forgotten bump cannot go backwards. mkversion also replaces the block copy-pasted into seven build scripts, and makesetup no longer writes a per-package VERSION file, so the stale checked-in confluent_common/VERSION goes with it. --- README.md | 21 +++++++++++++++ VERSION | 1 + confluent_common/VERSION | 1 - confluent_osdeploy/buildrpm | 10 +------- confluent_osdeploy/buildrpm-aarch64 | 10 +------- confluent_server/builddeb | 5 +--- confluent_server/buildrpm | 3 +-- confluent_server/makesetup | 14 +++------- confluent_vtbufferd/builddeb | 10 +------- confluent_vtbufferd/buildrpm | 10 +------- imgutil/builddeb | 11 ++------ imgutil/buildrpm | 10 +------- mkversion | 40 +++++++++++++++++++++++++++++ 13 files changed, 74 insertions(+), 72 deletions(-) create mode 100644 VERSION delete mode 100644 confluent_common/VERSION create mode 100755 mkversion diff --git a/README.md b/README.md index 2a994481..c08d94c7 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,24 @@ Confluent is made available under the Apache 2.0 license: https://opensource.org # Developers Want to help? Submit a [Pull Request](https://github.com/xcat2/confluent/pulls). + +## Versioning and releases + +The top-level `VERSION` file names the release the current branch is working toward. Build scripts +call `./mkversion`, which turns it into the version stamped on packages: the tag itself on a release +tag (`4.0.1`), otherwise a development version (`4.0.1.dev5+gdeadbee`, or `4.0.1~dev5+gdeadbee` for +the packages that have no `setup.py`). + +`mkversion` also derives a version from the newest tag reachable from HEAD and uses whichever is +higher, so forgetting to bump `VERSION` after tagging the current branch cannot walk the version +backwards. Staying ahead of tags on *other* branches is what `VERSION` itself is for: patch releases +are tagged on release branches, which master never sees. + +Cutting a new series: + +1. Land the release commit on master and tag `X.Y.0` there. +2. Create branch `X.Y` from that tag; it inherits `VERSION=X.Y.0`. +3. Only then bump `VERSION` on master. Doing it before step 2 leaves the release branch on the + wrong series. + +Patch releases land on branch `X.Y` and are tagged `X.Y.Z` there; no `VERSION` edit is needed. diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..fcdb2e10 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +4.0.0 diff --git a/confluent_common/VERSION b/confluent_common/VERSION deleted file mode 100644 index 7dea76ed..00000000 --- a/confluent_common/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0.1 diff --git a/confluent_osdeploy/buildrpm b/confluent_osdeploy/buildrpm index 7b5c075c..f2fb308a 100755 --- a/confluent_osdeploy/buildrpm +++ b/confluent_osdeploy/buildrpm @@ -1,13 +1,5 @@ cd $(dirname $0) -VERSION=`git describe|cut -d- -f 1` -NUMCOMMITS=`git describe|cut -d- -f 2` -if [ "$NUMCOMMITS" != "$VERSION" ]; then - LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev) - LASTNUM=$((LASTNUM+1)) - FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev) - VERSION=${FIRSTPART}.${LASTNUM} - VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3` -fi +VERSION=`../mkversion --tilde` || exit 1 sed -e "s/#VERSION#/$VERSION/" confluent_osdeploy.spec.tmpl > confluent_osdeploy.spec cd .. cp ../LICENSE . diff --git a/confluent_osdeploy/buildrpm-aarch64 b/confluent_osdeploy/buildrpm-aarch64 index c269284b..872bc8e1 100644 --- a/confluent_osdeploy/buildrpm-aarch64 +++ b/confluent_osdeploy/buildrpm-aarch64 @@ -1,13 +1,5 @@ cd $(dirname $0) -VERSION=`git describe|cut -d- -f 1` -NUMCOMMITS=`git describe|cut -d- -f 2` -if [ "$NUMCOMMITS" != "$VERSION" ]; then - LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev) - LASTNUM=$((LASTNUM+1)) - FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev) - VERSION=${FIRSTPART}.${LASTNUM} - VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3` -fi +VERSION=`../mkversion --tilde` || exit 1 sed -e "s/#VERSION#/$VERSION/" confluent_osdeploy-aarch64.spec.tmpl > confluent_osdeploy-aarch64.spec cd .. cp ../LICENSE . diff --git a/confluent_server/builddeb b/confluent_server/builddeb index 0364d9f0..644c61ef 100755 --- a/confluent_server/builddeb +++ b/confluent_server/builddeb @@ -19,10 +19,7 @@ cd /tmp/confluent/$PKGNAME if [ -x ./makeman ]; then ./makeman fi -sed -e 's/~/./' ./makesetup > ./makesetup.deb -chmod +x ./makesetup.deb -./makesetup.deb -VERSION=`cat VERSION` +VERSION=`./makesetup` || exit 1 cat > setup.cfg << EOF [install] install_purelib=/opt/confluent/lib/python diff --git a/confluent_server/buildrpm b/confluent_server/buildrpm index c4f347e8..4554e502 100755 --- a/confluent_server/buildrpm +++ b/confluent_server/buildrpm @@ -3,8 +3,7 @@ cd `dirname $0` if [ -x ./makeman ]; then ./makeman fi -./makesetup -VERSION=`cat VERSION` +VERSION=`./makesetup` || exit 1 PKGNAME=$(basename $(pwd)) python3 setup.py sdist > /dev/null 2>&1 cp dist/*.tar.gz ~/rpmbuild/SOURCES diff --git a/confluent_server/makesetup b/confluent_server/makesetup index 33b08654..25b85807 100755 --- a/confluent_server/makesetup +++ b/confluent_server/makesetup @@ -1,16 +1,8 @@ cd `dirname $0` -VERSION=`git describe|cut -d- -f 1` -NUMCOMMITS=`git describe|cut -d- -f 2` -if [ "$NUMCOMMITS" != "$VERSION" ]; then - LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev) - LASTNUM=$((LASTNUM+1)) - FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev) - VERSION=${FIRSTPART}.${LASTNUM} - VERSION=$VERSION.dev$NUMCOMMITS+`git describe|cut -d- -f 3` -fi -echo $VERSION > VERSION +VERSION=`../mkversion` || exit 1 sed -e "s/#VERSION#/$VERSION/" setup.py.tmpl > setup.py -if [ -f confluent/client.py ]; then +if [ -f confluent/client.py ]; then echo '__version__ = "'$VERSION'"' > confluent/__init__.py fi cp ../LICENSE . +echo $VERSION diff --git a/confluent_vtbufferd/builddeb b/confluent_vtbufferd/builddeb index c8ecf332..c4c60cce 100755 --- a/confluent_vtbufferd/builddeb +++ b/confluent_vtbufferd/builddeb @@ -6,15 +6,7 @@ PKGNAME=$(basename $(pwd)) DPKGNAME=$(basename $(pwd) | sed -e s/_/-/) OPKGNAME=$(basename $(pwd) | sed -e s/_/-/) DSCARGS="--with-python3=True --with-python2=False" -VERSION=`git describe|cut -d- -f 1` -NUMCOMMITS=`git describe|cut -d- -f 2` -if [ "$NUMCOMMITS" != "$VERSION" ]; then - LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev) - LASTNUM=$((LASTNUM+1)) - FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev) - VERSION=${FIRSTPART}.${LASTNUM} - VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3` -fi +VERSION=`../mkversion --tilde` || exit 1 cd .. rm -rf /tmp/confluent mkdir -p /tmp/confluent # $DPKGNAME diff --git a/confluent_vtbufferd/buildrpm b/confluent_vtbufferd/buildrpm index cc9e8a64..2f4b61bd 100755 --- a/confluent_vtbufferd/buildrpm +++ b/confluent_vtbufferd/buildrpm @@ -1,13 +1,5 @@ cd $(dirname $0) -VERSION=`git describe|cut -d- -f 1` -NUMCOMMITS=`git describe|cut -d- -f 2` -if [ "$NUMCOMMITS" != "$VERSION" ]; then - LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev) - LASTNUM=$((LASTNUM+1)) - FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev) - VERSION=${FIRSTPART}.${LASTNUM} - VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3` -fi +VERSION=`../mkversion --tilde` || exit 1 mkdir -p dist/confluent_vtbufferd-$VERSION cp ../LICENSE NOTICE *.c *.h Makefile dist/confluent_vtbufferd-$VERSION cd dist diff --git a/imgutil/builddeb b/imgutil/builddeb index 27b0902b..930b22ed 100755 --- a/imgutil/builddeb +++ b/imgutil/builddeb @@ -1,15 +1,8 @@ #!/bin/bash export DEBFULLNAME="Lenovo HPC" export DEBEMAIL="hpchelp@lenovo.com" -VERSION=`git describe|cut -d- -f 1` -NUMCOMMITS=`git describe|cut -d- -f 2` -if [ "$NUMCOMMITS" != "$VERSION" ]; then - LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev) - LASTNUM=$((LASTNUM+1)) - FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev) - VERSION=${FIRSTPART}.${LASTNUM} - VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3` -fi +cd "$(dirname "$0")" || exit 1 +VERSION=`../mkversion --tilde` || exit 1 mkdir -p /tmp/confluent-imgutil cp -a * /tmp/confluent-imgutil cp ../LICENSE /tmp/confluent-imgutil diff --git a/imgutil/buildrpm b/imgutil/buildrpm index b1cad8f2..400c7c15 100755 --- a/imgutil/buildrpm +++ b/imgutil/buildrpm @@ -1,14 +1,6 @@ #!/bin/bash cd $(dirname $0) -VERSION=`git describe|cut -d- -f 1` -NUMCOMMITS=`git describe|cut -d- -f 2` -if [ "$NUMCOMMITS" != "$VERSION" ]; then - LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev) - LASTNUM=$((LASTNUM+1)) - FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev) - VERSION=${FIRSTPART}.${LASTNUM} - VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3` -fi +VERSION=`../mkversion --tilde` || exit 1 sed -e "s/#VERSION#/$VERSION/" confluent_imgutil.spec.tmpl > confluent_imgutil.spec cp ../LICENSE . cd .. diff --git a/mkversion b/mkversion new file mode 100755 index 00000000..d6f85b63 --- /dev/null +++ b/mkversion @@ -0,0 +1,40 @@ +#!/bin/sh +# Print the version to stamp on packages built from this checkout. +# +# --tilde use "~dev" rather than ".dev" (packages with no setup.py; "~" sorts +# before the release, ".dev" after, but PEP 440 requires ".dev") +# +# The root VERSION file names the release this branch is working toward. Release +# tags do not always live on master (3.15.2 through 3.15.6 are on branch 3.15), so +# git describe alone stamps master builds with an already-released version. The +# newest tag reachable from HEAD is kept as a floor, so forgetting to bump VERSION +# after tagging *this* branch cannot walk the version backwards; staying ahead of +# tags on other branches is what the VERSION file itself is for. See README.md for +# the branch-cutting order. +cd "$(dirname "$0")" || exit 1 +sep=. +case "$1" in + --tilde) sep='~' ;; + '') ;; + *) echo "mkversion: unknown argument '$1'" >&2; exit 1 ;; +esac +next=$(tr -d '[:space:]' < VERSION 2>/dev/null) +case "$next" in + [0-9]*.[0-9]*.[0-9]*) ;; + *) echo "mkversion: VERSION must hold a release like 4.0.0, got '$next'" >&2; exit 1 ;; +esac +# plain describe: release tags are annotated, so lightweight ones (3.15.5-test) are +# already ignored. Never guess a version -- a silent fallback here would label a dev +# build as the release. +desc=$(git describe 2>/dev/null) || + { echo "mkversion: git describe failed, cannot version this build" >&2; exit 1; } +tag=${desc%%-*} +numcommits=$(echo "$desc" | cut -d- -f2) +if [ "$numcommits" = "$tag" ]; then # HEAD is exactly a tag: release build + echo "$tag" + exit 0 +fi +bumped=$(echo "$tag" | awk -F. -v OFS=. '{$NF=$NF+1; print}') +base=$(printf '%s\n%s\n' "$bumped" "$next" | sort -V | tail -1) && [ -n "$base" ] || + { echo "mkversion: sort -V failed" >&2; exit 1; } +echo "${base}${sep}dev${numcommits}+$(echo "$desc" | cut -d- -f3)"