#!/bin/bash # CHORUS Release Build System # Builds cross-platform binaries for distribution set -e # Colors and formatting RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' WHITE='\033[1;37m' NC='\033[0m' # No Color # Configuration CHORUS_ROOT="$HOME/chorus/project-queues/active" BZZZ_SOURCE="$CHORUS_ROOT/BZZZ" WHOOSH_SOURCE="$CHORUS_ROOT/WHOOSH" BUILD_DIR="$HOME/chorus/releases" VERSION="${VERSION:-$(date +%Y%m%d-%H%M%S)}" RELEASE_CHANNEL="${RELEASE_CHANNEL:-latest}" # Target platforms PLATFORMS=( "linux/amd64" "linux/arm64" "linux/arm" "darwin/amd64" "darwin/arm64" ) # Logging functions log_info() { echo -e "${GREEN}✓${NC} $1" } log_warn() { echo -e "${YELLOW}⚠${NC} $1" } log_error() { echo -e "${RED}✗${NC} $1" } log_step() { echo -e "${BLUE}▶${NC} $1" } print_banner() { echo -e "${PURPLE}" cat << 'EOF' ██████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗ ██╔════╝██║ ██║██╔═══██╗██╔══██╗██║ ██║██╔════╝ ██║ ███████║██║ ██║██████╔╝██║ ██║███████╗ ██║ ██╔══██║██║ ██║██╔══██╗██║ ██║╚════██║ ╚██████╗██║ ██║╚██████╔╝██║ ██║╚██████╔╝███████║ ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ 🏗️ Release Build System EOF echo -e "${NC}" echo -e "${CYAN} Building cross-platform binaries for distribution${NC}" echo "" } # Clean previous builds clean_build_dir() { log_step "Cleaning build directory..." rm -rf "$BUILD_DIR" mkdir -p "$BUILD_DIR"/{bzzz,whoosh}/"$RELEASE_CHANNEL" log_info "Build directory cleaned" } # Check prerequisites check_prerequisites() { log_step "Checking prerequisites..." # Check Go installation if ! command -v go >/dev/null 2>&1; then log_error "Go is not installed. Please install Go first." exit 1 fi # Check Docker for WHOOSH if ! command -v docker >/dev/null 2>&1; then log_warn "Docker not found - WHOOSH builds will be skipped" fi # Check source directories if [[ ! -d "$BZZZ_SOURCE" ]]; then log_error "BZZZ source not found at $BZZZ_SOURCE" exit 1 fi if [[ ! -d "$WHOOSH_SOURCE" ]]; then log_warn "WHOOSH source not found at $WHOOSH_SOURCE - skipping WHOOSH build" fi log_info "Prerequisites checked" } # Build BZZZ binaries build_bzzz() { log_step "Building BZZZ binaries..." cd "$BZZZ_SOURCE" # Fix import cycles first log_step "Attempting to fix import cycles..." if ! fix_import_cycles; then log_warn "Could not automatically fix import cycles" fi # Clean module cache go clean -modcache 2>/dev/null || true go mod tidy # Build for each platform for platform in "${PLATFORMS[@]}"; do local os="${platform%/*}" local arch="${platform#*/}" log_step "Building BZZZ for $os/$arch..." local output_name="bzzz-$os-$arch" if [[ "$os" == "windows" ]]; then output_name="$output_name.exe" fi local output_path="$BUILD_DIR/bzzz/$RELEASE_CHANNEL/$output_name" # Set build environment export GOOS="$os" export GOARCH="$arch" export CGO_ENABLED=0 # Build with minimal dependencies to avoid import cycles if go build -tags="minimal,release" -ldflags="-s -w -X main.version=$VERSION" -o "$output_path" . 2>/dev/null; then log_info "Built $output_name successfully" else log_warn "Failed to build $output_name - trying alternative approach" # Try building with main.go only if go build -tags="minimal" -ldflags="-s -w" -o "$output_path" main.go 2>/dev/null; then log_info "Built $output_name (minimal version)" else log_error "Failed to build $output_name" fi fi done # Reset environment unset GOOS GOARCH CGO_ENABLED log_info "BZZZ binaries build completed" } # Fix import cycles (basic attempt) fix_import_cycles() { log_step "Attempting to fix Go import cycles..." # Look for common import cycle patterns and try to fix them # This is a basic approach - may need manual intervention for complex cycles # Create a backup cp -r . "${BZZZ_SOURCE}.backup.$(date +%s)" 2>/dev/null || true # Try to build and capture errors local build_output if build_output=$(go build . 2>&1); then log_info "No import cycles detected" return 0 fi if echo "$build_output" | grep -q "import cycle"; then log_warn "Import cycles detected - manual intervention may be required" echo "$build_output" | grep "import cycle" | head -5 return 1 fi return 0 } # Copy service files copy_service_files() { log_step "Copying service files..." local bzzz_release_dir="$BUILD_DIR/bzzz/$RELEASE_CHANNEL" # Copy systemd service file if [[ -f "$BZZZ_SOURCE/bzzz.service" ]]; then cp "$BZZZ_SOURCE/bzzz.service" "$bzzz_release_dir/" log_info "Copied bzzz.service" else log_warn "bzzz.service not found in source" fi # Copy install script if [[ -f "$BZZZ_SOURCE/install-service.sh" ]]; then cp "$BZZZ_SOURCE/install-service.sh" "$bzzz_release_dir/" chmod +x "$bzzz_release_dir/install-service.sh" log_info "Copied install-service.sh" else log_warn "install-service.sh not found in source" fi log_info "Service files copied" } # Build WHOOSH package build_whoosh() { if [[ ! -d "$WHOOSH_SOURCE" ]]; then log_warn "WHOOSH source not found - skipping" return fi log_step "Building WHOOSH package..." cd "$WHOOSH_SOURCE" local whoosh_release_dir="$BUILD_DIR/whoosh/$RELEASE_CHANNEL" # Create docker-compose package if [[ -f "docker-compose.yml" ]] || [[ -f "docker-compose.swarm.yml" ]]; then log_step "Creating WHOOSH Docker Compose package..." # Create temporary directory for packaging local temp_dir=$(mktemp -d) # Copy relevant files cp -r . "$temp_dir/whoosh/" # Create tarball cd "$temp_dir" tar -czf "$whoosh_release_dir/whoosh-docker-compose.tar.gz" whoosh/ # Cleanup rm -rf "$temp_dir" log_info "WHOOSH package created" else log_warn "No Docker Compose files found for WHOOSH" fi } # Generate checksums generate_checksums() { log_step "Generating checksums..." cd "$BUILD_DIR" # Generate checksums for BZZZ binaries if [[ -d "bzzz/$RELEASE_CHANNEL" ]]; then cd "bzzz/$RELEASE_CHANNEL" sha256sum * > checksums.txt log_info "BZZZ checksums generated" cd "$BUILD_DIR" fi # Generate checksums for WHOOSH if [[ -d "whoosh/$RELEASE_CHANNEL" ]]; then cd "whoosh/$RELEASE_CHANNEL" sha256sum * > checksums.txt 2>/dev/null || true log_info "WHOOSH checksums generated" cd "$BUILD_DIR" fi log_info "Checksums generated" } # Create release info create_release_info() { log_step "Creating release information..." local release_info="$BUILD_DIR/release-info.json" cat > "$release_info" << EOF { "version": "$VERSION", "channel": "$RELEASE_CHANNEL", "build_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", "platforms": [ $(printf ' "%s"' "${PLATFORMS[@]}" | paste -sd ',' -) ], "components": { "bzzz": { "description": "P2P Task Coordination System", "binaries": [ $(find "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" -name "bzzz-*" -type f | sed 's|.*/||' | sed 's/^/ "/' | sed 's/$/"/' | paste -sd ',' -) ] }, "whoosh": { "description": "Web Dashboard and Management Interface", "packages": [ $(find "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" -name "*.tar.gz" -type f 2>/dev/null | sed 's|.*/||' | sed 's/^/ "/' | sed 's/$/"/' | paste -sd ',' - || echo '') ] } } } EOF log_info "Release information created" } # Show build summary show_summary() { echo "" echo -e "${GREEN}🎉 Release Build Complete!${NC}" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo -e "${WHITE}Build Information:${NC}" echo " • Version: $VERSION" echo " • Channel: $RELEASE_CHANNEL" echo " • Build Directory: $BUILD_DIR" echo "" echo -e "${WHITE}Built Components:${NC}" # List BZZZ binaries local bzzz_count=$(find "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" -name "bzzz-*" -type f 2>/dev/null | wc -l) echo " • BZZZ binaries: $bzzz_count" # List WHOOSH packages local whoosh_count=$(find "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" -name "*.tar.gz" -type f 2>/dev/null | wc -l) echo " • WHOOSH packages: $whoosh_count" echo "" echo -e "${WHITE}Next Steps:${NC}" echo " 1. Test binaries: $BUILD_DIR/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64 --version" echo " 2. Upload to releases.chorus.services" echo " 3. Update installer URLs if needed" echo "" } # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in --version) VERSION="$2" shift 2 ;; --channel) RELEASE_CHANNEL="$2" shift 2 ;; --bzzz-only) BUILD_WHOOSH=false shift ;; --whoosh-only) BUILD_BZZZ=false shift ;; --help) echo "CHORUS Release Build System" echo "" echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --version VERSION Set release version (default: timestamp)" echo " --channel CHANNEL Set release channel (default: latest)" echo " --bzzz-only Build only BZZZ binaries" echo " --whoosh-only Build only WHOOSH packages" echo " --help Show this help" echo "" exit 0 ;; *) echo "Unknown option: $1" exit 1 ;; esac done # Default build flags BUILD_BZZZ=${BUILD_BZZZ:-true} BUILD_WHOOSH=${BUILD_WHOOSH:-true} # Main build process main() { print_banner echo -e "${WHITE}Starting CHORUS release build...${NC}" echo " Version: $VERSION" echo " Channel: $RELEASE_CHANNEL" echo "" check_prerequisites clean_build_dir if [[ "$BUILD_BZZZ" == "true" ]]; then build_bzzz copy_service_files fi if [[ "$BUILD_WHOOSH" == "true" ]]; then build_whoosh fi generate_checksums create_release_info show_summary } # Run main build process main "$@"