mobile bluesky app made with flutter
lazurite.stormlightlabs.org/
mobile
bluesky
flutter
title: Release and Distribution Guide updated: 2026-05-02#
Shared Release Baseline#
- Pin and verify toolchain.
flutter --versiondart --version
- Set version in
pubspec.yamland/or pass build flags.--build-name=> human version (for example1.4.0)--build-number=> monotonically increasing integer
- Run release gates.
flutter pub getflutter analyzegtimeout 1200s flutter test --reporter=failures-only
- Tag immutable source.
git tag vX.Y.Z
- Build store artifacts from that exact tag/commit.
Environment Variables#
Use the root .env.example as the canonical variable list. Keep real values in untracked secrets (.env.local, CI secrets manager, etc.).
Google Play (Android)#
Build#
-
Configure real release signing (upload key), not debug signing.
-
Build AAB (preferred by Google Play):
flutter build appbundle --release \ --build-name "$FLUTTER_BUILD_NAME" \ --build-number "$FLUTTER_BUILD_NUMBER" -
Artifact:
build/app/outputs/bundle/release/app-release.aab
Deploy#
- Enroll in Play App Signing.
- Upload
app-release.aabto Internal testing first. - Promote to closed/open/production after validation.
Notes#
- If you need the same signing key across multiple stores, provide your own app signing key when configuring Play App Signing.
- For non-Play Android channels, ship signed APKs (Play consumes AAB; side channels consume APK).
Apple App Store (iOS)#
Build#
-
Use an explicit App ID + matching bundle ID.
-
Build signed IPA:
flutter build ipa --release \ --build-name "$FLUTTER_BUILD_NAME" \ --build-number "$FLUTTER_BUILD_NUMBER" -
Artifact:
build/ios/ipa/*.ipa
Deploy#
- Upload using Xcode or Transporter to App Store Connect.
- Wait for processing.
- Ship through TestFlight (internal/external) first.
- Submit selected build for App Review.
Notes#
- App Store Connect associates build using bundle ID + version + build string.
- As of 2026, Apple requires Xcode 14+ for uploads.
AltStore.io#
AltStore distribution has two distinct paths.
AltStore PAL (EU marketplace path)#
Build/Package#
- Build iOS release (
flutter build ipa --release). - Submit via App Store Connect with Notarization (or App Store approval, which also results in notarization).
- Download the Alternative Distribution Package (ADP).
- Host ADP exactly as-delivered; preserve directory hierarchy and do not modify
manifest.json.
Deploy#
- Accept Apple Alternative EU Terms Addendum.
- Register Developer ID with AltStore PAL API.
- Add returned marketplace token in App Store Connect Integrations.
- Publish a Source JSON with required app/version metadata.
AltStore Classic (sideloaded IPA path)#
Build#
- Build/sign IPA (
flutter build ipa --release). - Host IPA at stable HTTPS URL.
Deploy#
- Publish/update Source JSON.
- Keep newest entry first in
versionsarray. - Ensure each release updates
version(CFBundleShortVersionString) and/orbuildVersion(CFBundleVersion). - Include accurate
downloadURL,size, and optionalminOSVersion/maxOSVersion.
Notes#
- AltStore determines latest release by
versionsordering, not dates. - AltStore checks declared app permissions/entitlements against downloaded app package.
F-Droid#
Build Strategy#
- Decide target:
- Main F-Droid repo, or
- Your own F-Droid-compatible repo.
- For main F-Droid repo, create an
fdroidflavor without proprietary SDKs (Firebase/Crashlytics/Play Services tracking dependencies are not allowed in main repo). - Build signed deterministic APK for that flavor.
Recommended flavor command pattern:
flutter build apk --release \
--flavor fdroid \
--target lib/main_fdroid.dart \
--build-name "$FLUTTER_BUILD_NAME" \
--build-number "$FLUTTER_BUILD_NUMBER"
Deploy#
- Prepare fdroiddata metadata and submit inclusion proposal (prefer metadata merge request path).
- Keep upstream releases tagged.
- Aim for reproducible builds from day one (strongly recommended by F-Droid, harder to retrofit later).
Notes#
- If Firebase push is required in Play/App Store builds, maintain a clean non-proprietary F-Droid flavor where push is disabled or replaced.
Obtainium (Android direct update channel)#
Build#
- Produce signed APK artifacts for direct install.
- Prefer a stable, machine-discoverable release URL source (typically GitHub Releases).
Deploy#
- Publish release where source exposes:
- version identifier
- at least one APK download URL
- If multiple APK variants exist, keep filenames explicit (
arm64-v8a,universal, etc.) so users can filter reliably.
Notes#
- Obtainium supports GitHub, GitLab, F-Droid repos, direct APK links, and HTML fallback.
- Cross-store signing matters: updating from F-Droid-signed to non-F-Droid-signed builds may fail due to signature mismatch.
GitHub Releases#
Build#
- Build release artifacts from tagged commit (
vX.Y.Z). - Generate checksums for all distributables.
Example:
shasum -a 256 build/app/outputs/flutter-apk/*.apk build/ios/ipa/*.ipa > checksums.txt
Deploy#
- Create release from tag.
- Attach binaries (
.aab,.apk,.ipa,checksums.txt, optional symbols/maps). - Use generated release notes, then curate manually.
CLI example:
gh release create "v${FLUTTER_BUILD_NAME}" \
--generate-notes \
build/app/outputs/bundle/release/app-release.aab \
build/app/outputs/flutter-apk/*.apk \
build/ios/ipa/*.ipa \
checksums.txt
Hardening (Recommended)#
- Add artifact attestations in GitHub Actions for build provenance.
- Keep each release asset < 2 GiB.
Firebase Push Notifications (iOS + Android)#
1) Firebase Project and App Registration#
-
Install CLI tooling.
firebase logindart pub global activate flutterfire_cli
-
Run:
flutterfire configure -
Commit generated
lib/firebase_options.dart.
2) Platform Config Files#
- Android: place
google-services.jsonatandroid/app/google-services.json. - iOS: place
GoogleService-Info.plistatios/Runner/GoogleService-Info.plistand include it in Runner target.
3) Android Gradle Wiring#
- Add Google services Gradle plugin in project/plugin management.
- Apply
com.google.gms.google-servicesin app module.
4) Apple Push Prerequisites#
- In Xcode, enable
Push Notificationscapability. - In Xcode Background Modes, enable:
Background fetchRemote notifications
- Upload APNs auth key (
.p8, Key ID, Team ID) in Firebase Console > Project Settings > Cloud Messaging.
5) App Initialization and Runtime#
-
Initialize with generated options:
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); -
Request user notification permission (iOS) before expecting token delivery.
-
Register and sync FCM token with backend; rotate on refresh.
6) Channel-Specific Caveat#
- F-Droid mainline build should not include proprietary Firebase dependencies. Keep push-enabled binaries for Play/App Store/AltStore/Obtainium, and maintain a non-Firebase F-Droid flavor.
Primary References#
- Flutter Android release: https://docs.flutter.dev/deployment/android
- Flutter iOS release: https://docs.flutter.dev/deployment/ios
- Android signing + Play App Signing: https://developer.android.com/studio/publish/app-signing
- Play App Signing help: https://support.google.com/googleplay/android-developer/answer/9842756
- App Store Connect uploads: https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds/
- Apple explicit App ID / bundle ID requirements: https://developer.apple.com/help/glossary/app-id/ and https://developer.apple.com/documentation/bundleresources/information-property-list/cfbundleidentifier
- AltStore PAL distribution: https://faq.altstore.io/developers/distribute-with-altstore-pal
- AltStore source format: https://faq.altstore.io/developers/make-a-source
- AltStore updates/version ordering: https://faq.altstore.io/developers/updating-apps
- F-Droid inclusion policy: https://f-droid.org/en/docs/Inclusion_Policy/
- F-Droid inclusion workflow: https://f-droid.org/en/docs/Inclusion_How-To/
- F-Droid reproducible builds: https://f-droid.org/docs/Reproducible_Builds/
- Obtainium tracking/source behavior: https://wiki.obtainium.imranr.dev/app_tracking/ and https://wiki.obtainium.imranr.dev/sources/
- GitHub releases: https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository
- GitHub release notes automation: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
- GitHub build provenance (artifact attestations): https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations
- GitHub release asset limits: https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases
- Firebase Flutter setup: https://firebase.google.com/docs/flutter/setup
- Firebase FCM Flutter setup: https://firebase.google.com/docs/cloud-messaging/flutter/get-started
- Firebase Android config (
google-services.json+ plugin): https://firebase.google.com/docs/android/setup