# Android Release Configuration Android release builds must include the production Firebase client config so Firebase Core and Firebase Messaging initialize consistently. ## Required CI Secret - `ANDROID_GOOGLE_SERVICES_JSON_B64`: base64-encoded contents of the production Android `google-services.json` for Firebase project `ontime-c63f1`. The Android Play Internal Deploy workflow decodes this secret to `android/app/src/release/google-services.json` before running the Android release build. Generated `google-services.json` files are ignored and must not be committed. The decoded file must include an Android client whose package name is `club.devkor.ontime`. Gradle validates this package match for release builds and through the focused validation task below. ## Google Play Internal Testing Deploy Use the `Android Play Internal Deploy` GitHub Actions workflow to build a signed Android App Bundle and upload it to the Google Play Internal Testing track as a draft release. The workflow runs automatically on pushes to `main` and can also be dispatched manually from `main`. Configure a GitHub environment named `staging` for internal test distribution. Store these environment secrets there: - `ANDROID_GOOGLE_SERVICES_JSON_B64`: base64-encoded production Android Firebase config. - `ANDROID_UPLOAD_KEYSTORE_B64`: base64-encoded Google Play upload keystore. - `ANDROID_KEYSTORE_PASSWORD`: upload keystore password. - `ANDROID_KEY_ALIAS`: upload key alias. - `ANDROID_KEY_PASSWORD`: upload key password. - `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON`: raw service-account JSON for the Google Play Developer API. Store this environment variable in `staging`: - `REST_API_URL`: target API base URL passed to Flutter with `--dart-define`. The deploy workflow runs package install, code generation, generated-file drift checking, analysis, tests, and then `flutter build appbundle --release`. It derives Android `versionName` from the `pubspec.yaml` version name and supplies `${{ github.run_number }}` as Android `versionCode`: ```sh flutter build appbundle --release \ --build-name= \ --build-number=${{ github.run_number }} \ --dart-define=ENV=staging \ --dart-define=REST_API_URL="$REST_API_URL" ``` It uploads the signed `.aab` as a 14-day GitHub Actions artifact and creates a draft release on Google Play Internal Testing. If the optional release notes input is empty, the workflow uploads without custom release notes. Keep `pubspec.yaml` as the source of truth for the manually managed public version name, such as `version: 1.0.0+1`. Android CI ignores the checked-in build suffix for Play uploads, so do not open PRs only to bump `+2`, `+3`, and similar build numbers. The generated `github.run_number` must still be greater than every previously uploaded Google Play build for `club.devkor.ontime`; duplicate or lower build numbers fail during the Google Play upload step. ## Local Release Build Create the release source-set config before building: ```sh mkdir -p android/app/src/release base64 --decode android-google-services.json.b64 > android/app/src/release/google-services.json flutter build appbundle --release \ --build-name= \ --build-number= \ --dart-define=ENV=prod \ --dart-define=REST_API_URL= ``` On macOS, use `base64 -D` instead of `base64 --decode`. Debug/local builds may run without Android Firebase config. Release builds fail clearly if `android/app/src/release/google-services.json`, `android/app/google-services.json`, or `android/app/src/google-services.json` is missing. To validate only the Firebase config without requiring release signing inputs, materialize the ignored release config file and run: ```sh cd android gradle :app:validateAndroidGoogleServices ``` The task fails if the file is missing, invalid JSON, or missing a `client_info.android_client_info.package_name` entry for `club.devkor.ontime`. ## Auth Fingerprints Release SHA-1 and SHA-256 fingerprints must be added to Firebase after the release signing owner, upload key, and Play App Signing setup are finalized. Use `docs/Android-Play-Signing-Fingerprints.md` for the #454 checklist. Do not rotate or replace `ANDROID_GOOGLE_SERVICES_JSON_B64` for fingerprint changes until the release owner confirms the final signing fingerprints. ## Verification Use the `Android Play Internal Deploy` GitHub Actions workflow to confirm CI can reproduce the signed release build with the configured secrets. For production readiness, also install a real Android release build and verify Firebase initializes and FCM token registration reaches the backend.