|
| 1 | +# Issue #452 Signed Release AAB Plan |
| 2 | + |
| 3 | +Parent track: #467 |
| 4 | +Sub-issue: #452 - Build a signed release Android App Bundle |
| 5 | + |
| 6 | +## Current Status |
| 7 | + |
| 8 | +#452 remains externally blocked until all prerequisites are complete and release |
| 9 | +secrets are available to the release owner or the protected GitHub Actions |
| 10 | +environment. |
| 11 | + |
| 12 | +Prerequisite status checked on 2026-05-10: |
| 13 | + |
| 14 | +- #450 release signing ownership and secret process: closed. |
| 15 | +- #451 release Firebase/Google services config process: closed. |
| 16 | +- #453 initial production versioning: open, so #452 must not be closed. |
| 17 | + |
| 18 | +The repository already has Gradle checks for release Firebase config and release |
| 19 | +signing inputs, plus the `Android Play Internal Deploy` workflow that builds a |
| 20 | +signed AAB when the configured environment secrets and variables are present. |
| 21 | + |
| 22 | +## Decision-Complete Plan |
| 23 | + |
| 24 | +1. Wait for #453 to close with the approved public `versionName` and Android |
| 25 | + `versionCode` rule for the first production upload. |
| 26 | +2. Confirm the `staging` GitHub environment has these secrets: |
| 27 | + - `ANDROID_GOOGLE_SERVICES_JSON_B64` |
| 28 | + - `ANDROID_UPLOAD_KEYSTORE_B64` |
| 29 | + - `ANDROID_KEYSTORE_PASSWORD` |
| 30 | + - `ANDROID_KEY_ALIAS` |
| 31 | + - `ANDROID_KEY_PASSWORD` |
| 32 | + - `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON` |
| 33 | +3. Confirm the `staging` GitHub environment has `REST_API_URL` set to the |
| 34 | + approved release-candidate API base URL. |
| 35 | +4. From `main`, run the `Android Play Internal Deploy` workflow. |
| 36 | +5. Confirm the workflow passes: |
| 37 | + - `flutter pub get` |
| 38 | + - `dart run build_runner build --delete-conflicting-outputs` |
| 39 | + - generated-file drift check |
| 40 | + - `flutter analyze` |
| 41 | + - `flutter test` |
| 42 | + - `flutter build appbundle --release` |
| 43 | +6. Record the signed AAB evidence: |
| 44 | + - workflow run URL |
| 45 | + - artifact name: `ontime-android-release-aab` |
| 46 | + - artifact path inside the run: `build/app/outputs/bundle/release/app-release.aab` |
| 47 | + - version name |
| 48 | + - generated Android version code |
| 49 | + - target environment and `REST_API_URL` ownership confirmation |
| 50 | +7. Keep #452 open if any required secret, environment variable, versioning |
| 51 | + decision, or Play upload permission is unavailable. |
| 52 | + |
| 53 | +## Local Build Alternative |
| 54 | + |
| 55 | +Use this only when the release owner has local access to the upload keystore, |
| 56 | +passwords, production Firebase config, and approved version values: |
| 57 | + |
| 58 | +```sh |
| 59 | +flutter pub get |
| 60 | +dart run build_runner build --delete-conflicting-outputs |
| 61 | +flutter analyze |
| 62 | +flutter test |
| 63 | + |
| 64 | +mkdir -p android/app/src/release |
| 65 | +base64 --decode android-google-services.json.b64 > android/app/src/release/google-services.json |
| 66 | + |
| 67 | +export ANDROID_KEYSTORE_PATH=/absolute/path/to/ontime-upload.jks |
| 68 | +export ANDROID_KEYSTORE_PASSWORD='<keystore-password>' |
| 69 | +export ANDROID_KEY_ALIAS=ontime |
| 70 | +export ANDROID_KEY_PASSWORD='<key-password>' |
| 71 | + |
| 72 | +flutter build appbundle --release \ |
| 73 | + --build-name=<approved version name> \ |
| 74 | + --build-number=<approved monotonic Android versionCode> \ |
| 75 | + --dart-define=ENV=staging \ |
| 76 | + --dart-define=REST_API_URL=<approved release-candidate api url> |
| 77 | +``` |
| 78 | + |
| 79 | +On macOS, use `base64 -D` instead of `base64 --decode`. |
| 80 | + |
| 81 | +## Handoff Evidence Template |
| 82 | + |
| 83 | +```text |
| 84 | +#452 signed AAB evidence |
| 85 | +- Workflow run URL: |
| 86 | +- Git commit SHA: |
| 87 | +- Version name: |
| 88 | +- Android version code: |
| 89 | +- Build environment: staging |
| 90 | +- REST_API_URL owner-confirmed: yes/no |
| 91 | +- AAB artifact name: ontime-android-release-aab |
| 92 | +- AAB artifact path: build/app/outputs/bundle/release/app-release.aab |
| 93 | +- Follow-up issue unblocked: #456 |
| 94 | +- Remaining blockers, if any: |
| 95 | +``` |
| 96 | + |
| 97 | +## Out Of Scope |
| 98 | + |
| 99 | +- Choosing or changing the production version; that belongs to #453. |
| 100 | +- Creating, rotating, or disclosing signing keys. |
| 101 | +- Committing `google-services.json`, keystores, passwords, or generated AABs. |
| 102 | +- Verifying Play App Signing fingerprints; that belongs to #454. |
| 103 | +- Device smoke testing; that belongs to #456. |
0 commit comments