#!/bin/bash # CHORUS Release Deployment Script # Deploys built binaries to the release distribution system set -e # Colors GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' BLUE='\033[0;34m' PURPLE='\033[0;35m' NC='\033[0m' 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"; } # Configuration BUILD_DIR="$HOME/chorus/releases" DEPLOYMENT_TARGET="${DEPLOYMENT_TARGET:-local}" RELEASE_CHANNEL="${RELEASE_CHANNEL:-latest}" # Deployment targets CHORUS_SERVICES_ROOT="/var/www/releases.chorus.services" LOCAL_SERVE_DIR="$HOME/chorus/local-releases" print_banner() { echo -e "${PURPLE}" cat << 'EOF' ██████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗ ██╔════╝██║ ██║██╔═══██╗██╔══██╗██║ ██║██╔════╝ ██║ ███████║██║ ██║██████╔╝██║ ██║███████╗ ██║ ██╔══██║██║ ██║██╔══██╗██║ ██║╚════██║ ╚██████╗██║ ██║╚██████╔╝██║ ██║╚██████╔╝███████║ ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ 🚀 Release Deployment System EOF echo -e "${NC}" echo -e " Deploying to: $DEPLOYMENT_TARGET" echo "" } # Check if builds exist check_builds() { log_step "Checking for built releases..." if [[ ! -d "$BUILD_DIR" ]]; then log_error "Build directory not found: $BUILD_DIR" log_info "Run build-release.sh or build-bzzz-minimal.sh first" exit 1 fi local bzzz_dir="$BUILD_DIR/bzzz/$RELEASE_CHANNEL" local whoosh_dir="$BUILD_DIR/whoosh/$RELEASE_CHANNEL" if [[ -d "$bzzz_dir" ]]; then local bzzz_count=$(find "$bzzz_dir" -name "bzzz-*" -type f 2>/dev/null | wc -l) log_info "Found $bzzz_count BZZZ binaries" else log_warn "No BZZZ builds found" fi if [[ -d "$whoosh_dir" ]]; then local whoosh_count=$(find "$whoosh_dir" -name "*.tar.gz" -type f 2>/dev/null | wc -l) log_info "Found $whoosh_count WHOOSH packages" else log_warn "No WHOOSH builds found" fi } # Deploy to local development server deploy_local() { log_step "Deploying to local development server..." mkdir -p "$LOCAL_SERVE_DIR"/{bzzz,whoosh}/"$RELEASE_CHANNEL" # Copy BZZZ files if [[ -d "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" ]]; then cp -r "$BUILD_DIR/bzzz/$RELEASE_CHANNEL"/* "$LOCAL_SERVE_DIR/bzzz/$RELEASE_CHANNEL/" log_info "BZZZ files copied to local server" fi # Copy WHOOSH files if [[ -d "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" ]]; then cp -r "$BUILD_DIR/whoosh/$RELEASE_CHANNEL"/* "$LOCAL_SERVE_DIR/whoosh/$RELEASE_CHANNEL/" log_info "WHOOSH files copied to local server" fi # Create simple HTTP server script cat > "$LOCAL_SERVE_DIR/serve.sh" << 'EOF' #!/bin/bash echo "🎵 CHORUS Local Release Server" echo "Serving releases at http://localhost:8000" echo "URLs:" echo " http://localhost:8000/bzzz/latest/bzzz-linux-amd64" echo " http://localhost:8000/bzzz/latest/bzzz.service" echo " http://localhost:8000/bzzz/latest/install-service.sh" echo "" echo "Press Ctrl+C to stop" python3 -m http.server 8000 EOF chmod +x "$LOCAL_SERVE_DIR/serve.sh" log_info "Local deployment completed" echo "" echo -e "${YELLOW}To start local release server:${NC}" echo " cd $LOCAL_SERVE_DIR && ./serve.sh" echo "" echo -e "${YELLOW}To test installer with local server:${NC}" echo " # Edit install-chorus.sh and change:" echo " # GITEA_URL=\"http://localhost:8000\"" echo " # Then run the installer" } # Deploy to production server deploy_production() { log_step "Deploying to production server..." if [[ ! -d "$CHORUS_SERVICES_ROOT" ]]; then log_error "Production deployment directory not found: $CHORUS_SERVICES_ROOT" log_info "Make sure you have access to the production server" exit 1 fi # Create production directory structure mkdir -p "$CHORUS_SERVICES_ROOT"/{bzzz,whoosh}/"$RELEASE_CHANNEL" # Copy BZZZ files if [[ -d "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" ]]; then cp -r "$BUILD_DIR/bzzz/$RELEASE_CHANNEL"/* "$CHORUS_SERVICES_ROOT/bzzz/$RELEASE_CHANNEL/" log_info "BZZZ files deployed to production" fi # Copy WHOOSH files if [[ -d "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" ]]; then cp -r "$BUILD_DIR/whoosh/$RELEASE_CHANNEL"/* "$CHORUS_SERVICES_ROOT/whoosh/$RELEASE_CHANNEL/" log_info "WHOOSH files deployed to production" fi # Set proper permissions chmod -R 644 "$CHORUS_SERVICES_ROOT"/{bzzz,whoosh}/"$RELEASE_CHANNEL"/* find "$CHORUS_SERVICES_ROOT" -name "*.sh" -exec chmod 755 {} \; find "$CHORUS_SERVICES_ROOT" -name "bzzz-*" -exec chmod 755 {} \; log_info "Production deployment completed" } # Deploy to Docker Swarm (if available) deploy_swarm() { log_step "Deploying to Docker Swarm..." if ! command -v docker >/dev/null 2>&1; then log_error "Docker not found" exit 1 fi # Create a simple nginx container to serve releases cat > "$BUILD_DIR/nginx.conf" << 'EOF' server { listen 80; server_name releases.chorus.services; root /usr/share/nginx/html; location / { autoindex on; autoindex_exact_size off; autoindex_localtime on; } location ~* \.(sh|exe)$ { add_header Content-Type application/octet-stream; } } EOF cat > "$BUILD_DIR/Dockerfile.releases" << 'EOF' FROM nginx:alpine COPY nginx.conf /etc/nginx/conf.d/default.conf COPY bzzz/ /usr/share/nginx/html/bzzz/ COPY whoosh/ /usr/share/nginx/html/whoosh/ EXPOSE 80 EOF cat > "$BUILD_DIR/docker-compose.releases.yml" << 'EOF' version: '3.8' services: releases: build: context: . dockerfile: Dockerfile.releases image: chorus/releases:latest ports: - "8080:80" deploy: replicas: 2 placement: constraints: - node.role == worker networks: default: external: true name: chorus_network EOF cd "$BUILD_DIR" # Build and deploy docker build -f Dockerfile.releases -t chorus/releases:latest . if docker stack ls | grep -q chorus-releases; then docker stack rm chorus-releases sleep 5 fi docker stack deploy -c docker-compose.releases.yml chorus-releases log_info "Docker Swarm deployment completed" log_info "Releases available at http://your-swarm-manager:8080" } # Update installer URLs for local testing update_installer_urls() { if [[ "$DEPLOYMENT_TARGET" == "local" ]]; then log_step "Updating installer URLs for local testing..." local installer_file="install-chorus.sh" if [[ -f "$installer_file" ]]; then # Create a local version cp "$installer_file" "install-chorus-local.sh" # Update URLs in the local version sed -i 's|https://releases.chorus.services|http://localhost:8000|g' "install-chorus-local.sh" log_info "Created install-chorus-local.sh for local testing" echo "" echo -e "${YELLOW}To test with local server:${NC}" echo " 1. Start local server: cd $LOCAL_SERVE_DIR && ./serve.sh" echo " 2. In another terminal: ./install-chorus-local.sh --coordinator" fi fi } # Show deployment summary show_summary() { echo "" echo -e "${GREEN}🎉 Deployment Complete!${NC}" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo -e "${BLUE}Deployment Target:${NC} $DEPLOYMENT_TARGET" echo -e "${BLUE}Release Channel:${NC} $RELEASE_CHANNEL" echo "" case $DEPLOYMENT_TARGET in local) echo -e "${YELLOW}Local URLs:${NC}" echo " http://localhost:8000/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64" echo " http://localhost:8000/bzzz/$RELEASE_CHANNEL/bzzz.service" echo " http://localhost:8000/bzzz/$RELEASE_CHANNEL/install-service.sh" ;; production) echo -e "${YELLOW}Production URLs:${NC}" echo " https://releases.chorus.services/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64" echo " https://releases.chorus.services/bzzz/$RELEASE_CHANNEL/bzzz.service" echo " https://releases.chorus.services/bzzz/$RELEASE_CHANNEL/install-service.sh" ;; swarm) echo -e "${YELLOW}Swarm URLs:${NC}" echo " http://your-swarm-manager:8080/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64" ;; esac echo "" } # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in --target) DEPLOYMENT_TARGET="$2" shift 2 ;; --channel) RELEASE_CHANNEL="$2" shift 2 ;; --help) echo "CHORUS Release Deployment Script" echo "" echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --target TARGET Deployment target: local, production, swarm (default: local)" echo " --channel CHANNEL Release channel (default: latest)" echo " --help Show this help" echo "" echo "Examples:" echo " $0 --target local" echo " $0 --target production --channel v1.0.0" echo " $0 --target swarm" echo "" exit 0 ;; *) echo "Unknown option: $1" exit 1 ;; esac done # Main deployment process main() { print_banner check_builds case $DEPLOYMENT_TARGET in local) deploy_local update_installer_urls ;; production) deploy_production ;; swarm) deploy_swarm ;; *) log_error "Unknown deployment target: $DEPLOYMENT_TARGET" log_info "Valid targets: local, production, swarm" exit 1 ;; esac show_summary } main "$@"