feat: Client-Download-System + Auto-Upload nach Build

Backend:
- GET /api/clients - Verfuegbare Clients auflisten (oeffentlich)
- GET /api/clients/<platform>/download - Client herunterladen (oeffentlich)
- POST /api/clients/<platform>/upload - Build hochladen (BUILD_UPLOAD_TOKEN)
- Alte Version wird automatisch bei neuem Upload ersetzt
- Plattformen: linux, windows, mac, android, ios

Frontend:
- /clients - Download-Seite mit Grid aller verfuegbaren Clients
- Login-Seite zeigt "Desktop & Mobile Clients herunterladen" Link
  wenn mindestens ein Client verfuegbar ist

build.sh:
- Nach jedem Build wird der Client automatisch auf CLOUD_URL
  hochgeladen (wenn CLOUD_URL + BUILD_UPLOAD_TOKEN in .env gesetzt)
- Bestes Format pro Plattform: AppImage > .deb > Binary (Linux),
  .msi > .exe (Windows), .dmg (Mac), .apk (Android), .ipa (iOS)

.env.example:
- CLOUD_URL: Oeffentliche URL der Cloud-Instanz
- BUILD_UPLOAD_TOKEN: Auth-Token fuer Build-Upload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker
2026-04-11 23:39:51 +02:00
parent 3ed5adc1e8
commit 9a6aa7aadc
7 changed files with 312 additions and 1 deletions
+67
View File
@@ -12,6 +12,9 @@
# ./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
@@ -29,8 +32,42 @@ 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
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"
@@ -45,6 +82,13 @@ build_linux() {
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() {
@@ -64,6 +108,12 @@ build_windows() {
echo 'Windows Build fertig!'"
info "Windows Build fertig! Dateien in: $OUTPUT_DIR/"
local upload_file=""
for f in "$OUTPUT_DIR"/*.msi "$OUTPUT_DIR"/*.exe; do
if [ -f "$f" ]; then upload_file="$f"; break; fi
done
[ -n "$upload_file" ] && upload_to_server "windows" "$upload_file"
}
build_mac() {
@@ -79,6 +129,12 @@ build_mac() {
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() {
@@ -98,6 +154,7 @@ build_android() {
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() {
@@ -115,6 +172,12 @@ build_ios() {
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() {
@@ -172,5 +235,9 @@ case "${1:-help}" in
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