- #17: Amélioration gestion des secteurs et statistiques - #18: Optimisation services API et logs - #19: Corrections Flutter widgets et repositories - #20: Fix création passage - détection automatique ope_users.id vs users.id Suppression dossier web/ (migration vers app Flutter) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
499 lines
18 KiB
Bash
Executable File
499 lines
18 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Script de déploiement iOS automatisé pour GEOSECTOR
|
||
# Version: 1.0
|
||
# Date: 2025-12-05
|
||
# Auteur: Pierre (avec l'aide de Claude)
|
||
#
|
||
# Usage:
|
||
# ./deploy-ios-full-auto.sh # Utilise ../VERSION
|
||
# ./deploy-ios-full-auto.sh 3.6.0 # Version spécifique
|
||
# ./deploy-ios-full-auto.sh 3.6.0 --skip-build # Skip Flutter build si déjà fait
|
||
|
||
set -euo pipefail
|
||
|
||
# =====================================
|
||
# Configuration
|
||
# =====================================
|
||
|
||
# Couleurs pour les messages
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
MAGENTA='\033[0;35m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Configuration Mac mini
|
||
MAC_MINI_HOST="minipi4" # Nom défini dans ~/.ssh/config
|
||
MAC_BASE_DIR="/Users/pierre/dev/geosector"
|
||
|
||
# Timestamp pour logs et archives
|
||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||
LOG_FILE="./logs/deploy-ios-${TIMESTAMP}.log"
|
||
mkdir -p ./logs
|
||
|
||
# Variables globales pour le rapport
|
||
STEP_START_TIME=0
|
||
TOTAL_START_TIME=$(date +%s)
|
||
ERRORS_COUNT=0
|
||
WARNINGS_COUNT=0
|
||
|
||
# =====================================
|
||
# Fonctions utilitaires
|
||
# =====================================
|
||
|
||
log() {
|
||
echo -e "$1" | tee -a "${LOG_FILE}"
|
||
}
|
||
|
||
log_step() {
|
||
STEP_START_TIME=$(date +%s)
|
||
log "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log "${CYAN}▶ $1${NC}"
|
||
log "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
}
|
||
|
||
log_substep() {
|
||
log "${MAGENTA} ➜ $1${NC}"
|
||
}
|
||
|
||
log_info() {
|
||
log "${BLUE}ℹ ${NC}$1"
|
||
}
|
||
|
||
log_success() {
|
||
local elapsed=$(($(date +%s) - STEP_START_TIME))
|
||
log "${GREEN}✓${NC} $1 ${CYAN}(${elapsed}s)${NC}"
|
||
}
|
||
|
||
log_warning() {
|
||
((WARNINGS_COUNT++))
|
||
log "${YELLOW}⚠ ${NC}$1"
|
||
}
|
||
|
||
log_error() {
|
||
((ERRORS_COUNT++))
|
||
log "${RED}✗${NC} $1"
|
||
}
|
||
|
||
log_fatal() {
|
||
log_error "$1"
|
||
log "\n${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log "${RED}DÉPLOIEMENT ÉCHOUÉ${NC}"
|
||
log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log_error "Consultez le log: ${LOG_FILE}"
|
||
exit 1
|
||
}
|
||
|
||
# Fonction pour exécuter une commande et capturer les erreurs
|
||
safe_exec() {
|
||
local cmd="$1"
|
||
local error_msg="$2"
|
||
|
||
if ! eval "$cmd" >> "${LOG_FILE}" 2>&1; then
|
||
log_fatal "$error_msg"
|
||
fi
|
||
}
|
||
|
||
# Fonction pour exécuter une commande SSH avec gestion d'erreurs
|
||
ssh_exec() {
|
||
local cmd="$1"
|
||
local error_msg="$2"
|
||
|
||
if ! ssh "$MAC_MINI_HOST" "$cmd" >> "${LOG_FILE}" 2>&1; then
|
||
log_fatal "$error_msg"
|
||
fi
|
||
}
|
||
|
||
# =====================================
|
||
# En-tête
|
||
# =====================================
|
||
|
||
clear
|
||
log "${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
|
||
log "${BLUE}║ ║${NC}"
|
||
log "${BLUE}║ ${GREEN}🍎 DÉPLOIEMENT iOS AUTOMATISÉ${BLUE} ║${NC}"
|
||
log "${BLUE}║ ${CYAN}GEOSECTOR - Full Automation${BLUE} ║${NC}"
|
||
log "${BLUE}║ ║${NC}"
|
||
log "${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
|
||
log ""
|
||
log_info "Démarrage: $(date '+%Y-%m-%d %H:%M:%S')"
|
||
log_info "Log file: ${LOG_FILE}"
|
||
log ""
|
||
|
||
# =====================================
|
||
# Étape 1 : Gestion de la version
|
||
# =====================================
|
||
|
||
log_step "ÉTAPE 1/8 : Gestion de la version"
|
||
|
||
# Déterminer la version à utiliser
|
||
if [ "${1:-}" != "" ] && [[ ! "${1}" =~ ^-- ]]; then
|
||
VERSION="$1"
|
||
log_info "Version fournie en argument: ${VERSION}"
|
||
else
|
||
# Lire depuis ../VERSION
|
||
if [ ! -f ../VERSION ]; then
|
||
log_fatal "Fichier ../VERSION introuvable et aucune version fournie"
|
||
fi
|
||
VERSION=$(cat ../VERSION | tr -d '\n\r ' | tr -d '[:space:]')
|
||
log_info "Version lue depuis ../VERSION: ${VERSION}"
|
||
fi
|
||
|
||
# Vérifier le format de version
|
||
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||
log_fatal "Format de version invalide: ${VERSION} (attendu: x.x.x)"
|
||
fi
|
||
|
||
# Calculer le build number
|
||
BUILD_NUMBER=$(echo $VERSION | tr -d '.')
|
||
FULL_VERSION="${VERSION}+${BUILD_NUMBER}"
|
||
|
||
log_success "Version configurée"
|
||
log_info " Version name: ${GREEN}${VERSION}${NC}"
|
||
log_info " Build number: ${GREEN}${BUILD_NUMBER}${NC}"
|
||
log_info " Full version: ${GREEN}${FULL_VERSION}${NC}"
|
||
|
||
# =====================================
|
||
# Étape 2 : Mise à jour pubspec.yaml
|
||
# =====================================
|
||
|
||
log_step "ÉTAPE 2/8 : Mise à jour pubspec.yaml"
|
||
|
||
# Backup du pubspec.yaml
|
||
cp pubspec.yaml pubspec.yaml.backup
|
||
|
||
# Mise à jour de la version
|
||
sed -i "s/^version: .*/version: $FULL_VERSION/" pubspec.yaml
|
||
|
||
# Vérifier la mise à jour
|
||
UPDATED_VERSION=$(grep "^version:" pubspec.yaml | sed 's/version: //' | tr -d ' ')
|
||
if [ "$UPDATED_VERSION" != "$FULL_VERSION" ]; then
|
||
log_fatal "Échec de la mise à jour de pubspec.yaml (attendu: $FULL_VERSION, obtenu: $UPDATED_VERSION)"
|
||
fi
|
||
|
||
log_success "pubspec.yaml mis à jour"
|
||
|
||
# =====================================
|
||
# Étape 3 : Préparation du projet
|
||
# =====================================
|
||
|
||
SKIP_BUILD=false
|
||
if [[ "${2:-}" == "--skip-build" ]]; then
|
||
SKIP_BUILD=true
|
||
log_warning "Mode --skip-build activé, Flutter build sera ignoré"
|
||
fi
|
||
|
||
if [ "$SKIP_BUILD" = false ]; then
|
||
log_step "ÉTAPE 3/8 : Préparation du projet Flutter"
|
||
|
||
log_substep "Configuration du cache local"
|
||
export PUB_CACHE="$PWD/.pub-cache-local"
|
||
export GRADLE_USER_HOME="$PWD/.gradle-local"
|
||
mkdir -p "$PUB_CACHE" "$GRADLE_USER_HOME"
|
||
log_info " Cache Pub: $PUB_CACHE"
|
||
log_info " Cache Gradle: $GRADLE_USER_HOME"
|
||
|
||
log_substep "Nettoyage du projet"
|
||
safe_exec "flutter clean" "Échec du nettoyage Flutter"
|
||
|
||
log_substep "Récupération des dépendances"
|
||
safe_exec "flutter pub get" "Échec de flutter pub get"
|
||
|
||
log_substep "Application du patch nfc_manager"
|
||
safe_exec "./fastlane/scripts/commun/fix-nfc-manager.sh" "Échec du patch nfc_manager"
|
||
|
||
log_substep "Application du patch permission_handler (si nécessaire)"
|
||
if [ -f "./fastlane/scripts/commun/fix-permission-handler.sh" ]; then
|
||
safe_exec "./fastlane/scripts/commun/fix-permission-handler.sh" "Échec du patch permission_handler"
|
||
fi
|
||
|
||
log_substep "Génération des fichiers Hive"
|
||
safe_exec "dart run build_runner build --delete-conflicting-outputs" "Échec de la génération de code"
|
||
|
||
log_success "Projet préparé (dépendances + patchs + génération de code)"
|
||
log_info " ⚠️ Build iOS sera fait sur le Mac mini via Fastlane"
|
||
else
|
||
log_step "ÉTAPE 3/8 : Préparation du projet (BUILD SKIPPED)"
|
||
|
||
log_substep "Configuration du cache local uniquement"
|
||
export PUB_CACHE="$PWD/.pub-cache-local"
|
||
export GRADLE_USER_HOME="$PWD/.gradle-local"
|
||
|
||
if [ ! -d "$PUB_CACHE" ]; then
|
||
log_warning "Cache local introuvable, le build pourrait échouer sur le Mac mini"
|
||
fi
|
||
|
||
log_success "Cache configuré (build Flutter ignoré)"
|
||
fi
|
||
|
||
# =====================================
|
||
# Étape 4 : Vérification de la connexion Mac mini
|
||
# =====================================
|
||
|
||
log_step "ÉTAPE 4/8 : Connexion au Mac mini"
|
||
|
||
log_substep "Test de connexion SSH à ${MAC_MINI_HOST}"
|
||
|
||
if ! ssh "$MAC_MINI_HOST" "echo 'Connection OK'" >> "${LOG_FILE}" 2>&1; then
|
||
log_fatal "Impossible de se connecter au Mac mini (${MAC_MINI_HOST})"
|
||
fi
|
||
|
||
log_success "Connexion SSH établie"
|
||
|
||
# Vérifier l'environnement Mac
|
||
log_substep "Vérification de l'environnement Mac"
|
||
MAC_INFO=$(ssh "$MAC_MINI_HOST" "sw_vers -productVersion && xcodebuild -version | head -1 && flutter --version | head -1" 2>/dev/null || echo "N/A")
|
||
log_info "$(echo "$MAC_INFO" | head -1 | xargs -I {} echo " macOS: {}")"
|
||
log_info "$(echo "$MAC_INFO" | sed -n '2p' | xargs -I {} echo " Xcode: {}")"
|
||
log_info "$(echo "$MAC_INFO" | sed -n '3p' | xargs -I {} echo " Flutter: {}")"
|
||
|
||
# =====================================
|
||
# Étape 5 : Transfert vers Mac mini
|
||
# =====================================
|
||
|
||
log_step "ÉTAPE 5/8 : Transfert du projet vers Mac mini"
|
||
|
||
DEST_DIR="${MAC_BASE_DIR}/app_${BUILD_NUMBER}"
|
||
|
||
log_substep "Création du dossier de destination: ${DEST_DIR}"
|
||
ssh_exec "mkdir -p ${DEST_DIR}" "Impossible de créer le dossier ${DEST_DIR} sur le Mac mini"
|
||
|
||
log_substep "Transfert rsync (peut prendre 2-5 minutes)"
|
||
TRANSFER_START=$(date +%s)
|
||
|
||
rsync -avz --progress \
|
||
--exclude='build/' \
|
||
--exclude='.dart_tool/' \
|
||
--exclude='ios/Pods/' \
|
||
--exclude='ios/.symlinks/' \
|
||
--exclude='macos/Pods/' \
|
||
--exclude='linux/flutter/ephemeral/' \
|
||
--exclude='windows/flutter/ephemeral/' \
|
||
--exclude='android/build/' \
|
||
--exclude='*.aab' \
|
||
--exclude='*.apk' \
|
||
--exclude='logs/' \
|
||
--exclude='*.log' \
|
||
./ "${MAC_MINI_HOST}:${DEST_DIR}/" >> "${LOG_FILE}" 2>&1 || log_fatal "Échec du transfert rsync"
|
||
|
||
TRANSFER_TIME=$(($(date +%s) - TRANSFER_START))
|
||
|
||
log_success "Transfert terminé"
|
||
log_info " Destination: ${DEST_DIR}"
|
||
log_info " Durée: ${TRANSFER_TIME}s"
|
||
|
||
# =====================================
|
||
# Étape 6 : Build et Archive avec Fastlane
|
||
# =====================================
|
||
|
||
log_step "ÉTAPE 6/8 : Build et Archive iOS avec Fastlane"
|
||
|
||
log_info "Cette étape peut prendre 15-25 minutes"
|
||
log_info "Fastlane va :"
|
||
log_info " 1. Nettoyer les artefacts"
|
||
log_info " 2. Installer les CocoaPods"
|
||
log_info " 3. Analyser le code"
|
||
log_info " 4. Build Flutter iOS"
|
||
log_info " 5. Archive Xcode (gym)"
|
||
log_info " 6. Export IPA"
|
||
log_info ""
|
||
log_substep "Lancement de: cd ${DEST_DIR} && fastlane ios build"
|
||
|
||
FASTLANE_START=$(date +%s)
|
||
|
||
# Créer un fichier temporaire pour capturer la sortie Fastlane
|
||
FASTLANE_LOG="/tmp/fastlane-ios-${TIMESTAMP}.log"
|
||
|
||
# Exécuter Fastlane en temps réel avec affichage des étapes importantes
|
||
ssh -t "$MAC_MINI_HOST" "cd ${DEST_DIR} && /opt/homebrew/bin/fastlane ios build" 2>&1 | tee -a "${LOG_FILE}" | tee "${FASTLANE_LOG}" | while IFS= read -r line; do
|
||
# Afficher les lignes importantes
|
||
if echo "$line" | grep -qE "(🧹|📦|🔧|🔍|🏗️|✓|✗|Error|error:|ERROR|Build succeeded|Build failed)"; then
|
||
echo -e "${CYAN} ${line}${NC}"
|
||
fi
|
||
done
|
||
|
||
# Vérifier le code de retour de Fastlane
|
||
FASTLANE_EXIT_CODE=${PIPESTATUS[0]}
|
||
FASTLANE_TIME=$(($(date +%s) - FASTLANE_START))
|
||
|
||
if [ $FASTLANE_EXIT_CODE -ne 0 ]; then
|
||
log_error "Fastlane a échoué (code: ${FASTLANE_EXIT_CODE})"
|
||
log_error "Analyse des erreurs..."
|
||
|
||
# Extraire les erreurs du log Fastlane
|
||
if [ -f "${FASTLANE_LOG}" ]; then
|
||
log ""
|
||
log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log "${RED}ERREURS DÉTECTÉES :${NC}"
|
||
log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
grep -i "error:\|Error:\|ERROR:\|❌\|✗" "${FASTLANE_LOG}" | head -20 | while IFS= read -r error_line; do
|
||
log "${RED} ${error_line}${NC}"
|
||
done
|
||
log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
fi
|
||
|
||
log_fatal "Build iOS échoué via Fastlane. Consultez ${FASTLANE_LOG} pour plus de détails."
|
||
fi
|
||
|
||
log_success "Build et Archive iOS réussis"
|
||
log_info " Durée totale Fastlane: ${FASTLANE_TIME}s ($((FASTLANE_TIME/60))m $((FASTLANE_TIME%60))s)"
|
||
|
||
# Vérifier que l'IPA existe
|
||
log_substep "Vérification de l'IPA généré"
|
||
IPA_EXISTS=$(ssh "$MAC_MINI_HOST" "test -f ${DEST_DIR}/build/ios/ipa/Runner.ipa && echo 'YES' || echo 'NO'")
|
||
|
||
if [ "$IPA_EXISTS" != "YES" ]; then
|
||
log_fatal "IPA non trouvé dans ${DEST_DIR}/build/ios/ipa/Runner.ipa"
|
||
fi
|
||
|
||
IPA_SIZE=$(ssh "$MAC_MINI_HOST" "du -h ${DEST_DIR}/build/ios/ipa/Runner.ipa | cut -f1")
|
||
log_info " IPA trouvé: ${GREEN}${IPA_SIZE}${NC}"
|
||
|
||
# =====================================
|
||
# Étape 7 : Upload vers TestFlight (optionnel)
|
||
# =====================================
|
||
|
||
log_step "ÉTAPE 7/8 : Upload vers TestFlight"
|
||
|
||
log ""
|
||
log_info "${YELLOW}Voulez-vous uploader l'IPA vers TestFlight maintenant ?${NC}"
|
||
log_info " [Y] Oui - Upload automatique via fastlane ios upload"
|
||
log_info " [N] Non - Je ferai l'upload manuellement plus tard"
|
||
log ""
|
||
|
||
read -p "$(echo -e ${CYAN}Votre choix [Y/n]: ${NC})" -n 1 -r UPLOAD_CHOICE
|
||
echo
|
||
log ""
|
||
|
||
if [[ $UPLOAD_CHOICE =~ ^[Yy]$ ]] || [ -z "$UPLOAD_CHOICE" ]; then
|
||
log_substep "Lancement de: fastlane ios upload"
|
||
log_info "Upload vers TestFlight (peut prendre 5-10 minutes)"
|
||
|
||
UPLOAD_START=$(date +%s)
|
||
|
||
ssh -t "$MAC_MINI_HOST" "cd ${DEST_DIR} && /opt/homebrew/bin/fastlane ios upload" 2>&1 | tee -a "${LOG_FILE}"
|
||
UPLOAD_EXIT_CODE=${PIPESTATUS[0]}
|
||
UPLOAD_TIME=$(($(date +%s) - UPLOAD_START))
|
||
|
||
if [ $UPLOAD_EXIT_CODE -ne 0 ]; then
|
||
log_error "Upload TestFlight échoué (code: ${UPLOAD_EXIT_CODE})"
|
||
log_warning "L'IPA est disponible sur le Mac mini, vous pouvez réessayer manuellement"
|
||
log_info " Commande: ssh $MAC_USER@$MAC_MINI_IP \"cd ${DEST_DIR} && fastlane ios upload\""
|
||
else
|
||
log_success "Upload TestFlight réussi"
|
||
log_info " Durée: ${UPLOAD_TIME}s"
|
||
log_info " URL: ${CYAN}https://appstoreconnect.apple.com${NC}"
|
||
fi
|
||
else
|
||
log_info "Upload ignoré. Pour uploader manuellement plus tard :"
|
||
log_info " ${CYAN}ssh $MAC_MINI_HOST \"cd ${DEST_DIR} && /opt/homebrew/bin/fastlane ios upload\"${NC}"
|
||
fi
|
||
|
||
# =====================================
|
||
# Étape 8 : Nettoyage et archivage
|
||
# =====================================
|
||
|
||
log_step "ÉTAPE 8/8 : Nettoyage et archivage"
|
||
|
||
log_substep "Voulez-vous archiver le dossier de build ?"
|
||
log_info " [Y] Oui - Créer une archive ${DEST_DIR}.tar.gz"
|
||
log_info " [N] Non - Garder le dossier tel quel (défaut)"
|
||
log ""
|
||
|
||
read -p "$(echo -e ${CYAN}Votre choix [y/N]: ${NC})" -n 1 -r ARCHIVE_CHOICE
|
||
echo
|
||
log ""
|
||
|
||
if [[ $ARCHIVE_CHOICE =~ ^[Yy]$ ]]; then
|
||
log_substep "Création de l'archive..."
|
||
ssh_exec "cd ${MAC_BASE_DIR} && tar -czf app_${BUILD_NUMBER}.tar.gz app_${BUILD_NUMBER}" \
|
||
"Échec de la création de l'archive"
|
||
|
||
ARCHIVE_SIZE=$(ssh "$MAC_MINI_HOST" "du -h ${MAC_BASE_DIR}/app_${BUILD_NUMBER}.tar.gz | cut -f1")
|
||
log_success "Archive créée"
|
||
log_info " Archive: ${MAC_BASE_DIR}/app_${BUILD_NUMBER}.tar.gz (${ARCHIVE_SIZE})"
|
||
|
||
log_substep "Suppression du dossier de build"
|
||
ssh_exec "rm -rf ${DEST_DIR}" "Échec de la suppression du dossier"
|
||
log_success "Dossier de build supprimé"
|
||
else
|
||
log_info "Dossier conservé: ${DEST_DIR}"
|
||
fi
|
||
|
||
# Restaurer le pubspec.yaml original (optionnel)
|
||
log_substep "Restauration de pubspec.yaml local"
|
||
mv pubspec.yaml.backup pubspec.yaml
|
||
log_info " pubspec.yaml local restauré à son état initial"
|
||
|
||
# =====================================
|
||
# Rapport final
|
||
# =====================================
|
||
|
||
TOTAL_TIME=$(($(date +%s) - TOTAL_START_TIME))
|
||
TOTAL_MINUTES=$((TOTAL_TIME / 60))
|
||
TOTAL_SECONDS=$((TOTAL_TIME % 60))
|
||
|
||
log ""
|
||
log "${GREEN}╔════════════════════════════════════════════════════════╗${NC}"
|
||
log "${GREEN}║ ║${NC}"
|
||
log "${GREEN}║ ✓ DÉPLOIEMENT iOS TERMINÉ AVEC SUCCÈS ║${NC}"
|
||
log "${GREEN}║ ║${NC}"
|
||
log "${GREEN}╚════════════════════════════════════════════════════════╝${NC}"
|
||
log ""
|
||
log "${CYAN}📊 RAPPORT DE DÉPLOIEMENT${NC}"
|
||
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log ""
|
||
log " ${BLUE}Version déployée:${NC} ${GREEN}${VERSION} (Build ${BUILD_NUMBER})${NC}"
|
||
log " ${BLUE}Destination:${NC} ${DEST_DIR}"
|
||
log " ${BLUE}IPA généré:${NC} ${GREEN}${IPA_SIZE}${NC}"
|
||
log " ${BLUE}Durée totale:${NC} ${GREEN}${TOTAL_MINUTES}m ${TOTAL_SECONDS}s${NC}"
|
||
log ""
|
||
if [ $WARNINGS_COUNT -gt 0 ]; then
|
||
log " ${YELLOW}⚠ Avertissements:${NC} ${WARNINGS_COUNT}"
|
||
fi
|
||
if [ $ERRORS_COUNT -gt 0 ]; then
|
||
log " ${RED}✗ Erreurs:${NC} ${ERRORS_COUNT}"
|
||
fi
|
||
log ""
|
||
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log ""
|
||
log "${BLUE}📱 PROCHAINES ÉTAPES${NC}"
|
||
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log ""
|
||
|
||
if [[ $UPLOAD_CHOICE =~ ^[Yy]$ ]] || [ -z "$UPLOAD_CHOICE" ]; then
|
||
if [ $UPLOAD_EXIT_CODE -eq 0 ]; then
|
||
log " 1. ${GREEN}✓${NC} IPA uploadé sur TestFlight"
|
||
log " 2. Accéder à App Store Connect:"
|
||
log " ${CYAN}https://appstoreconnect.apple.com${NC}"
|
||
log " 3. Attendre le traitement Apple (5-15 min)"
|
||
log " 4. Configurer la conformité export si demandée"
|
||
log " 5. Ajouter des testeurs internes"
|
||
log " 6. Installer via TestFlight sur iPhone"
|
||
else
|
||
log " 1. ${YELLOW}⚠${NC} Upload TestFlight a échoué"
|
||
log " 2. Réessayer manuellement:"
|
||
log " ${CYAN}ssh $MAC_USER@$MAC_MINI_IP \"cd ${DEST_DIR} && fastlane ios upload\"${NC}"
|
||
fi
|
||
else
|
||
log " 1. L'IPA est prêt sur le Mac mini"
|
||
log " 2. Pour uploader vers TestFlight:"
|
||
log " ${CYAN}ssh $MAC_USER@$MAC_MINI_IP \"cd ${DEST_DIR} && fastlane ios upload\"${NC}"
|
||
log " 3. Ou distribuer l'IPA manuellement via Xcode"
|
||
fi
|
||
|
||
log ""
|
||
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
log ""
|
||
log " ${BLUE}Log complet:${NC} ${LOG_FILE}"
|
||
log " ${BLUE}Fin:${NC} $(date '+%Y-%m-%d %H:%M:%S')"
|
||
log ""
|
||
|
||
# Nettoyer le log Fastlane temporaire
|
||
rm -f "${FASTLANE_LOG}"
|
||
|
||
exit 0
|