- support_page: repoint comunes.org link to project page (Play re-approval) - build.gradle: conditional release signing (debug fallback), versionCode/Name from pubspec, drop duplicate google-services plugin - pubspec: version 1.10.0+10 (versionCode must exceed last uploaded) - track AndroidManifest.xml (no secrets in it) - fastlane: Appfile/Fastfile (deploy_play/deploy_metadata/promote_production) + Gemfile + es/en/gl store metadata - .forgejo: ci.yml (analyze+test) + release.yml (tag v* -> signed AAB -> Play internal) - README + RELEASE.md
85 lines
3.1 KiB
Markdown
85 lines
3.1 KiB
Markdown
# Releasing Tod@s contra el Fuego
|
|
|
|
Publishing to Google Play is **automated and password-free**: pushing a signed
|
|
git tag to `git.comunes.org` triggers Forgejo Actions, which builds a signed AAB
|
|
and uploads it to Play's **internal** track. Modeled on the `tane` pipeline.
|
|
|
|
## TL;DR — cut a release
|
|
|
|
```bash
|
|
# bump version in pubspec.yaml (version: X.Y.Z+CODE), add changelogs/<CODE>.txt
|
|
git tag v1.10 && git push origin v1.10
|
|
```
|
|
|
|
[`.forgejo/workflows/release.yml`](.forgejo/workflows/release.yml) builds the
|
|
signed AAB/APK (production flavor, `lib/main_prod.dart`) and uploads via
|
|
`fastlane deploy_play`. No passwords are typed.
|
|
|
|
## Versioning
|
|
|
|
- `version:` in [`pubspec.yaml`](pubspec.yaml) as `MAJOR.MINOR.PATCH+CODE`.
|
|
Flutter maps `+CODE` to Android `versionCode` (read via `flutter.versionCode`
|
|
in `android/app/build.gradle`) and the rest to `versionName`.
|
|
- **`versionCode` must be strictly greater than the highest ever uploaded** to
|
|
the `org.comunes.fires` listing. This re-launch starts at `+10` (was 9).
|
|
- Add a per-locale note under
|
|
`fastlane/metadata/android/<locale>/changelogs/<versionCode>.txt`.
|
|
|
|
## One-time setup
|
|
|
|
### Signing keystore
|
|
|
|
The app already exists in Play with **Play App Signing**, so releases MUST be
|
|
signed with the **existing upload key** that signed `org.comunes.fires` before
|
|
(`android/app/key.jks` → shared Comunes signing dir). Do **not** generate a new
|
|
one. Get the alias with:
|
|
|
|
```bash
|
|
keytool -list -v -keystore android/app/key.jks
|
|
```
|
|
|
|
Local signed builds read a **gitignored** `android/key.properties`:
|
|
|
|
```properties
|
|
storeFile=/abs/path/to/key.jks
|
|
storePassword=…
|
|
keyAlias=…
|
|
keyPassword=…
|
|
```
|
|
|
|
Without `key.properties`, release builds fall back to **debug** signing so
|
|
contributors/CI can still build.
|
|
|
|
### CI secrets (Forgejo → repo → Settings → Actions → Secrets)
|
|
|
|
| Secret | Contents |
|
|
|---|---|
|
|
| `FIRES_KEYSTORE_BASE64` | `base64 -w0 android/app/key.jks` |
|
|
| `FIRES_KEYSTORE_PASSWORD` / `FIRES_KEY_ALIAS` / `FIRES_KEY_PASSWORD` | keystore credentials |
|
|
| `SUPPLY_JSON_KEY_DATA` | Google Play service-account JSON (shared Comunes account) |
|
|
| `FIRES_PRIVATE_SETTINGS_JSON` | raw contents of `assets/private-settings.json` |
|
|
| `FIRES_GOOGLE_SERVICES_JSON` | `base64 -w0 android/app/google-services.json` |
|
|
|
|
### First upload
|
|
|
|
The app was removed by Google and an update was rejected. Before the API accepts
|
|
uploads: resolve any enforcement flag in the Play Console (appeal / re-submit),
|
|
and confirm the flagged content is addressed (the `comunes.org` support link was
|
|
repointed to the project page — see `lib/support_page.dart`). After the listing
|
|
accepts a build again, `fastlane deploy_play` is fully automated.
|
|
|
|
## Manual / local fallback
|
|
|
|
```bash
|
|
flutter pub get
|
|
dart run build_runner build --delete-conflicting-outputs
|
|
flutter build appbundle --release --flavor production -t lib/main_prod.dart
|
|
# AAB: build/app/outputs/bundle/productionRelease/app-production-release.aab
|
|
SUPPLY_JSON_KEY_DATA="$(cat play-service-account.json)" bundle exec fastlane deploy_play
|
|
```
|
|
|
|
Promote internal → production (reuses the reviewed AAB, no rebuild):
|
|
|
|
```bash
|
|
bundle exec fastlane promote_production
|
|
```
|