ZIMBRA 10 FOSS

Zimbra Single Package Build Script

October 27, 2025
0 views
DOCUMENTATION
#!/bin/bash
#
# Zimbra Single Package Build Script
# Build individual Zimbra components instead of the entire suite
#

set -e  # Exit on error

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Configuration
ZIMBRA_VERSION="10.1.0"
BUILD_TYPE="FOSS"
BUILD_RELEASE="LIBERTY"
BUILD_RELEASE_CANDIDATE="GA"
THIRDPARTY_SERVER="files.zimbra.com"

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"

# Function to print status messages
print_status() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Function to display usage
usage() {
    echo -e "${BLUE}Usage:${NC} $0 <package-name> [options]"
    echo ""
    echo "Build a single Zimbra package instead of the entire suite."
    echo ""
    echo -e "${BLUE}Examples:${NC}"
    echo "  $0 zm-mta                    # Build zm-mta package"
    echo "  $0 zm-mailbox                # Build zm-mailbox"
    echo "  $0 zm-web-client             # Build web client"
    echo "  $0 zm-admin-console          # Build admin console"
    echo ""
    echo -e "${BLUE}Options:${NC}"
    echo "  --clean         Clean before building (removes build cache)"
    echo "  --with-deps     Build dependencies first"
    echo "  --list          List all available packages"
    echo "  --help          Show this help message"
    echo ""
    echo -e "${BLUE}Available Packages:${NC}"
    list_packages
}

# Function to list available packages
list_packages() {
    if [ -f "$SCRIPT_DIR/instructions/FOSS_staging_list.pl" ]; then
        print_status "Main packages:"
        echo ""
        grep -E '^\s*name\s*=>' "$SCRIPT_DIR/instructions/FOSS_staging_list.pl" | \
            sed 's/.*name\s*=>\s*"\([^"]*\)".*/  - \1/' | sort | uniq
    else
        print_warning "Cannot find package list"
        echo "  Common packages:"
        echo "  - zm-mailbox"
        echo "  - zm-mta"
        echo "  - zm-web-client"
        echo "  - zm-admin-console"
        echo "  - zm-nginx-conf"
        echo "  - zm-postfix"
        echo "  - zm-amavis"
        echo "  - zm-ldap-utilities"
        echo "  - zm-core-utils"
    fi
}

# Parse arguments
PACKAGE_NAME=""
CLEAN_BUILD=false
WITH_DEPS=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --help|-h)
            usage
            exit 0
            ;;
        --list|-l)
            list_packages
            exit 0
            ;;
        --clean)
            CLEAN_BUILD=true
            shift
            ;;
        --with-deps)
            WITH_DEPS=true
            shift
            ;;
        *)
            if [ -z "$PACKAGE_NAME" ]; then
                PACKAGE_NAME="$1"
            else
                print_error "Unknown option: $1"
                usage
                exit 1
            fi
            shift
            ;;
    esac
done

# Check if package name is provided
if [ -z "$PACKAGE_NAME" ]; then
    print_error "Package name is required"
    echo ""
    usage
    exit 1
fi

echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}  Zimbra Single Package Build${NC}"
echo -e "${BLUE}  Package: ${PACKAGE_NAME}${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""

# Check if package directory exists
PACKAGE_DIR="$PROJECT_ROOT/$PACKAGE_NAME"
if [ ! -d "$PACKAGE_DIR" ]; then
    print_error "Package directory not found: $PACKAGE_DIR"
    print_status "Available packages in $PROJECT_ROOT:"
    ls -d "$PROJECT_ROOT"/zm-* 2>/dev/null | xargs -n 1 basename || true
    exit 1
fi

# Check for build file
BUILD_FILE=""
if [ -f "$PACKAGE_DIR/build.xml" ]; then
    BUILD_FILE="build.xml"
    BUILD_TOOL="ant"
elif [ -f "$PACKAGE_DIR/pom.xml" ]; then
    BUILD_FILE="pom.xml"
    BUILD_TOOL="mvn"
elif [ -f "$PACKAGE_DIR/Makefile" ]; then
    BUILD_FILE="Makefile"
    BUILD_TOOL="make"
else
    print_warning "No standard build file found in $PACKAGE_DIR"
    print_status "Trying to build with build.pl..."
    BUILD_TOOL="build.pl"
