Deployment Guide - utourismboard/explore-uganda-application-documentation GitHub Wiki
- Deployment Overview
- Environment Setup
- Build Process
- Release Management
- Monitoring
- Rollback Procedures
graph LR
    A[Development] --> B[Staging]
    B --> C[Production]
    
    style A fill:#f9f,stroke:#333
    style B fill:#bbf,stroke:#333
    style C fill:#bfb,stroke:#333
    // lib/config/environment.dart
enum Environment {
  development,
  staging,
  production,
}
class EnvironmentConfig {
  static const Environment environment = String.fromEnvironment(
    'ENVIRONMENT',
    defaultValue: 'development',
  ) as Environment;
  
  static const Map<Environment, String> apiBaseUrls = {
    Environment.development: 'https://dev-api.exploreuganda.app/v1',
    Environment.staging: 'https://staging-api.exploreuganda.app/v1',
    Environment.production: 'https://api.exploreuganda.app/v1',
  };
  
  static const Map<Environment, String> firebaseProjects = {
    Environment.development: 'explore-uganda-dev',
    Environment.staging: 'explore-uganda-staging',
    Environment.production: 'explore-uganda-prod',
  };
}# Set up development environment
flutter pub get
flutter pub run build_runner build
flutter run --dart-define=ENVIRONMENT=development# Set up staging environment
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs
flutter run --dart-define=ENVIRONMENT=staging# Set up production environment
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs
flutter run --dart-define=ENVIRONMENT=production# Generate Android release
flutter build apk --release --dart-define=ENVIRONMENT=production
# Generate Android App Bundle
flutter build appbundle --release --dart-define=ENVIRONMENT=production# Generate iOS release
flutter build ios --release --dart-define=ENVIRONMENT=production
# Archive and upload to App Store
xcodebuild -workspace ios/Runner.xcworkspace \
           -scheme Runner \
           -configuration Release \
           -archivePath build/Runner.xcarchive \
           archive# android/app/build.gradle
android {
    defaultConfig {
        applicationId "com.exploreuganda.app"
        minSdkVersion 21
        targetSdkVersion 33
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
        }
    }
}
# ios/Runner.xcodeproj/project.pbxproj
PRODUCT_BUNDLE_IDENTIFIER = com.exploreuganda.app
MARKETING_VERSION = 1.0.0
CURRENT_PROJECT_VERSION = 1// lib/config/version.dart
class AppVersion {
  static const String version = '1.0.0';
  static const int buildNumber = 1;
  
  static String get fullVersion => '$version+$buildNumber';
}- 
Pre-release - Update version numbers
- Run all tests
- Update changelog
- Review documentation
 
- 
Release Process - Create release branch
- Build release artifacts
- Run release tests
- Submit to stores
 
- 
Post-release - Monitor crash reports
- Track user feedback
- Document issues
 
# Fastfile
default_platform(:android)
platform :android do
  desc "Deploy to Play Store Internal Testing"
  lane :internal do
    upload_to_play_store(
      track: 'internal',
      aab: '../build/app/outputs/bundle/release/app-release.aab'
    )
  end
end
platform :ios do
  desc "Deploy to TestFlight"
  lane :beta do
    build_ios_app(
      workspace: "Runner.xcworkspace",
      scheme: "Runner",
      export_method: "app-store"
    )
    upload_to_testflight
  end
end// lib/utils/performance_monitoring.dart
class PerformanceMonitoring {
  static Future<void> trackStartup() async {
    final trace = FirebasePerformance.instance.newTrace('app_start');
    await trace.start();
    // Measure startup time
    await trace.stop();
  }
  
  static Future<void> trackScreenLoad(String screenName) async {
    final trace = FirebasePerformance.instance
        .newTrace('screen_load_$screenName');
    await trace.start();
    // Measure screen load time
    await trace.stop();
  }
}// lib/utils/error_tracking.dart
class ErrorTracking {
  static Future<void> initialize() async {
    await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
    FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
  }
  
  static Future<void> logError(
    String message,
    dynamic error,
    StackTrace stackTrace,
  ) async {
    await FirebaseCrashlytics.instance.recordError(
      error,
      stackTrace,
      reason: message,
    );
  }
}// lib/utils/analytics.dart
class Analytics {
  static Future<void> logScreenView(String screenName) async {
    await FirebaseAnalytics.instance.logScreenView(
      screenName: screenName,
    );
  }
  
  static Future<void> logUserAction(
    String action,
    Map<String, dynamic> parameters,
  ) async {
    await FirebaseAnalytics.instance.logEvent(
      name: action,
      parameters: parameters,
    );
  }
}# Revert to previous version
git checkout release/1.0.0
# Build emergency fix
flutter build apk --release --dart-define=ENVIRONMENT=production
# Deploy emergency version
fastlane android deploy- 
Identify Issue - Monitor crash reports
- Check user feedback
- Verify error logs
 
- 
Decision Making - Assess impact
- Evaluate options
- Plan rollback
 
- 
Execute Rollback - Revert code
- Build release
- Deploy update
 
- 
Post-Rollback - Verify stability
- Notify users
- Document incident
 
graph TD
    A[Detect Issue] --> B[Assess Impact]
    B --> C{Critical?}
    C -->|Yes| D[Immediate Rollback]
    C -->|No| E[Plan Fix]
    D --> F[Deploy Previous Version]
    E --> G[Deploy Fix]
    F --> H[Monitor]
    G --> H