mobile bluesky app made with flutter
lazurite.stormlightlabs.org/
mobile
bluesky
flutter
1---
2title: Release and Distribution Guide
3updated: 2026-05-02
4---
5
6## Shared Release Baseline
7
81. Pin and verify toolchain.
9 - `flutter --version`
10 - `dart --version`
112. Set version in `pubspec.yaml` and/or pass build flags.
12 - `--build-name` => human version (for example `1.4.0`)
13 - `--build-number` => monotonically increasing integer
143. Run release gates.
15 - `flutter pub get`
16 - `flutter analyze`
17 - `gtimeout 1200s flutter test --reporter=failures-only`
184. Tag immutable source.
19 - `git tag vX.Y.Z`
205. Build store artifacts from that exact tag/commit.
21
22## Environment Variables
23
24Use the root `.env.example` as the canonical variable list. Keep real values in untracked secrets (`.env.local`, CI secrets manager, etc.).
25
26## Google Play (Android)
27
28### Build
29
301. Configure real release signing (upload key), not debug signing.
312. Build AAB (preferred by Google Play):
32
33 ```bash
34 flutter build appbundle --release \
35 --build-name "$FLUTTER_BUILD_NAME" \
36 --build-number "$FLUTTER_BUILD_NUMBER"
37 ```
38
393. Artifact: `build/app/outputs/bundle/release/app-release.aab`
40
41### Deploy
42
431. Enroll in Play App Signing.
442. Upload `app-release.aab` to Internal testing first.
453. Promote to closed/open/production after validation.
46
47### Notes
48
49- If you need the same signing key across multiple stores, provide your own app signing key when configuring Play App Signing.
50- For non-Play Android channels, ship signed APKs (Play consumes AAB; side channels consume APK).
51
52## Apple App Store (iOS)
53
54### Build
55
561. Use an explicit App ID + matching bundle ID.
572. Build signed IPA:
58
59 ```bash
60 flutter build ipa --release \
61 --build-name "$FLUTTER_BUILD_NAME" \
62 --build-number "$FLUTTER_BUILD_NUMBER"
63 ```
64
653. Artifact: `build/ios/ipa/*.ipa`
66
67### Deploy
68
691. Upload using Xcode or Transporter to App Store Connect.
702. Wait for processing.
713. Ship through TestFlight (internal/external) first.
724. Submit selected build for App Review.
73
74### Notes
75
76- App Store Connect associates build using bundle ID + version + build string.
77- As of 2026, Apple requires Xcode 14+ for uploads.
78
79## AltStore.io
80
81AltStore distribution has two distinct paths.
82
83### AltStore PAL (EU marketplace path)
84
85#### Build/Package
86
871. Build iOS release (`flutter build ipa --release`).
882. Submit via App Store Connect with Notarization (or App Store approval, which also results in notarization).
893. Download the Alternative Distribution Package (ADP).
904. Host ADP exactly as-delivered; preserve directory hierarchy and do not modify `manifest.json`.
91
92#### Deploy
93
941. Accept Apple Alternative EU Terms Addendum.
952. Register Developer ID with AltStore PAL API.
963. Add returned marketplace token in App Store Connect Integrations.
974. Publish a Source JSON with required app/version metadata.
98
99### AltStore Classic (sideloaded IPA path)
100
101#### Build
102
1031. Build/sign IPA (`flutter build ipa --release`).
1042. Host IPA at stable HTTPS URL.
105
106#### Deploy
107
1081. Publish/update Source JSON.
1092. Keep newest entry first in `versions` array.
1103. Ensure each release updates `version` (`CFBundleShortVersionString`) and/or `buildVersion` (`CFBundleVersion`).
1114. Include accurate `downloadURL`, `size`, and optional `minOSVersion` / `maxOSVersion`.
112
113### Notes
114
115- AltStore determines latest release by `versions` ordering, not dates.
116- AltStore checks declared app permissions/entitlements against downloaded app package.
117
118## F-Droid
119
120### Build Strategy
121
1221. Decide target:
123 - Main F-Droid repo, or
124 - Your own F-Droid-compatible repo.
1252. For main F-Droid repo, create an `fdroid` flavor without proprietary SDKs (Firebase/Crashlytics/Play Services tracking dependencies are not allowed in main repo).
1263. Build signed deterministic APK for that flavor.
127
128Recommended flavor command pattern:
129
130```bash
131flutter build apk --release \
132 --flavor fdroid \
133 --target lib/main_fdroid.dart \
134 --build-name "$FLUTTER_BUILD_NAME" \
135 --build-number "$FLUTTER_BUILD_NUMBER"
136```
137
138### Deploy
139
1401. Prepare fdroiddata metadata and submit inclusion proposal (prefer metadata merge request path).
1412. Keep upstream releases tagged.
1423. Aim for reproducible builds from day one (strongly recommended by F-Droid, harder to retrofit later).
143
144### Notes
145
146- If Firebase push is required in Play/App Store builds, maintain a clean non-proprietary F-Droid flavor where push is disabled or replaced.
147
148## Obtainium (Android direct update channel)
149
150### Build
151
1521. Produce signed APK artifacts for direct install.
1532. Prefer a stable, machine-discoverable release URL source (typically GitHub Releases).
154
155### Deploy
156
1571. Publish release where source exposes:
158 - version identifier
159 - at least one APK download URL
1602. If multiple APK variants exist, keep filenames explicit (`arm64-v8a`, `universal`, etc.) so users can filter reliably.
161
162### Notes
163
164- Obtainium supports GitHub, GitLab, F-Droid repos, direct APK links, and HTML fallback.
165- Cross-store signing matters: updating from F-Droid-signed to non-F-Droid-signed builds may fail due to signature mismatch.
166
167## GitHub Releases
168
169### Build
170
1711. Build release artifacts from tagged commit (`vX.Y.Z`).
1722. Generate checksums for all distributables.
173
174Example:
175
176```bash
177shasum -a 256 build/app/outputs/flutter-apk/*.apk build/ios/ipa/*.ipa > checksums.txt
178```
179
180### Deploy
181
1821. Create release from tag.
1832. Attach binaries (`.aab`, `.apk`, `.ipa`, `checksums.txt`, optional symbols/maps).
1843. Use generated release notes, then curate manually.
185
186CLI example:
187
188```bash
189gh release create "v${FLUTTER_BUILD_NAME}" \
190 --generate-notes \
191 build/app/outputs/bundle/release/app-release.aab \
192 build/app/outputs/flutter-apk/*.apk \
193 build/ios/ipa/*.ipa \
194 checksums.txt
195```
196
197### Hardening (Recommended)
198
199- Add artifact attestations in GitHub Actions for build provenance.
200- Keep each release asset < 2 GiB.
201
202## Firebase Push Notifications (iOS + Android)
203
204### 1) Firebase Project and App Registration
205
2061. Install CLI tooling.
207 - `firebase login`
208 - `dart pub global activate flutterfire_cli`
2092. Run:
210
211 ```bash
212 flutterfire configure
213 ```
214
2153. Commit generated `lib/firebase_options.dart`.
216
217### 2) Platform Config Files
218
2191. Android: place `google-services.json` at `android/app/google-services.json`.
2202. iOS: place `GoogleService-Info.plist` at `ios/Runner/GoogleService-Info.plist` and include it in Runner target.
221
222### 3) Android Gradle Wiring
223
2241. Add Google services Gradle plugin in project/plugin management.
2252. Apply `com.google.gms.google-services` in app module.
226
227### 4) Apple Push Prerequisites
228
2291. In Xcode, enable `Push Notifications` capability.
2302. In Xcode Background Modes, enable:
231 - `Background fetch`
232 - `Remote notifications`
2333. Upload APNs auth key (`.p8`, Key ID, Team ID) in Firebase Console > Project Settings > Cloud Messaging.
234
235### 5) App Initialization and Runtime
236
2371. Initialize with generated options:
238
239 ```dart
240 await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
241 ```
242
2432. Request user notification permission (iOS) before expecting token delivery.
2443. Register and sync FCM token with backend; rotate on refresh.
245
246### 6) Channel-Specific Caveat
247
248- F-Droid mainline build should not include proprietary Firebase dependencies.
249Keep push-enabled binaries for Play/App Store/AltStore/Obtainium, and maintain a non-Firebase F-Droid flavor.
250
251## Primary References
252
253- Flutter Android release: <https://docs.flutter.dev/deployment/android>
254- Flutter iOS release: <https://docs.flutter.dev/deployment/ios>
255- Android signing + Play App Signing: <https://developer.android.com/studio/publish/app-signing>
256- Play App Signing help: <https://support.google.com/googleplay/android-developer/answer/9842756>
257- App Store Connect uploads: <https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds/>
258- 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>
259- AltStore PAL distribution: <https://faq.altstore.io/developers/distribute-with-altstore-pal>
260- AltStore source format: <https://faq.altstore.io/developers/make-a-source>
261- AltStore updates/version ordering: <https://faq.altstore.io/developers/updating-apps>
262- F-Droid inclusion policy: <https://f-droid.org/en/docs/Inclusion_Policy/>
263- F-Droid inclusion workflow: <https://f-droid.org/en/docs/Inclusion_How-To/>
264- F-Droid reproducible builds: <https://f-droid.org/docs/Reproducible_Builds/>
265- Obtainium tracking/source behavior: <https://wiki.obtainium.imranr.dev/app_tracking/> and <https://wiki.obtainium.imranr.dev/sources/>
266- GitHub releases: <https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository>
267- GitHub release notes automation: <https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes>
268- GitHub build provenance (artifact attestations): <https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations>
269- GitHub release asset limits: <https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases>
270- Firebase Flutter setup: <https://firebase.google.com/docs/flutter/setup>
271- Firebase FCM Flutter setup: <https://firebase.google.com/docs/cloud-messaging/flutter/get-started>
272- Firebase Android config (`google-services.json` + plugin): <https://firebase.google.com/docs/android/setup>