blob: 61a29e50fc9a97b045f2bb1f07d4e84b711e388e [file]
#!/bin/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.
#
# Script Name: build-deb.sh
#
# Description:
# This script automates the process of building an DEB package using a specified
# version number. It ensures that the necessary tools are installed
# and that the control file exists before attempting to build the DEB. The script
# also includes error handling to provide meaningful feedback in case of failure.
#
# Usage:
# ./build-deb.sh [-v <version>] [-h] [--dry-run]
#
# Options:
# -v, --version <version> : Specify the version (required)
# -h, --help : Display this help and exit
# -n, --dry-run : Show what would be done, without making any changes
#
# Example:
# ./build-deb.sh -v 1.5.5 # Build with version 1.5.5
#
# Prerequisites:
# - The dpkg-buildpackage package must be installed (provides the dpkg-buildpackage command).
# - The control file must exist at debian/control.
#
# Error Handling:
# The script includes checks to ensure:
# - The version option (-v or --version) is provided.
# - The necessary commands are available.
# - The control file exists at the specified location.
# If any of these checks fail, the script exits with an appropriate error message.
# Enable strict mode for better error handling
set -euo pipefail
# Default values
VERSION=""
RELEASE="1"
DEBUG_BUILD=false
# Function to display usage information
usage() {
echo "Usage: $0 [-v <version>] [-h] [--dry-run]"
echo " -v, --version <version> : Specify the version (optional)"
echo " -h, --help : Display this help and exit"
echo " -n, --dry-run : Show what would be done, without making any changes"
exit 1
}
# Function to check if required commands are available
check_commands() {
local cmds=("dpkg-buildpackage")
for cmd in "${cmds[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
echo "Error: Required command '$cmd' not found. Please install it before running the script."
exit 1
fi
done
}
function print_changelog() {
cat <<EOF
apache-cloudberry-db-incubating (${CBDB_PKG_VERSION}) stable; urgency=low
* apache-cloudberry-db autobuild
-- ${BUILD_USER} <${BUILD_USER}@$(hostname)> $(date +'%a, %d %b %Y %H:%M:%S %z')
EOF
}
# Parse options
while [[ "$#" -gt 0 ]]; do
case $1 in
-v|--version)
VERSION="$2"
shift 2
;;
-h|--help)
usage
;;
-n|--dry-run)
DRY_RUN=true
shift
;;
*)
echo "Unknown option: ($1)"
shift
;;
esac
done
export CBDB_FULL_VERSION=$VERSION
# Set version if not provided
if [ -z "${VERSION}" ]; then
export CBDB_FULL_VERSION=$(./getversion 2>/dev/null | cut -d'-' -f 1 | cut -d'+' -f 1 || echo "unknown")
fi
if [[ ! $CBDB_FULL_VERSION =~ ^[0-9] ]]; then
export CBDB_FULL_VERSION="0.$CBDB_FULL_VERSION"
fi
if [ -z ${BUILD_NUMBER+x} ]; then
export BUILD_NUMBER=1
fi
if [ -z ${BUILD_USER+x} ]; then
export BUILD_USER=github
fi
# Detect OS distribution (e.g., ubuntu22.04, debian12)
if [ -z ${OS_DISTRO+x} ]; then
if [ -f /etc/os-release ]; then
# Temporarily disable unbound variable check for sourcing os-release
set +u
. /etc/os-release
set -u
# Ensure ID and VERSION_ID are set before using them
OS_DISTRO=$(echo "${ID:-unknown}${VERSION_ID:-}" | tr '[:upper:]' '[:lower:]')
else
OS_DISTRO="unknown"
fi
fi
# Ensure OS_DISTRO is exported and not empty
export OS_DISTRO=${OS_DISTRO:-unknown}
export CBDB_PKG_VERSION=${CBDB_FULL_VERSION}-${BUILD_NUMBER}-${OS_DISTRO}
# Check if required commands are available
check_commands
# Find project root (assumed to be four levels up from scripts directory: devops/build/packaging/deb/)
PROJECT_ROOT="$(cd "$(dirname "$0")/../../../../" && pwd)"
# Define where the debian metadata is located
DEBIAN_SRC_DIR="$(dirname "$0")/${OS_DISTRO}"
# Prepare the debian directory at the project root (required by dpkg-buildpackage)
if [ -d "$DEBIAN_SRC_DIR" ]; then
echo "Preparing debian directory from $DEBIAN_SRC_DIR..."
mkdir -p "$PROJECT_ROOT/debian"
# Use /. to copy directory contents if target exists instead of nested directories
cp -rf "$DEBIAN_SRC_DIR"/. "$PROJECT_ROOT/debian/"
else
if [ ! -d "$PROJECT_ROOT/debian" ]; then
echo "Error: Debian metadata not found at $DEBIAN_SRC_DIR and no debian/ directory exists at root."
exit 1
fi
fi
# Define the control file path (at the project root)
CONTROL_FILE="$PROJECT_ROOT/debian/control"
# Check if the control file exists
if [ ! -f "$CONTROL_FILE" ]; then
echo "Error: Control file not found at $CONTROL_FILE."
exit 1
fi
# Build the rpmbuild command based on options
DEBBUILD_CMD="dpkg-buildpackage -us -uc"
# Dry-run mode
if [ "${DRY_RUN:-false}" = true ]; then
echo "Dry-run mode: This is what would be done:"
print_changelog
echo ""
echo "$DEBBUILD_CMD"
exit 0
fi
# Run debbuild from the project root
echo "Building DEB with Version $CBDB_FULL_VERSION in $PROJECT_ROOT ..."
print_changelog > "$PROJECT_ROOT/debian/changelog"
# Only cd if we are not already at the project root
if [ "$(pwd)" != "$PROJECT_ROOT" ]; then
cd "$PROJECT_ROOT"
fi
if ! eval "$DEBBUILD_CMD"; then
echo "Error: deb build failed."
exit 1
fi
# Print completion message
echo "DEB build completed successfully with package $CBDB_PKG_VERSION"