blob: b4c29112651a27c52da9040810939bd12a9fcbb3 [file] [log] [blame]
#!/usr/bin/env bash
# ======================================================================
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -----------------------------------------------------------------------------
# getversion — determine the project version for packaging and diagnostics
# -----------------------------------------------------------------------------
#
# This script computes a version string using the following logic:
#
# 1. Extract the base PACKAGE_VERSION from the `configure` script.
#
# 2. If running inside a Git repository and `git describe` is usable:
#
# a. If the current commit matches an annotated tag exactly:
# VERSION = <tag>
# e.g., VERSION = 2.0.0+RC1
#
# b. If the current commit is ahead of a tag:
# VERSION = <PACKAGE_VERSION>+dev.<N>.g<commit>
# e.g., VERSION = 2.0.1-devel+dev.3.gabcd123
#
# 3. If *not* in a Git repo but a `VERSION` file exists:
#
# a. If the file contains a line like "<version> build <build_number>", both values are extracted.
#
# b. Otherwise, the VERSION is read from the file and the BUILDNUMBER is taken from BUILD_NUMBER if it exists.
#
# (This is the case for Apache Cloudberry packaging builds, where these files are created by the
# release script and may also be leveraged by downstream users.)
#
# 4. If neither a Git repo nor a VERSION file is present:
# VERSION = <PACKAGE_VERSION> from configure
# BUILDNUMBER = dev
#
# 5. If a BUILD_NUMBER file is present and BUILDNUMBER is "dev", it will override the default:
# BUILDNUMBER = $(cat BUILD_NUMBER)
#
# Output:
# - Default: <version> build <build_number>
# - With --short: just <version>
#
# Examples:
# ./getversion
# → 2.0.1-devel+dev.3.gabcd123 build dev
#
# ./getversion --short
# → 2.0.1-devel+dev.3.gabcd123
#
# (On exact tag)
# → 2.0.0+RC1 build dev
#
# Supported Features:
# - Handles annotated tags with special characters like `+` or `-`
# - Produces semver-compatible version strings for CI/CD
# - Works with or without Git
#
# Intended for use in:
# - Release packaging
# - Diagnostic reporting
# - Embedding traceable version info into builds
#
# ======================================================================
# Make sure we're running from the root git repository
pushd "$(dirname "$0")" > /dev/null
# Extract PACKAGE_VERSION from the configure script
VERSION=$(perl -ne 'print $1 if /^PACKAGE_VERSION='\''(.+)'\''$/' < configure)
BUILDNUMBER=dev
# Function to generate a dev suffix like "dev.1.gabcd123"
generate_dev_version() {
local latest_tag
latest_tag=$(git describe --tags --abbrev=0)
local full_desc
full_desc=$(git describe --tags --long)
local suffix="${full_desc#$latest_tag-}"
echo "dev.${suffix//-/.}"
}
# Check if we're in a Git repo and git is available
if type git >/dev/null 2>&1 && [ -e '.git' ]; then
# Ensure git describe doesn't fail due to shallow clone
if git describe --tags --long >/dev/null 2>&1; then
if git describe --exact-match >/dev/null 2>&1; then
# We're exactly on a tag
VERSION=$(git describe --exact-match)
else
# Not on a tag: add dev version suffix
VERSION+="+$(generate_dev_version)"
fi
fi
# Not a git repo but VERSION file exists
elif [[ -s ./VERSION ]]; then
# Support both legacy "<version> build <build_number>" and newer single-version formats
if grep -q ' build ' ./VERSION; then
VERSION=$(awk -F' build ' '{print $1}' ./VERSION)
BUILDNUMBER=$(awk -F' build ' '{print $2}' ./VERSION)
else
VERSION=$(<./VERSION)
if [[ -f ./BUILD_NUMBER ]]; then
BUILDNUMBER=$(<./BUILD_NUMBER)
fi
fi
fi
# Handle optional flag
FLAG="${1:-noflag}"
if [ "$FLAG" = "--short" ]; then
echo "${VERSION}"
else
if [[ ${BUILDNUMBER} = "dev" && -f BUILD_NUMBER ]]; then
BUILDNUMBER=$(<BUILD_NUMBER)
fi
echo "${VERSION} build ${BUILDNUMBER}"
fi
popd > /dev/null