#!/bin/bash # # Mini-Cloud Client Build Script # Baut Desktop- und Mobile-Clients via Docker (kein lokales Setup noetig) # # Verwendung: # ./build.sh linux # Linux Desktop (.deb + .AppImage) # ./build.sh windows # Windows Desktop (.msi + .exe) # ./build.sh mac # macOS Desktop (.dmg) - nur auf macOS moeglich # ./build.sh android # Android App (.apk) # ./build.sh ios # iOS App (.ipa) - nur auf macOS moeglich # ./build.sh all-desktop # Linux + Windows # ./build.sh clean # Build-Cache loeschen # # Nach dem Build wird der Client automatisch auf den Server hochgeladen # wenn CLOUD_URL und BUILD_UPLOAD_TOKEN in .env gesetzt sind. # set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" DESKTOP_DIR="$SCRIPT_DIR/clients/desktop" MOBILE_DIR="$SCRIPT_DIR/clients/mobile" OUTPUT_DIR="$SCRIPT_DIR/build-output" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' info() { echo -e "${GREEN}[BUILD]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } # Load .env if exists if [ -f "$SCRIPT_DIR/.env" ]; then export $(grep -v '^#' "$SCRIPT_DIR/.env" | grep -E '^(CLOUD_URL|BUILD_UPLOAD_TOKEN)=' | xargs) fi mkdir -p "$OUTPUT_DIR" upload_to_server() { local platform="$1" local filepath="$2" if [ -z "$CLOUD_URL" ] || [ -z "$BUILD_UPLOAD_TOKEN" ]; then warn "CLOUD_URL oder BUILD_UPLOAD_TOKEN nicht gesetzt - Upload uebersprungen" warn "Setze beide in .env fuer automatischen Upload" return fi local filename=$(basename "$filepath") info "Lade $filename auf $CLOUD_URL hoch..." local http_code http_code=$(curl -s -o /tmp/upload_response.txt -w "%{http_code}" \ -X POST "$CLOUD_URL/api/clients/$platform/upload" \ -H "X-Build-Token: $BUILD_UPLOAD_TOKEN" \ -F "file=@$filepath") if [ "$http_code" = "200" ]; then info "Upload erfolgreich: $filename -> $CLOUD_URL" cat /tmp/upload_response.txt | python3 -m json.tool 2>/dev/null || cat /tmp/upload_response.txt elif [ "$http_code" = "403" ]; then error "Upload fehlgeschlagen: BUILD_UPLOAD_TOKEN ist falsch!" echo "" echo " Der BUILD_UPLOAD_TOKEN in deiner .env muss der SECRET_KEY" echo " oder JWT_SECRET_KEY vom Zielserver sein." echo "" echo " Pruefe auf dem Server: grep SECRET_KEY /pfad/zur/.env" echo " Dann den Wert in die lokale .env als BUILD_UPLOAD_TOKEN kopieren." echo "" elif [ "$http_code" = "000" ]; then error "Upload fehlgeschlagen: Server nicht erreichbar ($CLOUD_URL)" else warn "Upload fehlgeschlagen (HTTP $http_code)" cat /tmp/upload_response.txt 2>/dev/null fi rm -f /tmp/upload_response.txt } build_linux() { info "Baue Linux Desktop Client..." cd "$DESKTOP_DIR" sudo docker build -f Dockerfile.build -t minicloud-desktop-builder . sudo docker run --rm \ -v "$OUTPUT_DIR:/output" \ minicloud-desktop-builder \ bash -c "npm run tauri build && cp -r src-tauri/target/release/bundle/* /output/ 2>/dev/null; \ cp src-tauri/target/release/minicloud-sync /output/ 2>/dev/null; \ echo 'Linux Build fertig!'" info "Linux Build fertig! Dateien in: $OUTPUT_DIR/" # Upload best file (AppImage > deb > binary) local upload_file="" for f in "$OUTPUT_DIR"/*.AppImage "$OUTPUT_DIR"/*.deb "$OUTPUT_DIR"/minicloud-sync; do if [ -f "$f" ]; then upload_file="$f"; break; fi done [ -n "$upload_file" ] && upload_to_server "linux" "$upload_file" } build_windows() { info "Baue Windows Desktop Client (Cross-Compile)..." cd "$DESKTOP_DIR" sudo docker build -f Dockerfile.build -t minicloud-desktop-builder . sudo docker run --rm \ -v "$OUTPUT_DIR:/output" \ -e CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc \ minicloud-desktop-builder \ bash -c "npm run tauri build -- --target x86_64-pc-windows-gnu 2>&1 || true; \ find src-tauri/target -name '*.exe' -o -name '*.msi' | head -5; \ cp src-tauri/target/x86_64-pc-windows-gnu/release/*.exe /output/ 2>/dev/null; \ cp -r src-tauri/target/x86_64-pc-windows-gnu/release/bundle/* /output/ 2>/dev/null; \ echo 'Windows Build fertig!'" info "Windows Build fertig! Dateien in: $OUTPUT_DIR/" # Upload setup installer (NSIS with WebView2 bundled), not the naked .exe local upload_file="" for f in "$OUTPUT_DIR"/nsis/*setup*.exe "$OUTPUT_DIR"/*.msi "$OUTPUT_DIR"/nsis/*.exe; do if [ -f "$f" ]; then upload_file="$f"; break; fi done [ -n "$upload_file" ] && upload_to_server "windows" "$upload_file" } build_mac() { # macOS kann nicht cross-compiled werden, muss auf macOS laufen if [[ "$(uname)" != "Darwin" ]]; then error "macOS Build ist nur auf macOS moeglich!" fi info "Baue macOS Desktop Client..." cd "$DESKTOP_DIR" npm install npm run tauri build cp -r src-tauri/target/release/bundle/* "$OUTPUT_DIR/" 2>/dev/null info "macOS Build fertig! Dateien in: $OUTPUT_DIR/" local upload_file="" for f in "$OUTPUT_DIR"/*.dmg; do if [ -f "$f" ]; then upload_file="$f"; break; fi done [ -n "$upload_file" ] && upload_to_server "mac" "$upload_file" } build_android() { if [ ! -d "$MOBILE_DIR" ]; then error "Mobile Client noch nicht erstellt (clients/mobile/)" fi info "Baue Android App..." cd "$MOBILE_DIR" sudo docker run --rm \ -v "$MOBILE_DIR:/app" \ -v "$OUTPUT_DIR:/output" \ ghcr.io/nickvdyck/flutter-android:latest \ bash -c "cd /app && flutter pub get && flutter build apk --release && \ cp build/app/outputs/flutter-apk/app-release.apk /output/minicloud.apk && \ echo 'Android Build fertig!'" info "Android APK: $OUTPUT_DIR/minicloud.apk" [ -f "$OUTPUT_DIR/minicloud.apk" ] && upload_to_server "android" "$OUTPUT_DIR/minicloud.apk" } build_ios() { if [[ "$(uname)" != "Darwin" ]]; then error "iOS Build ist nur auf macOS moeglich!" fi if [ ! -d "$MOBILE_DIR" ]; then error "Mobile Client noch nicht erstellt (clients/mobile/)" fi info "Baue iOS App..." cd "$MOBILE_DIR" flutter pub get flutter build ios --release info "iOS Build fertig! Oeffne Xcode fuer Signierung + Archive." local upload_file="" for f in "$MOBILE_DIR"/build/ios/ipa/*.ipa; do if [ -f "$f" ]; then upload_file="$f"; break; fi done [ -n "$upload_file" ] && upload_to_server "ios" "$upload_file" } do_clean() { info "Loesche Build-Cache..." rm -rf "$OUTPUT_DIR"/* rm -rf "$DESKTOP_DIR/src-tauri/target" rm -rf "$MOBILE_DIR/build" 2>/dev/null sudo docker rmi minicloud-desktop-builder 2>/dev/null || true info "Build-Cache geloescht." } # Main case "${1:-help}" in linux) build_linux ;; windows) build_windows ;; mac|macos) build_mac ;; android) build_android ;; ios) build_ios ;; all-desktop) build_linux build_windows ;; clean) do_clean ;; *) echo "" echo "Mini-Cloud Client Build Script" echo "" echo "Verwendung: $0 " echo "" echo "Desktop:" echo " linux Linux (.deb + .AppImage + Binary)" echo " windows Windows (.msi + .exe) - Cross-Compile via Docker" echo " mac macOS (.dmg) - nur auf macOS" echo " all-desktop Linux + Windows" echo "" echo "Mobile:" echo " android Android (.apk) - via Docker" echo " ios iOS (.ipa) - nur auf macOS" echo "" echo "Sonstiges:" echo " clean Build-Cache loeschen" echo "" echo "Alle Builds (ausser mac/ios) laufen in Docker - kein lokales" echo "Setup noetig. Output landet in: build-output/" echo "" echo "Auto-Upload: Wenn CLOUD_URL und BUILD_UPLOAD_TOKEN in .env" echo "gesetzt sind, wird der Client nach dem Build automatisch auf" echo "den Server hochgeladen und steht zum Download bereit." echo "" ;; esac