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