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>
This commit is contained in:
381
app/fastlane/Fastfile
Normal file
381
app/fastlane/Fastfile
Normal file
@@ -0,0 +1,381 @@
|
||||
# Fastfile pour GEOSECTOR Flutter App
|
||||
# Version: 2.0
|
||||
# Date: 2025-10-26
|
||||
# Auteur: Pierre (avec l'aide de Claude)
|
||||
#
|
||||
# Usage depuis le Mac mini (après transfert depuis Debian):
|
||||
# cd /Users/pierre/dev/geosector/app_346
|
||||
# fastlane android build # Build seulement (test local)
|
||||
# fastlane android release # Build + Upload vers Play Store
|
||||
# fastlane ios build # Build iOS seulement (test local)
|
||||
# fastlane ios release # Build + Upload vers TestFlight
|
||||
|
||||
default_platform(:android)
|
||||
|
||||
# =============================================================================
|
||||
# ANDROID
|
||||
# =============================================================================
|
||||
|
||||
platform :android do
|
||||
|
||||
desc "Build Android AAB (bundle) en mode release - sans upload"
|
||||
lane :build do
|
||||
UI.header("🤖 Build Android Bundle")
|
||||
|
||||
# Étape 1 : Nettoyer le projet
|
||||
UI.message("🧹 [1/6] Nettoyage du projet...")
|
||||
sh("cd .. && flutter clean")
|
||||
UI.success("Projet nettoyé")
|
||||
|
||||
# Étape 2 : Récupérer les dépendances
|
||||
UI.message("📦 [2/6] Récupération des dépendances...")
|
||||
sh("cd .. && flutter pub get")
|
||||
UI.success("Dépendances récupérées")
|
||||
|
||||
# Étape 3 : Patch nfc_manager
|
||||
UI.message("🔧 [3/6] Application du patch nfc_manager...")
|
||||
sh("cd .. && ./fastlane/scripts/commun/fix-nfc-manager.sh")
|
||||
UI.success("Patch nfc_manager appliqué")
|
||||
|
||||
# Étape 4 : Analyser le code (non bloquant)
|
||||
UI.message("🔍 [4/6] Analyse du code...")
|
||||
begin
|
||||
sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
|
||||
UI.success("Analyse du code terminée")
|
||||
rescue => ex
|
||||
UI.important("⚠️ Des warnings détectés, mais on continue...")
|
||||
end
|
||||
|
||||
# Étape 5 : Build du bundle AAB
|
||||
UI.message("🏗️ [5/6] Build du bundle Android (RELEASE)...")
|
||||
sh("cd .. && flutter build appbundle --release")
|
||||
UI.success("Bundle AAB généré")
|
||||
|
||||
# Étape 6 : Copier le bundle avec version
|
||||
UI.message("📋 [6/6] Copie du bundle avec version...")
|
||||
version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
|
||||
version_code = version_info.split('+').last
|
||||
final_name = "geosector-#{version_code}.aab"
|
||||
|
||||
sh("cd .. && cp build/app/outputs/bundle/release/app-release.aab #{final_name}")
|
||||
|
||||
bundle_size = sh("cd .. && du -h #{final_name} | cut -f1").strip
|
||||
|
||||
UI.success("✅ Build Android terminé avec succès!")
|
||||
UI.success("📦 Bundle: #{final_name}")
|
||||
UI.success("📊 Taille: #{bundle_size}")
|
||||
end
|
||||
|
||||
desc "Build Android AAB + Upload vers Google Play Console (Internal Testing)"
|
||||
lane :release do
|
||||
UI.header("🚀 Build & Deploy Android vers Play Store")
|
||||
|
||||
# Étape 1 : Nettoyer le projet
|
||||
UI.message("🧹 [1/7] Nettoyage du projet...")
|
||||
sh("cd .. && flutter clean")
|
||||
UI.success("Projet nettoyé")
|
||||
|
||||
# Étape 2 : Récupérer les dépendances
|
||||
UI.message("📦 [2/7] Récupération des dépendances...")
|
||||
sh("cd .. && flutter pub get")
|
||||
UI.success("Dépendances récupérées")
|
||||
|
||||
# Étape 3 : Patch nfc_manager
|
||||
UI.message("🔧 [3/7] Application du patch nfc_manager...")
|
||||
sh("cd .. && ./fastlane/scripts/commun/fix-nfc-manager.sh")
|
||||
UI.success("Patch nfc_manager appliqué")
|
||||
|
||||
# Étape 4 : Analyser le code (non bloquant)
|
||||
UI.message("🔍 [4/7] Analyse du code...")
|
||||
begin
|
||||
sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
|
||||
UI.success("Analyse du code terminée")
|
||||
rescue => ex
|
||||
UI.important("⚠️ Des warnings détectés, mais on continue...")
|
||||
end
|
||||
|
||||
# Étape 5 : Build du bundle AAB
|
||||
UI.message("🏗️ [5/7] Build du bundle Android (RELEASE)...")
|
||||
sh("cd .. && flutter build appbundle --release")
|
||||
UI.success("Bundle AAB généré")
|
||||
|
||||
# Étape 6 : Récupérer les informations de version
|
||||
version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
|
||||
version_name = version_info.split('+').first
|
||||
version_code = version_info.split('+').last
|
||||
|
||||
UI.message("📋 Version: #{version_name} (#{version_code})")
|
||||
|
||||
# Étape 7 : Upload vers Google Play Console
|
||||
UI.message("📤 [6/7] Upload vers Google Play Console...")
|
||||
|
||||
upload_to_play_store(
|
||||
json_key: '../android/google-play-api-key.json', # Credentials Google Play API
|
||||
track: 'internal', # Track: internal, alpha, beta, ou production
|
||||
aab: '../build/app/outputs/bundle/release/app-release.aab',
|
||||
skip_upload_apk: true, # On n'upload que l'AAB
|
||||
skip_upload_metadata: true, # On ne met pas à jour les métadonnées
|
||||
skip_upload_images: true, # On ne met pas à jour les images
|
||||
skip_upload_screenshots: true, # On ne met pas à jour les screenshots
|
||||
release_status: 'completed', # completed = publié immédiatement sur le track
|
||||
version_code: version_code.to_i, # Version code explicite
|
||||
package_name: 'fr.geosector.app3' # Package name explicite
|
||||
)
|
||||
|
||||
UI.success("✅ Déploiement Android terminé avec succès!")
|
||||
UI.success("📦 Version: #{version_name} (Build #{version_code})")
|
||||
UI.success("🎯 Track: Internal Testing")
|
||||
UI.success("🌐 URL: https://play.google.com/console")
|
||||
end
|
||||
|
||||
desc "Upload un AAB existant vers Google Play Console"
|
||||
lane :upload do
|
||||
UI.header("📤 Upload AAB vers Play Store")
|
||||
|
||||
# Vérifier que le bundle existe
|
||||
aab_path = '../build/app/outputs/bundle/release/app-release.aab'
|
||||
|
||||
if File.exist?(aab_path)
|
||||
# Récupérer la version
|
||||
version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
|
||||
version_code = version_info.split('+').last
|
||||
|
||||
UI.message("📦 Upload du bundle existant...")
|
||||
|
||||
upload_to_play_store(
|
||||
json_key: '../android/google-play-api-key.json',
|
||||
track: 'internal',
|
||||
aab: aab_path,
|
||||
skip_upload_apk: true,
|
||||
skip_upload_metadata: true,
|
||||
skip_upload_images: true,
|
||||
skip_upload_screenshots: true,
|
||||
release_status: 'completed',
|
||||
version_code: version_code.to_i,
|
||||
package_name: 'fr.geosector.app3'
|
||||
)
|
||||
|
||||
UI.success("✅ Upload terminé!")
|
||||
else
|
||||
UI.user_error!("❌ Bundle introuvable: #{aab_path}")
|
||||
UI.message("💡 Lancez d'abord: fastlane android build")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# =============================================================================
|
||||
# iOS
|
||||
# =============================================================================
|
||||
|
||||
platform :ios do
|
||||
|
||||
desc "Build iOS IPA en mode release - sans upload"
|
||||
lane :build do
|
||||
UI.header("🍎 Build iOS IPA")
|
||||
|
||||
# Étape 1 : Vérifier le cache local (préparé sur Debian)
|
||||
UI.message("📦 [1/6] Vérification du cache local...")
|
||||
|
||||
cache_path = File.expand_path("../.pub-cache-local")
|
||||
if !Dir.exist?(cache_path)
|
||||
UI.user_error!("❌ Cache local introuvable: #{cache_path}")
|
||||
UI.message("💡 Exécutez './deploy-app.sh' sur Debian pour préparer le projet")
|
||||
end
|
||||
|
||||
ENV['PUB_CACHE'] = cache_path
|
||||
ENV['GRADLE_USER_HOME'] = File.expand_path("../.gradle-local")
|
||||
|
||||
UI.success("Cache local configuré: #{cache_path}")
|
||||
UI.important("⚠️ flutter pub get et patchs déjà appliqués sur Debian")
|
||||
|
||||
# Étape 2 : Nettoyer les artefacts de build
|
||||
UI.message("🧹 [2/6] Nettoyage des artefacts...")
|
||||
sh("cd .. && rm -rf build .dart_tool ios/Pods ios/.symlinks")
|
||||
UI.success("Artefacts nettoyés")
|
||||
|
||||
# Étape 3 : Installation des pods
|
||||
UI.message("📦 [3/6] Installation des CocoaPods...")
|
||||
sh("cd ../ios && pod install")
|
||||
UI.success("CocoaPods installés")
|
||||
|
||||
# Étape 4 : Analyser le code (non bloquant)
|
||||
UI.message("🔍 [4/6] Analyse du code...")
|
||||
begin
|
||||
sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
|
||||
UI.success("Analyse du code terminée")
|
||||
rescue => ex
|
||||
UI.important("⚠️ Des warnings détectés, mais on continue...")
|
||||
end
|
||||
|
||||
# Étape 5 : Build Flutter iOS
|
||||
UI.message("🏗️ [5/6] Build Flutter iOS (RELEASE)...")
|
||||
sh("cd .. && flutter build ios --release --no-codesign")
|
||||
UI.success("Build Flutter iOS généré")
|
||||
|
||||
# Étape 6 : Archive Xcode (gym)
|
||||
UI.message("📦 [6/6] Archive Xcode et export IPA...")
|
||||
|
||||
build_ios_app(
|
||||
workspace: "./Runner.xcworkspace",
|
||||
scheme: "Runner",
|
||||
export_method: "app-store",
|
||||
export_options: {
|
||||
method: "app-store",
|
||||
teamID: "6WT84NWCTC",
|
||||
uploadBitcode: false,
|
||||
uploadSymbols: true,
|
||||
compileBitcode: false,
|
||||
signingStyle: "automatic",
|
||||
destination: "export",
|
||||
provisioningProfiles: {
|
||||
"fr.geosector.app3" => "match AppStore fr.geosector.app3"
|
||||
}
|
||||
},
|
||||
output_directory: "../build/ios/ipa",
|
||||
output_name: "Runner.ipa",
|
||||
clean: false,
|
||||
skip_profile_detection: true
|
||||
)
|
||||
|
||||
UI.success("IPA généré")
|
||||
|
||||
# Afficher les informations de version
|
||||
version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
|
||||
ipa_size = sh("cd .. && du -h build/ios/ipa/Runner.ipa | cut -f1").strip
|
||||
|
||||
UI.success("✅ Build iOS terminé avec succès!")
|
||||
UI.success("📦 IPA: build/ios/ipa/Runner.ipa")
|
||||
UI.success("📊 Version: #{version_info}")
|
||||
UI.success("📊 Taille: #{ipa_size}")
|
||||
end
|
||||
|
||||
desc "Build iOS IPA + Upload vers TestFlight"
|
||||
lane :release do
|
||||
UI.header("🚀 Build & Deploy iOS vers TestFlight")
|
||||
|
||||
# Étape 1 : Vérifier le cache local (préparé sur Debian)
|
||||
UI.message("📦 [1/7] Vérification du cache local...")
|
||||
|
||||
cache_path = File.expand_path("../.pub-cache-local")
|
||||
if !Dir.exist?(cache_path)
|
||||
UI.user_error!("❌ Cache local introuvable: #{cache_path}")
|
||||
UI.message("💡 Exécutez './deploy-app.sh' sur Debian pour préparer le projet")
|
||||
end
|
||||
|
||||
ENV['PUB_CACHE'] = cache_path
|
||||
ENV['GRADLE_USER_HOME'] = File.expand_path("../.gradle-local")
|
||||
|
||||
UI.success("Cache local configuré: #{cache_path}")
|
||||
UI.important("⚠️ flutter pub get et patchs déjà appliqués sur Debian")
|
||||
|
||||
# Étape 2 : Nettoyer les artefacts de build
|
||||
UI.message("🧹 [2/7] Nettoyage des artefacts...")
|
||||
sh("cd .. && rm -rf build .dart_tool ios/Pods ios/.symlinks")
|
||||
UI.success("Artefacts nettoyés")
|
||||
|
||||
# Étape 3 : Installation des pods
|
||||
UI.message("📦 [3/7] Installation des CocoaPods...")
|
||||
sh("cd ../ios && pod install")
|
||||
UI.success("CocoaPods installés")
|
||||
|
||||
# Étape 4 : Récupérer les informations de version
|
||||
version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
|
||||
version_name = version_info.split('+').first
|
||||
version_code = version_info.split('+').last
|
||||
|
||||
UI.message("📋 Version: #{version_name} (#{version_code})")
|
||||
|
||||
# Étape 5 : Analyser le code (non bloquant)
|
||||
UI.message("🔍 [4/7] Analyse du code...")
|
||||
begin
|
||||
sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
|
||||
UI.success("Analyse du code terminée")
|
||||
rescue => ex
|
||||
UI.important("⚠️ Des warnings détectés, mais on continue...")
|
||||
end
|
||||
|
||||
# Étape 6 : Build Flutter iOS
|
||||
UI.message("🏗️ [5/7] Build Flutter iOS (RELEASE)...")
|
||||
sh("cd .. && flutter build ios --release --no-codesign")
|
||||
UI.success("Build Flutter iOS généré")
|
||||
|
||||
# Étape 7 : Archive Xcode
|
||||
UI.message("📦 [6/7] Archive Xcode...")
|
||||
|
||||
build_ios_app(
|
||||
workspace: "./Runner.xcworkspace",
|
||||
scheme: "Runner",
|
||||
export_method: "app-store",
|
||||
export_options: {
|
||||
method: "app-store",
|
||||
teamID: "6WT84NWCTC",
|
||||
uploadBitcode: false,
|
||||
uploadSymbols: true,
|
||||
compileBitcode: false,
|
||||
signingStyle: "automatic",
|
||||
provisioningProfiles: {
|
||||
"fr.geosector.app3" => "match AppStore fr.geosector.app3"
|
||||
}
|
||||
},
|
||||
output_directory: "../build/ios/ipa",
|
||||
output_name: "Runner.ipa",
|
||||
clean: false,
|
||||
skip_profile_detection: true
|
||||
)
|
||||
|
||||
UI.success("IPA généré")
|
||||
|
||||
# Étape 7 : Upload vers TestFlight
|
||||
UI.message("📤 [7/7] Upload vers TestFlight...")
|
||||
|
||||
upload_to_testflight(
|
||||
apple_id: "contact@d6soft.com",
|
||||
app_identifier: "fr.geosector.app3",
|
||||
team_id: "6WT84NWCTC",
|
||||
ipa: "../build/ios/ipa/Runner.ipa",
|
||||
skip_waiting_for_build_processing: true,
|
||||
skip_submission: true,
|
||||
distribute_external: false
|
||||
)
|
||||
|
||||
UI.success("✅ Déploiement iOS terminé avec succès!")
|
||||
UI.success("📦 Version: #{version_name} (Build #{version_code})")
|
||||
UI.success("🎯 Track: TestFlight (Internal)")
|
||||
UI.success("🌐 URL: https://appstoreconnect.apple.com")
|
||||
end
|
||||
|
||||
desc "Upload un IPA existant vers TestFlight"
|
||||
lane :upload do
|
||||
UI.header("📤 Upload IPA vers TestFlight")
|
||||
|
||||
# Vérifier que l'IPA existe
|
||||
ipa_path = '../build/ios/ipa/Runner.ipa'
|
||||
|
||||
if File.exist?(ipa_path)
|
||||
# Récupérer la version
|
||||
version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
|
||||
version_name = version_info.split('+').first
|
||||
version_code = version_info.split('+').last
|
||||
|
||||
UI.message("📦 Upload de l'IPA existant...")
|
||||
|
||||
upload_to_testflight(
|
||||
apple_id: "contact@d6soft.com",
|
||||
app_identifier: "fr.geosector.app3",
|
||||
team_id: "6WT84NWCTC",
|
||||
ipa: ipa_path,
|
||||
skip_waiting_for_build_processing: true,
|
||||
skip_submission: true,
|
||||
distribute_external: false
|
||||
)
|
||||
|
||||
UI.success("✅ Upload terminé!")
|
||||
UI.success("📦 Version: #{version_name} (Build #{version_code})")
|
||||
else
|
||||
UI.user_error!("❌ IPA introuvable: #{ipa_path}")
|
||||
UI.message("💡 Lancez d'abord: fastlane ios build")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user