Build and package Flutter applications for multiple platforms with code signing, obfuscation, and release optimization
From flutter-corenpx claudepluginhub aaronbassett/agent-foundry --plugin flutter-core<android|ios|web|windows|macos|linux|all> [release|debug|profile] [--flavor=<name>] [--obfuscate]/flutter-buildFixes Dart analyzer errors and Flutter build failures incrementally: runs diagnostics, applies minimal fixes one-by-one, verifies each, and reports summary with changes.
/flutter-buildFixes Dart analyzer errors and Flutter build failures incrementally: runs diagnostics, applies minimal fixes one-by-one, verifies each, and reports summary with changes.
/flutter-buildFixes Dart analyzer errors and Flutter build failures incrementally: runs diagnostics, applies minimal fixes one-by-one, verifies each, and reports summary with changes.
This command orchestrates building and packaging Flutter applications for all supported platforms with production-ready configurations, code signing, and optimization.
/flutter-build <platform> [mode] [options]
android - Build APK/AAB for Androidios - Build IPA for iOS (macOS only)web - Build web appwindows - Build Windows executablemacos - Build macOS app (macOS only)linux - Build Linux app (Linux/macOS only)all - Build for all available platformsrelease - Production build (default)debug - Debug build with assertionsprofile - Performance profiling build--flavor=<name> - Build flavor (dev, staging, prod)--obfuscate - Obfuscate Dart code--split-per-abi - Create separate APKs per ABI (Android)--bundle - Create app bundle instead of APK (Android)--export-method=<method> - iOS export method (app-store, ad-hoc, enterprise, development)--codesign - Code sign the build (required for iOS/macOS distribution)--analyze-size - Generate size analysis report# Android release build
/flutter-build android release
# iOS App Store build with obfuscation
/flutter-build ios release --export-method=app-store --obfuscate --codesign
# Android bundle with flavor
/flutter-build android release --bundle --flavor=prod
# Multi-platform release
/flutter-build all release --obfuscate
# Web with size analysis
/flutter-build web release --analyze-size
# Development build for testing
/flutter-build android debug --flavor=dev
When this command runs:
Check environment and prerequisites:
# Verify Flutter installation
flutter doctor -v
# Check we're in a Flutter project
if [ ! -f "pubspec.yaml" ]; then
echo "Error: Not a Flutter project"
exit 1
fi
# Verify platform support
flutter config
Platform-Specific Checks:
Android:
iOS/macOS:
Web:
Windows:
Linux:
Extract configuration from arguments and project files:
// Read from pubspec.yaml
final config = {
'name': packageName,
'version': version,
'build_number': buildNumber,
};
// Check for flavor configurations
final flavorConfig = flavor != null
? readFlavorConfig(flavor)
: null;
Check for build configuration files:
android/app/build.gradle - Android configios/Runner.xcodeproj - iOS configweb/index.html - Web configbuild.yaml - Build settingsClean and prepare:
# Clean previous builds
flutter clean
# Get dependencies
flutter pub get
# Run code generation if needed
if grep -q "build_runner" pubspec.yaml; then
flutter pub run build_runner build --delete-conflicting-outputs
fi
# Run analysis
flutter analyze
If analysis has errors (release mode):
⚠️ Analysis found errors. Building with errors may cause runtime issues.
Continue anyway? (y/n)
Execute platform-specific builds:
APK Build:
flutter build apk \
--release \
${flavor:+--flavor=$flavor} \
${obfuscate:+--obfuscate --split-debug-info=./debug-info} \
${split_abi:+--split-per-abi} \
--target-platform android-arm,android-arm64,android-x64
App Bundle Build:
flutter build appbundle \
--release \
${flavor:+--flavor=$flavor} \
${obfuscate:+--obfuscate --split-debug-info=./debug-info}
Output locations:
build/app/outputs/flutter-apk/app-release.apkbuild/app/outputs/bundle/release/app-release.aabCode Signing (release):
# Verify keystore exists
if [ ! -f "$KEYSTORE_PATH" ]; then
echo "Error: Keystore not found"
echo "Create keystore: keytool -genkey -v -keystore release.jks ..."
exit 1
fi
# Sign APK
jarsigner -verbose \
-sigalg SHA256withRSA \
-digestalg SHA-256 \
-keystore $KEYSTORE_PATH \
app-release.apk \
$KEY_ALIAS
# Zipalign
zipalign -v 4 app-release.apk app-release-aligned.apk
# Build iOS app
flutter build ios \
--release \
${flavor:+--flavor=$flavor} \
${obfuscate:+--obfuscate --split-debug-info=./debug-info} \
${no_codesign:+--no-codesign}
# Create archive (if codesigning)
if [ "$codesign" = true ]; then
xcodebuild -workspace ios/Runner.xcworkspace \
-scheme Runner \
-configuration Release \
-archivePath build/ios/archive/Runner.xcarchive \
archive
# Export IPA
xcodebuild -exportArchive \
-archivePath build/ios/archive/Runner.xcarchive \
-exportPath build/ios/ipa \
-exportOptionsPlist ios/ExportOptions.plist
fi
Output: build/ios/ipa/Runner.ipa
Provisioning Profile Check:
# List available profiles
security find-identity -v -p codesigning
# Verify profile matches bundle ID
flutter build web \
--release \
--web-renderer canvaskit \
${obfuscate:+--source-maps}
# Optimize assets
if command -v gzip &> /dev/null; then
find build/web -type f \( -name '*.js' -o -name '*.css' -o -name '*.html' \) \
-exec gzip -k {} \;
fi
Output: build/web/
Web Optimization:
# Create service worker
# Configure caching strategy
# Optimize images
# Generate manifest.json
flutter build windows \
--release \
${obfuscate:+--obfuscate --split-debug-info=./debug-info}
# Create installer (optional)
if command -v iscc &> /dev/null; then
iscc windows/installer.iss
fi
Output: build/windows/runner/Release/
flutter build macos \
--release \
${obfuscate:+--obfuscate --split-debug-info=./debug-info}
# Code sign (if required)
if [ "$codesign" = true ]; then
codesign --deep --force \
--sign "$DEVELOPER_ID" \
build/macos/Build/Products/Release/your_app.app
# Notarize (for distribution)
xcrun notarytool submit \
build/macos/Build/Products/Release/your_app.app \
--apple-id "$APPLE_ID" \
--password "$APP_PASSWORD" \
--team-id "$TEAM_ID"
fi
Output: build/macos/Build/Products/Release/your_app.app
flutter build linux \
--release \
${obfuscate:+--obfuscate --split-debug-info=./debug-info}
# Create package (optional)
# - .deb package
# - AppImage
# - Snap
Output: build/linux/x64/release/bundle/
Analyze build output:
# Calculate sizes
du -sh build/*/
# For Android
apkanalyzer apk summary app-release.apk
# For iOS
xcrun dyld_info -size Runner.app/Runner
# Generate size breakdown
flutter build apk --analyze-size --target-platform android-arm64
Create size report:
Build Size Analysis
===================
Platform: Android (ARM64)
Total size: 15.2 MB
Breakdown:
Code (Dart): 8.3 MB (55%)
Assets: 4.2 MB (28%)
Native libs: 2.1 MB (14%)
Resources: 0.6 MB (3%)
Largest assets:
1. assets/images/splash.png - 1.2 MB
2. assets/fonts/Roboto.ttf - 0.8 MB
3. assets/data/cities.json - 0.5 MB
Recommendations:
- Compress splash image (PNG → WebP)
- Use variable fonts to reduce font size
- Consider code splitting for large apps
Handle build flavors:
Android (build.gradle):
android {
flavorDimensions "environment"
productFlavors {
dev {
dimension "environment"
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
}
prod {
dimension "environment"
}
}
}
iOS (Scheme configuration):
Flutter (dart-defines):
flutter build apk --dart-define=FLAVOR=prod --dart-define=API_URL=https://api.prod.com
After successful build:
# Run built app (debug/profile mode)
if [ "$mode" != "release" ]; then
flutter install
fi
# Copy artifacts to distribution folder
mkdir -p dist/
cp build/app/outputs/flutter-apk/*.apk dist/
# Generate checksums
sha256sum dist/*.apk > dist/checksums.txt
# Create build manifest
cat > dist/build-manifest.json <<EOF
{
"version": "$version",
"build_number": "$build_number",
"platform": "$platform",
"mode": "$mode",
"flavor": "$flavor",
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"git_commit": "$(git rev-parse HEAD)",
"obfuscated": $obfuscate
}
EOF
Create comprehensive build report:
# Flutter Build Report
## Build Information
- Platform: Android
- Mode: Release
- Flavor: prod
- Date: 2026-01-23 16:30:00
- Git Commit: a1b2c3d4
## Configuration
- Obfuscation: ✓ Enabled
- Code Signing: ✓ Signed
- Bundle: ✓ AAB created
- Split ABIs: ✓ Enabled
## Build Artifacts
- `app-arm64-v8a-release.apk` (12.1 MB)
- `app-armeabi-v7a-release.apk` (13.5 MB)
- `app-x86_64-release.apk` (14.2 MB)
- `app-release.aab` (28.5 MB)
## Size Analysis
- Total APK size: 12.1 MB (ARM64)
- 23% smaller than previous build
- Dart code: 6.8 MB
- Native code: 3.2 MB
- Assets: 2.1 MB
## Quality Checks
- ✓ Analysis: No issues
- ✓ Tests: 177/177 passed
- ✓ Code signing: Valid
- ✓ Permissions: Reviewed
## Distribution
- Location: `dist/`
- Checksum: SHA256 available
- Upload to: Play Console
## Next Steps
1. Test on physical devices
2. Submit to Play Store
3. Monitor crash reports
Android:
Google Play Console Upload:
1. Go to: https://play.google.com/console
2. Select your app
3. Navigate to: Release > Production
4. Upload: app-release.aab
5. Fill release notes
6. Submit for review
iOS:
App Store Connect Upload:
1. Open Xcode
2. Window > Organizer
3. Select archive
4. Distribute App > App Store Connect
5. Upload
6. Go to: https://appstoreconnect.apple.com
7. Submit for review
Web:
Deploy to hosting:
Firebase:
firebase deploy --only hosting
GitHub Pages:
cp -r build/web/* docs/
git add docs/ && git commit -m "Deploy web build"
git push
Custom server:
rsync -avz build/web/ user@server:/var/www/html/
Common build errors and solutions:
Android:
flutter doctor --android-licensesiOS:
cd ios && pod installAll Platforms:
flutter pub getExample GitHub Actions workflow:
name: Build and Release
on:
push:
tags:
- 'v*'
jobs:
build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
- name: Build Android
run: /flutter-build android release --bundle --obfuscate
- name: Upload to Play Store
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_STORE_JSON }}
packageName: com.example.app
releaseFiles: build/app/outputs/bundle/release/*.aab
build-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
- name: Build iOS
run: /flutter-build ios release --export-method=app-store --codesign
- name: Upload to App Store
uses: apple-actions/upload-testflight-build@v1
with:
app-path: build/ios/ipa/Runner.ipa
issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }}
api-key-id: ${{ secrets.APPSTORE_KEY_ID }}