#!/bin/bash # Script de génération du bundle Android pour GEOSECTOR # Usage: ./android.sh set -e # Arrêter le script en cas d'erreur # Couleurs pour les messages RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Fonction pour afficher les messages print_message() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } # Fonction pour gérer les erreurs handle_error() { print_error "Une erreur est survenue lors de l'exécution de la commande" print_error "Ligne $1" exit 1 } # Trap pour capturer les erreurs trap 'handle_error $LINENO' ERR # Vérifier que nous sommes dans le bon dossier if [ ! -f "pubspec.yaml" ]; then print_error "Ce script doit être exécuté depuis le dossier racine de l'application Flutter" print_error "Fichier pubspec.yaml introuvable" exit 1 fi print_message "=========================================" print_message " GEOSECTOR - Génération Bundle Android" print_message "=========================================" echo # Vérifier que Flutter est installé if ! command -v flutter &> /dev/null; then print_error "Flutter n'est pas installé ou n'est pas dans le PATH" exit 1 fi # Étape 0 : Synchroniser la version depuis ../VERSION print_message "Étape 0/5 : Synchronisation de la version..." echo VERSION_FILE="../VERSION" if [ ! -f "$VERSION_FILE" ]; then print_error "Fichier VERSION introuvable : $VERSION_FILE" exit 1 fi # Lire la version depuis le fichier (enlever espaces/retours à la ligne) VERSION_NUMBER=$(cat "$VERSION_FILE" | tr -d '\n\r ' | tr -d '[:space:]') if [ -z "$VERSION_NUMBER" ]; then print_error "Le fichier VERSION est vide" exit 1 fi print_message "Version lue depuis $VERSION_FILE : $VERSION_NUMBER" # Calculer le versionCode (supprimer les points) VERSION_CODE=$(echo $VERSION_NUMBER | tr -d '.') if [ -z "$VERSION_CODE" ]; then print_error "Impossible de calculer le versionCode" exit 1 fi print_message "Version code calculé : $VERSION_CODE" # Mettre à jour pubspec.yaml print_message "Mise à jour de pubspec.yaml..." sed -i.bak "s/^version:.*/version: $VERSION_NUMBER+$VERSION_CODE/" pubspec.yaml # Vérifier que la mise à jour a réussi UPDATED_VERSION=$(grep "^version:" pubspec.yaml | sed 's/version: //') if [ "$UPDATED_VERSION" != "$VERSION_NUMBER+$VERSION_CODE" ]; then print_error "Échec de la mise à jour de pubspec.yaml" print_error "Attendu : $VERSION_NUMBER+$VERSION_CODE" print_error "Obtenu : $UPDATED_VERSION" exit 1 fi print_success "pubspec.yaml mis à jour : version: $VERSION_NUMBER+$VERSION_CODE" print_message "build.gradle.kts se synchronisera automatiquement via Flutter Gradle Plugin" echo # Récupérer la version finale pour l'affichage VERSION="$VERSION_NUMBER-$VERSION_CODE" print_message "Version finale : $VERSION" print_message "Version code : $VERSION_CODE" echo # Demander le mode Debug ou Release print_message "=========================================" print_message " MODE DE BUILD" print_message "=========================================" echo print_message "Choisissez le mode de build :" echo print_message " ${YELLOW}[D]${NC} Debug" print_message " ✓ Installation rapide via ADB" print_message " ✓ Hot reload possible" print_message " ✓ Logs complets" print_message " ⚠ Tap to Pay simulé uniquement" print_message " ⚠ Performance non optimisée" echo print_message " ${GREEN}[R]${NC} Release (recommandé)" print_message " ✓ APK/AAB optimisé" print_message " ✓ Tap to Pay réel en production" print_message " ✓ Performance maximale" echo read -p "Votre choix (D/R) [défaut: R] : " -n 1 -r BUILD_TYPE echo echo # Définir le flag de build et le suffixe pour les noms de fichiers BUILD_MODE_FLAG="--release" MODE_SUFFIX="release" SKIP_R8_CHOICE=false if [[ $BUILD_TYPE =~ ^[Dd]$ ]]; then BUILD_MODE_FLAG="--debug" MODE_SUFFIX="debug" SKIP_R8_CHOICE=true print_success "Mode Debug sélectionné" echo print_warning "Attention : Tap to Pay ne fonctionnera qu'en mode simulé" echo # En mode debug, pas de choix R8 ni de vérification keystore USE_R8=false COPY_DEBUG_FILES=false else print_success "Mode Release sélectionné" echo fi # Demander le mode R8 SEULEMENT si Release if [ "$SKIP_R8_CHOICE" = false ]; then print_message "=========================================" print_message " OPTIMISATION RELEASE" print_message "=========================================" echo print_message "Choisissez le niveau d'optimisation :" echo print_message " ${GREEN}[A]${NC} Production - R8/ProGuard activé" print_message " ✓ Taille réduite (~30-40%)" print_message " ✓ Code obscurci (sécurité)" print_message " ✓ Génère mapping.txt pour débogage" print_message " ✓ Génère symboles natifs" echo print_message " ${YELLOW}[B]${NC} Test interne - Sans R8/ProGuard (défaut)" print_message " ✓ Build plus rapide" print_message " ✓ Pas d'obscurcissement (débogage facile)" print_message " ⚠ Taille plus importante" print_message " ⚠ Avertissements Google Play Console" echo read -p "Votre choix (A/B) [défaut: B] : " -n 1 -r BUILD_MODE echo echo # Définir les variables selon le choix USE_R8=false COPY_DEBUG_FILES=false if [[ $BUILD_MODE =~ ^[Aa]$ ]]; then USE_R8=true COPY_DEBUG_FILES=true print_success "Mode Production sélectionné - R8/ProGuard activé" else print_success "Mode Test interne sélectionné - R8/ProGuard désactivé" fi echo fi # Vérifier la présence du keystore SEULEMENT si Release if [ "$SKIP_R8_CHOICE" = false ]; then if [ ! -f "android/app/geosector2025.jks" ]; then print_error "Fichier keystore introuvable : android/app/geosector2025.jks" exit 1 fi # Vérifier la présence du fichier key.properties if [ ! -f "android/key.properties" ]; then print_error "Fichier key.properties introuvable" print_error "Ce fichier est nécessaire pour signer l'application" exit 1 fi print_success "Configuration de signature vérifiée" echo fi # Activer R8 si demandé (modification temporaire du build.gradle.kts) GRADLE_FILE="android/app/build.gradle.kts" GRADLE_BACKUP="android/app/build.gradle.kts.backup" if [ "$USE_R8" = true ]; then print_message "Activation de R8/ProGuard dans build.gradle.kts..." # Créer une sauvegarde cp "$GRADLE_FILE" "$GRADLE_BACKUP" # Activer minifyEnabled et shrinkResources sed -i.tmp 's/isMinifyEnabled = false/isMinifyEnabled = true/' "$GRADLE_FILE" sed -i.tmp 's/isShrinkResources = false/isShrinkResources = true/' "$GRADLE_FILE" # Nettoyer les fichiers temporaires de sed rm -f "${GRADLE_FILE}.tmp" print_success "R8/ProGuard activé temporairement" echo fi # Étape 1 : Nettoyer le projet print_message "Étape 1/5 : Nettoyage du projet..." flutter clean if [ $? -eq 0 ]; then print_success "Projet nettoyé" else print_error "Échec du nettoyage du projet" exit 1 fi echo # Étape 2 : Récupérer les dépendances print_message "Étape 2/5 : Récupération des dépendances..." flutter pub get if [ $? -eq 0 ]; then print_success "Dépendances récupérées" else print_error "Échec de la récupération des dépendances" exit 1 fi echo # Étape 3 : Analyser le code (optionnel mais recommandé) print_message "Étape 3/5 : Analyse du code Dart..." flutter analyze --no-fatal-infos --no-fatal-warnings || { print_warning "Des avertissements ont été détectés dans le code" read -p "Voulez-vous continuer malgré les avertissements ? (y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then print_message "Génération annulée par l'utilisateur" exit 0 fi } print_success "Analyse du code terminée" echo # Étape 4 : Générer le bundle print_message "Étape 4/5 : Génération du bundle Android..." print_message "Cette opération peut prendre plusieurs minutes..." flutter build appbundle $BUILD_MODE_FLAG if [ $? -eq 0 ]; then print_success "Bundle généré avec succès" else print_error "Échec de la génération du bundle" exit 1 fi echo # Restaurer le build.gradle.kts original si modifié if [ "$USE_R8" = true ] && [ -f "$GRADLE_BACKUP" ]; then print_message "Restauration du build.gradle.kts original..." mv "$GRADLE_BACKUP" "$GRADLE_FILE" print_success "Fichier restauré" echo fi # Vérifier que le bundle a été créé BUNDLE_PATH="build/app/outputs/bundle/$MODE_SUFFIX/app-$MODE_SUFFIX.aab" if [ ! -f "$BUNDLE_PATH" ]; then print_error "Bundle introuvable à l'emplacement attendu : $BUNDLE_PATH" exit 1 fi # Copier le bundle à la racine avec le nouveau nom FINAL_NAME="geosector-$VERSION_CODE-$MODE_SUFFIX.aab" print_message "Copie du bundle vers : $FINAL_NAME" cp "$BUNDLE_PATH" "$FINAL_NAME" if [ -f "$FINAL_NAME" ]; then print_success "Bundle copié avec succès" # Afficher la taille du fichier FILE_SIZE=$(du -h "$FINAL_NAME" | cut -f1) print_message "Taille du bundle : $FILE_SIZE" else print_error "Échec de la copie du bundle" exit 1 fi # Copier les fichiers de débogage si Option A sélectionnée if [ "$COPY_DEBUG_FILES" = true ]; then echo print_message "Copie des fichiers de débogage pour Google Play Console..." # Créer un dossier de release RELEASE_DIR="release-$VERSION_CODE" mkdir -p "$RELEASE_DIR" # Copier le bundle cp "$FINAL_NAME" "$RELEASE_DIR/" # Copier le fichier mapping.txt (R8/ProGuard) MAPPING_FILE="build/app/outputs/mapping/release/mapping.txt" if [ -f "$MAPPING_FILE" ]; then cp "$MAPPING_FILE" "$RELEASE_DIR/mapping.txt" print_success "Fichier mapping.txt copié" else print_warning "Fichier mapping.txt introuvable (peut être normal)" fi # Copier les symboles natifs SYMBOLS_ZIP="build/app/intermediates/merged_native_libs/release/out/lib" if [ -d "$SYMBOLS_ZIP" ]; then # Créer une archive des symboles cd build/app/intermediates/merged_native_libs/release/out zip -r "../../../../../../$RELEASE_DIR/native-symbols.zip" lib/ cd - > /dev/null print_success "Symboles natifs archivés" else print_warning "Symboles natifs introuvables (peut être normal)" fi print_success "Fichiers de débogage copiés dans : $RELEASE_DIR/" echo print_message "Pour uploader sur Google Play Console :" print_message "1. Bundle : $RELEASE_DIR/$FINAL_NAME" print_message "2. Mapping : $RELEASE_DIR/mapping.txt" print_message "3. Symboles : $RELEASE_DIR/native-symbols.zip" fi echo print_message "=========================================" print_success " GÉNÉRATION TERMINÉE AVEC SUCCÈS !" print_message "=========================================" echo print_message "Bundle généré : ${GREEN}$FINAL_NAME${NC}" print_message "Version : $VERSION" print_message "Chemin : $(pwd)/$FINAL_NAME" if [ "$BUILD_MODE_FLAG" = "--debug" ]; then echo print_message "Mode : ${YELLOW}Debug${NC}" print_message "⚠ Tap to Pay simulé uniquement" print_message "✓ Logs complets disponibles" echo print_message "Prochaines étapes :" print_message "1. Installer l'APK sur l'appareil (proposé ci-dessous)" print_message "2. Tester l'application avec adb logcat" print_message "3. Pour Tap to Pay réel, relancer en mode Release" elif [ "$USE_R8" = true ]; then echo print_message "Mode : ${GREEN}Release - Production (R8/ProGuard activé)${NC}" print_message "Dossier release : ${GREEN}$RELEASE_DIR/${NC}" echo print_message "Prochaines étapes :" print_message "1. Tester le bundle sur un appareil Android" print_message "2. Uploader le bundle sur Google Play Console" print_message "3. Uploader mapping.txt et native-symbols.zip" print_message "4. Soumettre pour review" else echo print_message "Mode : ${GREEN}Release${NC} - ${YELLOW}Test interne (R8/ProGuard désactivé)${NC}" print_warning "Avertissements attendus sur Google Play Console" echo print_message "Prochaines étapes :" print_message "1. Tester le bundle sur un appareil Android" print_message "2. Uploader sur Google Play Console (test interne)" print_message "3. Pour production, relancer avec Option A" fi echo # Optionnel : Générer aussi l'APK read -p "Voulez-vous aussi générer l'APK pour des tests ? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then print_message "Génération de l'APK..." flutter build apk $BUILD_MODE_FLAG if [ $? -eq 0 ]; then APK_PATH="build/app/outputs/flutter-apk/app-$MODE_SUFFIX.apk" if [ -f "$APK_PATH" ]; then APK_NAME="geosector-$VERSION_CODE-$MODE_SUFFIX.apk" cp "$APK_PATH" "$APK_NAME" print_success "APK généré : $APK_NAME" # Afficher la taille de l'APK APK_SIZE=$(du -h "$APK_NAME" | cut -f1) print_message "Taille de l'APK : $APK_SIZE" # Si mode Debug, proposer installation automatique if [ "$BUILD_MODE_FLAG" = "--debug" ]; then echo read -p "Installer l'APK debug sur l'appareil connecté ? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then print_message "Installation sur l'appareil..." adb install -r "$APK_NAME" if [ $? -eq 0 ]; then print_success "APK installé avec succès" # Proposer de lancer l'app read -p "Lancer l'application ? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then adb shell am start -n fr.geosector.app3/.MainActivity if [ $? -eq 0 ]; then print_success "Application lancée" else print_warning "Impossible de lancer l'application" fi fi else print_error "Échec de l'installation" print_message "Vérifiez qu'un appareil est bien connecté : adb devices" fi fi fi fi else print_warning "Échec de la génération de l'APK (le bundle a été créé avec succès)" fi fi echo print_success "Script terminé !"