Files
geo/app/deploy-app.sh
pierre 2f5946a184 feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles
- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD)
  * DEV: Clés TEST Pierre (mode test)
  * REC: Clés TEST Client (mode test)
  * PROD: Clés LIVE Client (mode live)
- Ajout de la gestion des bases de données immeubles/bâtiments
  * Configuration buildings_database pour DEV/REC/PROD
  * Service BuildingService pour enrichissement des adresses
- Optimisations pages et améliorations ergonomie
- Mises à jour des dépendances Composer
- Nettoyage des fichiers obsolètes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:26:27 +01:00

552 lines
23 KiB
Bash
Executable File

#!/bin/bash
# Script de déploiement unifié pour GEOSECTOR Flutter App
# Version: 4.0 (Janvier 2025)
# Auteur: Pierre (avec l'aide de Claude)
#
# Usage:
# ./deploy-app.sh # Déploiement local DEV (build → container geo)
# ./deploy-app.sh rca # Livraison RECETTE (container geo → rca-geo)
# ./deploy-app.sh pra # Livraison PRODUCTION (rca-geo → pra-geo)
set -euo pipefail
# Timestamp de début pour mesurer le temps total
START_TIME=$(($(date +%s%N)/1000000))
echo "[$(date '+%H:%M:%S.%3N')] Début du script deploy-app.sh"
cd /home/pierre/dev/geosector/app
# =====================================
# Configuration générale
# =====================================
# Paramètre optionnel pour l'environnement cible
TARGET_ENV=${1:-dev}
# Configuration SSH
HOST_KEY="/home/pierre/.ssh/id_rsa_mbpi"
HOST_PORT="22"
HOST_USER="root"
# Configuration des serveurs
IN3_HOST="IN3" # Serveur IN3 (via .ssh/config)
RCA_HOST="195.154.80.116" # Serveur de recette (même que IN3)
PRA_HOST="51.159.7.190" # Serveur de production
# Configuration Incus
INCUS_PROJECT="default"
APP_PATH="/var/www/geosector/app"
FINAL_OWNER="nginx"
FINAL_GROUP="nginx"
# Configuration de sauvegarde
BACKUP_DIR="/data/backup/geosector"
# Couleurs pour les messages
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# =====================================
# Fonctions utilitaires
# =====================================
echo_step() {
echo -e "${GREEN}==>${NC} $1"
}
echo_info() {
echo -e "${BLUE}Info:${NC} $1"
}
echo_warning() {
echo -e "${YELLOW}Warning:${NC} $1"
}
echo_error() {
echo -e "${RED}Error:${NC} $1"
exit 1
}
# Fonction pour créer une sauvegarde locale
create_local_backup() {
local archive_file=$1
local backup_type=$2
echo_info "Creating backup in ${BACKUP_DIR}..."
if [ ! -d "${BACKUP_DIR}" ]; then
mkdir -p "${BACKUP_DIR}" || echo_warning "Could not create backup directory ${BACKUP_DIR}"
fi
if [ -d "${BACKUP_DIR}" ]; then
BACKUP_FILE="${BACKUP_DIR}/app-${backup_type}-$(date +%Y%m%d-%H%M%S).tar.gz"
cp "${archive_file}" "${BACKUP_FILE}" && {
echo_info "Backup saved to: ${BACKUP_FILE}"
echo_info "Backup size: $(du -h "${BACKUP_FILE}" | cut -f1)"
# Nettoyer les anciens backups (garder les 10 derniers)
echo_info "Cleaning old backups (keeping last 10)..."
ls -t "${BACKUP_DIR}"/app-${backup_type}-*.tar.gz 2>/dev/null | tail -n +11 | xargs -r rm -f && {
REMAINING_BACKUPS=$(ls "${BACKUP_DIR}"/app-${backup_type}-*.tar.gz 2>/dev/null | wc -l)
echo_info "Kept ${REMAINING_BACKUPS} backup(s)"
}
} || echo_warning "Failed to create backup in ${BACKUP_DIR}"
fi
}
# =====================================
# Détermination de la configuration selon l'environnement
# =====================================
case $TARGET_ENV in
"dev")
echo_step "Configuring for DEV deployment to IN3"
SOURCE_TYPE="local_build"
DEST_CONTAINER="dva-geo"
DEST_HOST="${IN3_HOST}"
ENV_NAME="DEVELOPMENT"
;;
"rca")
echo_step "Configuring for RECETTE delivery (IN3 dva-geo to rca-geo)"
SOURCE_TYPE="remote_container"
SOURCE_HOST="${IN3_HOST}"
SOURCE_CONTAINER="dva-geo"
DEST_CONTAINER="rca-geo"
DEST_HOST="${IN3_HOST}" # Même serveur IN3
ENV_NAME="RECETTE"
;;
"pra")
echo_step "Configuring for PRODUCTION delivery"
SOURCE_TYPE="remote_container"
SOURCE_HOST="${RCA_HOST}"
SOURCE_CONTAINER="rca-geo"
DEST_CONTAINER="pra-geo"
DEST_HOST="${PRA_HOST}"
ENV_NAME="PRODUCTION"
;;
*)
echo_error "Unknown environment: $TARGET_ENV. Use 'dev', 'rca' or 'pra'"
;;
esac
echo_info "Deployment flow: ${ENV_NAME}"
# =====================================
# Création de l'archive selon la source
# =====================================
TIMESTAMP=$(date +%s)
ARCHIVE_NAME="app-deploy-${TIMESTAMP}.tar.gz"
TEMP_ARCHIVE="/tmp/${ARCHIVE_NAME}"
if [ "$SOURCE_TYPE" = "local_build" ]; then
# DEV: Build Flutter et créer une archive
echo_step "Building Flutter app for DEV..."
# Configuration du cache local (partagé web + iOS/Android)
echo_info "📦 Configuration du cache local pour builds web et mobile..."
export PUB_CACHE="$PWD/.pub-cache-local"
export GRADLE_USER_HOME="$PWD/.gradle-local"
mkdir -p "$PUB_CACHE" "$GRADLE_USER_HOME"
echo_info " Cache Pub: $PUB_CACHE"
echo_info " Cache Gradle: $GRADLE_USER_HOME"
echo_info " → Packages patchés seront prêts pour transfert iOS/Android"
# Charger les variables d'environnement
if [ ! -f .env-deploy-dev ]; then
echo_error "Missing .env-deploy-dev file"
fi
source .env-deploy-dev
# Mise à jour de la version
echo_info "Managing version..."
if [ -f ../VERSION ]; then
VERSION=$(cat ../VERSION | tr -d '\n\r' | tr -d ' ')
echo_info "Version found: $VERSION"
else
echo_warning "VERSION file not found"
read -p "Enter version number (x.x.x format): " VERSION
if [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$VERSION" > ../VERSION
echo_info "VERSION file created with $VERSION"
else
echo_error "Invalid version format"
fi
fi
# Génération du build number et mise à jour du pubspec.yaml
BUILD_NUMBER=$(echo $VERSION | tr -d '.')
FULL_VERSION="${VERSION}+${BUILD_NUMBER}"
echo_info "Full version: $FULL_VERSION"
sed -i "s/^version: .*/version: $FULL_VERSION/" pubspec.yaml || echo_error "Failed to update pubspec.yaml"
# Génération automatique du fichier AppInfoService (remplace package_info_plus)
echo_info "Auto-generating app_info_service.dart with version $VERSION+$BUILD_NUMBER..."
cat > lib/core/services/app_info_service.dart <<EOF
// ⚠️ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
// This file is automatically generated by deploy-app.sh script
// Last update: $(date '+%Y-%m-%d %H:%M:%S')
// Source: ../VERSION file
//
// GEOSECTOR App Version Service
// Provides application version and build information without external dependencies
class AppInfoService {
// Version number (format: x.x.x)
static const String version = '$VERSION';
// Build number (version without dots: xxx)
static const String buildNumber = '$BUILD_NUMBER';
// Full version string (format: vx.x.x+xxx)
static String get fullVersion => 'v\$version+\$buildNumber';
// Application name
static const String appName = 'GeoSector';
// Package name
static const String packageName = 'fr.geosector.app3';
}
EOF
echo_info "✓ app_info_service.dart updated successfully"
# Mode de compilation en RELEASE (production)
echo_info "🏁 Mode RELEASE - Compilation optimisée pour production"
BUILD_FLAGS="--release"
# Nettoyage
echo_info "Cleaning previous builds..."
rm -rf .dart_tool build .packages pubspec.lock 2>/dev/null || true
flutter clean || echo_warning "Flutter clean partially failed"
# Build
echo_info "Getting dependencies..."
flutter pub get || echo_error "Flutter pub get failed"
# Patch nfc_manager 3.3.0 (AndroidManifest namespace)
echo_info "Applying nfc_manager 3.3.0 patch..."
./fastlane/scripts/commun/fix-nfc-manager.sh || echo_error "nfc_manager patch failed"
echo_info "Cleaning generated files..."
dart run build_runner clean || echo_error "Build runner clean failed"
echo_info "Generating code files..."
dart run build_runner build --delete-conflicting-outputs || echo_error "Code generation failed"
echo_info "Building Flutter web application..."
# Mesure du temps de compilation Flutter
BUILD_START=$(($(date +%s%N)/1000000))
echo_info "[$(date '+%H:%M:%S.%3N')] Début de la compilation Flutter (Mode: RELEASE)"
flutter build web $BUILD_FLAGS || echo_error "Flutter build failed"
BUILD_END=$(($(date +%s%N)/1000000))
BUILD_TIME=$((BUILD_END - BUILD_START))
echo_info "[$(date '+%H:%M:%S.%3N')] Fin de la compilation Flutter"
echo_info "⏱️ Temps de compilation Flutter: ${BUILD_TIME} ms ($((BUILD_TIME/1000)) secondes)"
echo_info "Fixing web assets structure..."
./copy-web-images.sh || echo_error "Failed to fix web assets"
# Créer l'archive depuis le build
echo_info "Creating archive from build..."
tar -czf "${TEMP_ARCHIVE}" -C ${FLUTTER_BUILD_DIR} . || echo_error "Failed to create archive"
create_local_backup "${TEMP_ARCHIVE}" "dev"
elif [ "$SOURCE_TYPE" = "local_container" ]; then
# RCA: Créer une archive depuis le container local
echo_step "Creating archive from local container ${SOURCE_CONTAINER}..."
echo_info "Switching to Incus project ${INCUS_PROJECT}..."
incus project switch ${INCUS_PROJECT} || echo_error "Failed to switch project"
# Créer l'archive directement depuis le container local
incus exec ${SOURCE_CONTAINER} -- tar -czf /tmp/${ARCHIVE_NAME} -C ${APP_PATH} . || echo_error "Failed to create archive from container"
# Récupérer l'archive depuis le container
incus file pull ${SOURCE_CONTAINER}/tmp/${ARCHIVE_NAME} ${TEMP_ARCHIVE} || echo_error "Failed to pull archive from container"
incus exec ${SOURCE_CONTAINER} -- rm -f /tmp/${ARCHIVE_NAME}
create_local_backup "${TEMP_ARCHIVE}" "to-rca"
elif [ "$SOURCE_TYPE" = "remote_container" ]; then
# RCA ou PRA: Créer une archive depuis un container distant
echo_step "Creating archive from remote container ${SOURCE_CONTAINER} on ${SOURCE_HOST}..."
# Créer l'archive sur le serveur source
if [[ "$SOURCE_HOST" == "IN3" ]]; then
ssh ${SOURCE_HOST} "
incus project switch ${INCUS_PROJECT} &&
incus exec ${SOURCE_CONTAINER} -- tar -czf /tmp/${ARCHIVE_NAME} -C ${APP_PATH} .
" || echo_error "Failed to create archive on IN3"
# Extraire l'archive du container vers l'hôte
ssh ${SOURCE_HOST} "
incus file pull ${SOURCE_CONTAINER}/tmp/${ARCHIVE_NAME} /tmp/${ARCHIVE_NAME} &&
incus exec ${SOURCE_CONTAINER} -- rm -f /tmp/${ARCHIVE_NAME}
" || echo_error "Failed to extract archive from IN3 container"
# Télécharger l'archive vers la machine locale
if [[ "$TARGET_ENV" == "pra" ]]; then
# Pour PROD: télécharger directement vers /data/backup/geosector/
BACKUP_TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/app-to-pra-${BACKUP_TIMESTAMP}.tar.gz"
echo_info "Downloading archive to backup directory..."
mkdir -p "${BACKUP_DIR}" || echo_warning "Could not create backup directory ${BACKUP_DIR}"
scp ${SOURCE_HOST}:/tmp/${ARCHIVE_NAME} ${BACKUP_FILE} || echo_error "Failed to download archive from IN3"
# Nettoyer sur IN3
ssh ${SOURCE_HOST} "rm -f /tmp/${ARCHIVE_NAME}"
echo_info "Backup saved to: ${BACKUP_FILE}"
echo_info "Backup size: $(du -h \"${BACKUP_FILE}\" | cut -f1)"
# Nettoyer les anciens backups (garder les 10 derniers)
echo_info "Cleaning old backups (keeping last 10)..."
ls -t "${BACKUP_DIR}"/app-to-pra-*.tar.gz 2>/dev/null | tail -n +11 | xargs -r rm -f && {
REMAINING_BACKUPS=$(ls "${BACKUP_DIR}"/app-to-pra-*.tar.gz 2>/dev/null | wc -l)
echo_info "Kept ${REMAINING_BACKUPS} backup(s)"
}
# Utiliser le backup comme archive de travail
TEMP_ARCHIVE="${BACKUP_FILE}"
else
# Pour RCA: copier vers /tmp comme avant
scp ${SOURCE_HOST}:/tmp/${ARCHIVE_NAME} ${TEMP_ARCHIVE} || echo_error "Failed to copy archive from IN3"
create_local_backup "${TEMP_ARCHIVE}" "to-rca"
fi
else
ssh -i ${HOST_KEY} -p ${HOST_PORT} ${HOST_USER}@${SOURCE_HOST} "
incus project switch ${INCUS_PROJECT} &&
incus exec ${SOURCE_CONTAINER} -- tar -czf /tmp/${ARCHIVE_NAME} -C ${APP_PATH} .
" || echo_error "Failed to create archive on remote"
# Extraire l'archive du container vers l'hôte
ssh -i ${HOST_KEY} -p ${HOST_PORT} ${HOST_USER}@${SOURCE_HOST} "
incus file pull ${SOURCE_CONTAINER}/tmp/${ARCHIVE_NAME} /tmp/${ARCHIVE_NAME} &&
incus exec ${SOURCE_CONTAINER} -- rm -f /tmp/${ARCHIVE_NAME}
" || echo_error "Failed to extract archive from remote container"
# Copier l'archive vers la machine locale pour backup
scp -i ${HOST_KEY} -P ${HOST_PORT} ${HOST_USER}@${SOURCE_HOST}:/tmp/${ARCHIVE_NAME} ${TEMP_ARCHIVE} || echo_error "Failed to copy archive locally"
create_local_backup "${TEMP_ARCHIVE}" "to-pra"
fi
fi
ARCHIVE_SIZE=$(du -h "${TEMP_ARCHIVE}" | cut -f1)
echo_info "Archive size: ${ARCHIVE_SIZE}"
# =====================================
# Déploiement selon la destination
# =====================================
if [ "$DEST_HOST" = "local" ]; then
# Déploiement sur container local (ancien mode, non utilisé)
echo_step "Deploying to local container ${DEST_CONTAINER}..."
echo_info "Switching to Incus project ${INCUS_PROJECT}..."
incus project switch ${INCUS_PROJECT} || echo_error "Failed to switch to project ${INCUS_PROJECT}"
echo_info "Pushing archive to container..."
incus file push "${TEMP_ARCHIVE}" ${DEST_CONTAINER}/tmp/${ARCHIVE_NAME} || echo_error "Failed to push archive to container"
echo_info "Preparing deployment directory..."
incus exec ${DEST_CONTAINER} -- mkdir -p ${APP_PATH} || echo_error "Failed to create deployment directory"
incus exec ${DEST_CONTAINER} -- rm -rf ${APP_PATH}/* || echo_warning "Could not clean deployment directory"
echo_info "Extracting archive..."
incus exec ${DEST_CONTAINER} -- tar -xzf /tmp/${ARCHIVE_NAME} -C ${APP_PATH}/ || echo_error "Failed to extract archive"
echo_info "Setting permissions..."
incus exec ${DEST_CONTAINER} -- chown -R ${FINAL_OWNER}:${FINAL_GROUP} ${APP_PATH}
incus exec ${DEST_CONTAINER} -- find ${APP_PATH} -type d -exec chmod 755 {} \;
incus exec ${DEST_CONTAINER} -- find ${APP_PATH} -type f -exec chmod 644 {} \;
echo_info "Cleaning up..."
incus exec ${DEST_CONTAINER} -- rm -f /tmp/${ARCHIVE_NAME}
else
# Déploiement sur container distant (DEV sur IN3, RCA ou PRA)
echo_step "Deploying to remote container ${DEST_CONTAINER} on ${DEST_HOST}..."
# Créer une sauvegarde sur le serveur de destination
BACKUP_TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
REMOTE_BACKUP_DIR="${APP_PATH}_backup_${BACKUP_TIMESTAMP}"
echo_info "Creating backup on destination..."
# Utiliser ssh avec IN3 configuré ou ssh classique
if [[ "$DEST_HOST" == "IN3" ]]; then
ssh ${DEST_HOST} "
incus project switch ${INCUS_PROJECT} &&
incus exec ${DEST_CONTAINER} -- test -d ${APP_PATH} &&
incus exec ${DEST_CONTAINER} -- cp -r ${APP_PATH} ${REMOTE_BACKUP_DIR} &&
echo 'Backup created: ${REMOTE_BACKUP_DIR}'
" || echo_warning "No existing installation to backup"
# Nettoyage automatique des anciens backups (garder les 2 derniers)
echo_info "Cleaning old remote backups (keeping last 2)..."
ssh ${DEST_HOST} "
incus exec ${DEST_CONTAINER} -- bash -c '
cd /var/www/geosector/ &&
ls -dt app_backup_* 2>/dev/null | tail -n +3 | xargs -r rm -rf &&
echo \"Remote backups: \$(ls -d app_backup_* 2>/dev/null | wc -l) kept\"
'
" || echo_warning "Could not clean old remote backups"
else
ssh -i ${HOST_KEY} -p ${HOST_PORT} ${HOST_USER}@${DEST_HOST} "
incus project switch ${INCUS_PROJECT} &&
incus exec ${DEST_CONTAINER} -- test -d ${APP_PATH} &&
incus exec ${DEST_CONTAINER} -- cp -r ${APP_PATH} ${REMOTE_BACKUP_DIR} &&
echo 'Backup created: ${REMOTE_BACKUP_DIR}'
" || echo_warning "No existing installation to backup"
# Nettoyage automatique des anciens backups (garder les 2 derniers)
echo_info "Cleaning old remote backups (keeping last 2)..."
ssh -i ${HOST_KEY} -p ${HOST_PORT} ${HOST_USER}@${DEST_HOST} "
incus exec ${DEST_CONTAINER} -- bash -c '
cd /var/www/geosector/ &&
ls -dt app_backup_* 2>/dev/null | tail -n +3 | xargs -r rm -rf &&
echo \"Remote backups: \$(ls -d app_backup_* 2>/dev/null | wc -l) kept\"
'
" || echo_warning "Could not clean old remote backups"
fi
# Transférer l'archive vers le serveur de destination
echo_info "Transferring archive to ${DEST_HOST}..."
if [ "$SOURCE_TYPE" = "local_build" ]; then
# Pour DEV: copier depuis local vers IN3
if [[ "$DEST_HOST" == "IN3" ]]; then
scp ${TEMP_ARCHIVE} ${DEST_HOST}:/tmp/${ARCHIVE_NAME} || echo_error "Failed to copy archive to IN3"
else
scp -i ${HOST_KEY} -P ${HOST_PORT} ${TEMP_ARCHIVE} ${HOST_USER}@${DEST_HOST}:/tmp/${ARCHIVE_NAME} || echo_error "Failed to copy archive to destination"
fi
elif [ "$SOURCE_TYPE" = "local_container" ]; then
# Pour RCA depuis container local: copier depuis local vers distant
if [[ "$DEST_HOST" == "IN3" ]]; then
scp ${TEMP_ARCHIVE} ${DEST_HOST}:/tmp/${ARCHIVE_NAME} || echo_error "Failed to copy archive to IN3"
else
scp -i ${HOST_KEY} -P ${HOST_PORT} ${TEMP_ARCHIVE} ${HOST_USER}@${DEST_HOST}:/tmp/${ARCHIVE_NAME} || echo_error "Failed to copy archive to destination"
fi
else
# Pour transferts entre containers distants
if [[ "$SOURCE_HOST" == "IN3" && "$DEST_HOST" == "IN3" ]]; then
# Cas spécial : source et destination sur le même serveur IN3 (RCA)
echo_info "Transfer within IN3 (${SOURCE_CONTAINER} to ${DEST_CONTAINER})"
# L'archive est déjà sur IN3, pas besoin de transfert réseau
# Elle a été créée lors de l'étape "remote_container" plus haut
elif [[ "$TARGET_ENV" == "pra" ]]; then
# Pour PROD: upload depuis le PC local (backup) vers IN4
echo_info "Uploading from local backup to IN4..."
scp -i ${HOST_KEY} -P ${HOST_PORT} ${TEMP_ARCHIVE} ${HOST_USER}@${DEST_HOST}:/tmp/${ARCHIVE_NAME} || echo_error "Failed to upload archive to IN4"
elif [[ "$SOURCE_HOST" == "IN3" ]]; then
# Source sur IN3, destination ailleurs (cas théorique)
ssh ${SOURCE_HOST} "
scp -i ${HOST_KEY} -P ${HOST_PORT} /tmp/${ARCHIVE_NAME} ${HOST_USER}@${DEST_HOST}:/tmp/${ARCHIVE_NAME}
" || echo_error "Failed to transfer archive from IN3"
ssh ${SOURCE_HOST} "rm -f /tmp/${ARCHIVE_NAME}"
else
# Transfert classique serveur à serveur
ssh -i ${HOST_KEY} -p ${HOST_PORT} ${HOST_USER}@${SOURCE_HOST} "
scp -i ${HOST_KEY} -P ${HOST_PORT} /tmp/${ARCHIVE_NAME} ${HOST_USER}@${DEST_HOST}:/tmp/${ARCHIVE_NAME}
" || echo_error "Failed to transfer archive between servers"
ssh -i ${HOST_KEY} -p ${HOST_PORT} ${HOST_USER}@${SOURCE_HOST} "rm -f /tmp/${ARCHIVE_NAME}"
fi
fi
# Déployer sur le container de destination
echo_info "Extracting on destination container..."
if [[ "$DEST_HOST" == "IN3" ]]; then
ssh ${DEST_HOST} "
set -euo pipefail
# Pousser l'archive dans le container
incus project switch ${INCUS_PROJECT} &&
incus file push /tmp/${ARCHIVE_NAME} ${DEST_CONTAINER}/tmp/${ARCHIVE_NAME} &&
# Nettoyer et recréer le dossier
incus exec ${DEST_CONTAINER} -- rm -rf ${APP_PATH} &&
incus exec ${DEST_CONTAINER} -- mkdir -p ${APP_PATH} &&
# Extraire l'archive
incus exec ${DEST_CONTAINER} -- tar -xzf /tmp/${ARCHIVE_NAME} -C ${APP_PATH}/ &&
# Permissions
incus exec ${DEST_CONTAINER} -- chown -R ${FINAL_OWNER}:${FINAL_GROUP} ${APP_PATH} &&
incus exec ${DEST_CONTAINER} -- find ${APP_PATH} -type d -exec chmod 755 {} \; &&
incus exec ${DEST_CONTAINER} -- find ${APP_PATH} -type f -exec chmod 644 {} \; &&
# Nettoyage
incus exec ${DEST_CONTAINER} -- rm -f /tmp/${ARCHIVE_NAME} &&
rm -f /tmp/${ARCHIVE_NAME}
" || echo_error "Deployment failed on IN3"
else
ssh -i ${HOST_KEY} -p ${HOST_PORT} ${HOST_USER}@${DEST_HOST} "
set -euo pipefail
# Pousser l'archive dans le container
incus project switch ${INCUS_PROJECT} &&
incus file push /tmp/${ARCHIVE_NAME} ${DEST_CONTAINER}/tmp/${ARCHIVE_NAME} &&
# Nettoyer et recréer le dossier
incus exec ${DEST_CONTAINER} -- rm -rf ${APP_PATH} &&
incus exec ${DEST_CONTAINER} -- mkdir -p ${APP_PATH} &&
# Extraire l'archive
incus exec ${DEST_CONTAINER} -- tar -xzf /tmp/${ARCHIVE_NAME} -C ${APP_PATH}/ &&
# Permissions
incus exec ${DEST_CONTAINER} -- chown -R ${FINAL_OWNER}:${FINAL_GROUP} ${APP_PATH} &&
incus exec ${DEST_CONTAINER} -- find ${APP_PATH} -type d -exec chmod 755 {} \; &&
incus exec ${DEST_CONTAINER} -- find ${APP_PATH} -type f -exec chmod 644 {} \; &&
# Nettoyage
incus exec ${DEST_CONTAINER} -- rm -f /tmp/${ARCHIVE_NAME} &&
rm -f /tmp/${ARCHIVE_NAME}
" || echo_error "Deployment failed on destination"
fi
echo_info "Remote backup saved: ${REMOTE_BACKUP_DIR} on ${DEST_CONTAINER}"
fi
# Nettoyage local
# Pour PROD, on conserve l'archive dans /data/backup/geosector/
# Pour DEV et RCA, on supprime le fichier temporaire
if [[ "$TARGET_ENV" != "pra" ]]; then
rm -f "${TEMP_ARCHIVE}"
fi
# =====================================
# Résumé final
# =====================================
echo_step "Deployment completed successfully!"
echo_info "Environment: ${ENV_NAME}"
if [ "$TARGET_ENV" = "dev" ]; then
echo_info "Built and deployed Flutter app to container ${DEST_CONTAINER}"
echo_info "Version: ${FULL_VERSION}"
elif [ "$TARGET_ENV" = "rca" ]; then
echo_info "Delivered from ${SOURCE_CONTAINER} (local) to ${DEST_CONTAINER} on ${DEST_HOST}"
elif [ "$TARGET_ENV" = "pra" ]; then
echo_info "Delivered from ${SOURCE_CONTAINER} on ${SOURCE_HOST} to ${DEST_CONTAINER} on ${DEST_HOST}"
fi
echo_info "Deployment completed at: $(date '+%H:%M:%S')"
# Calcul et affichage du temps total
END_TIME=$(($(date +%s%N)/1000000))
TOTAL_TIME=$((END_TIME - START_TIME))
echo_info "[$(date '+%H:%M:%S.%3N')] Fin du script"
echo_step "⏱️ TEMPS TOTAL D'EXÉCUTION: ${TOTAL_TIME} ms ($((TOTAL_TIME/1000)) secondes)"
# Journaliser le déploiement
echo "$(date '+%Y-%m-%d %H:%M:%S') - Flutter app deployed to ${ENV_NAME} (${DEST_CONTAINER}) - Total: ${TOTAL_TIME}ms" >> ~/.geo_deploy_history