fi

print_status "Found package: $PACKAGE_NAME"
print_status "Build tool: $BUILD_TOOL"
echo ""

# Check Java version
if command -v java &> /dev/null; then
    CURRENT_JAVA=$(java -version 2>&1 | head -n 1)
    if [[ "$CURRENT_JAVA" =~ "1.8" ]]; then
        print_success "Java 8 is configured"
    else
        print_warning "Java 8 recommended, current: $CURRENT_JAVA"
    fi
fi

# Change to package directory
cd "$PACKAGE_DIR"

# Build based on tool
if [ "$BUILD_TOOL" = "ant" ]; then
    print_status "Building with Ant..."
    echo ""

    # Clean if requested
    if [ "$CLEAN_BUILD" = true ]; then
        print_status "Cleaning package..."
        ant clean || print_warning "Clean failed, continuing..."
    fi

    # Build
    print_status "Compiling package..."
    ant -Dzimbra.buildinfo.version=10.1.0_GA_1001 \
        -Dzimbra.buildinfo.platform=UBUNTU24_64 \
        -Dzimbra.buildinfo.type=FOSS \
        -DskipTests=true \
        compile publish-local

    BUILD_EXIT=$?

elif [ "$BUILD_TOOL" = "mvn" ]; then
    print_status "Building with Maven..."
    echo ""

    if [ "$CLEAN_BUILD" = true ]; then
        print_status "Cleaning package..."
        mvn clean
    fi

    print_status "Compiling package..."
    mvn install -DskipTests=true

    BUILD_EXIT=$?

elif [ "$BUILD_TOOL" = "make" ]; then
    print_status "Building with Make..."
    echo ""

    if [ "$CLEAN_BUILD" = true ]; then
        print_status "Cleaning package..."
        make clean || print_warning "Clean failed, continuing..."
    fi

    print_status "Compiling package..."
    make

    BUILD_EXIT=$?

else
    # Use build.pl for this specific package
    print_status "Building with build.pl..."
    echo ""

    cd "$SCRIPT_DIR"

    ENV_BUILD_INCLUDE="$PACKAGE_NAME" ./build.pl \
        --ant-options -DskipTests=true \
        --git-default-tag=${ZIMBRA_VERSION} \
        --build-release-no=${ZIMBRA_VERSION} \
        --build-type=${BUILD_TYPE} \
        --build-release=${BUILD_RELEASE} \
        --build-release-candidate=${BUILD_RELEASE_CANDIDATE} \
        --build-thirdparty-server=${THIRDPARTY_SERVER} \
        --no-interactive

    BUILD_EXIT=$?
fi

echo ""
if [ $BUILD_EXIT -eq 0 ]; then
    print_success "Package built successfully: $PACKAGE_NAME"
    echo ""

    # Show build artifacts
    print_status "Build artifacts:"
    if [ -d "$PACKAGE_DIR/build" ]; then
        find "$PACKAGE_DIR/build" -type f \( -name "*.jar" -o -name "*.war" -o -name "*.zip" \) 2>/dev/null | while read file; do
            SIZE=$(du -h "$file" | cut -f1)
            echo "  📦 $(basename "$file") ($SIZE)"
        done
    fi

    if [ -d "$PACKAGE_DIR/target" ]; then
        find "$PACKAGE_DIR/target" -type f \( -name "*.jar" -o -name "*.war" \) 2>/dev/null | while read file; do
            SIZE=$(du -h "$file" | cut -f1)
            echo "  📦 $(basename "$file") ($SIZE)"
        done
    fi

    # Show installation location if exists
    if [ -d "$HOME/.zcs-deps/zimbra/$PACKAGE_NAME" ]; then
        echo ""
        print_status "Published to local repository:"
        echo "  📁 $HOME/.zcs-deps/zimbra/$PACKAGE_NAME/"
    fi

else
    print_error "Build failed for package: $PACKAGE_NAME"
    exit $BUILD_EXIT
fi

echo ""
print_status "To deploy this package to a running Zimbra instance:"
echo "  cd $PACKAGE_DIR"
echo "  ant deploy    # (for Ant-based packages)"
echo ""

echo -e "${BLUE}========================================${NC}"