Skip to content

Rename app ID to com.bookbridge.app, restore Android build, add CI and release signing - #28

Open
DCT-Berinyuy wants to merge 4 commits into
devfrom
dct-berinyuy-rename-app-package-id
Open

DCT-Berinyuy wants to merge 4 commits into
devfrom
dct-berinyuy-rename-app-package-id

Conversation

@DCT-Berinyuy

@DCT-Berinyuy DCT-Berinyuy commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Four commits. Each can be reviewed on its own.

1. Rename app identifier com.example.* → com.bookbridge.app

Flutter's scaffold placeholder com.example.* is rejected by Google Play and unsuitable for the App Store. It's also expensive to change after first publish: the package name is permanent on Play, and Firebase/OAuth bindings key on it.

Target Before After
Android applicationId + namespace com.example.book_bridge com.bookbridge.app
MainActivity.kt package + path com/example/book_bridge/ com/bookbridge/app/
google-services.json package_name com.example.book_bridge com.bookbridge.app
iOS / macOS PRODUCT_BUNDLE_IDENTIFIER (app + tests) com.example.bookBridge com.bookbridge.app
firebase_options.dart iosBundleId com.example.book_bridge com.bookbridge.app
Linux APPLICATION_ID, Windows / macOS metadata com.example… com.bookbridge.app / BookBridge

Latent bug fixed: firebase_options.dart declared com.example.book_bridge while the iOS project used com.example.bookBridge. They never matched.

2. Restore a working Android build

No Android build could complete before this, independent of the rename. There were three pre-existing blockers, and each surfaced only after the previous one was fixed:

Blocker Cause Fix
AGP 8.7.0 below Flutter 3.47's minimum of 8.11.1 Downgraded from 8.11.1 in a0026fa AGP 8.13.2: latest 8.x, avoids the separate AGP 9 migration
:jni plugin: "NDK not configured" ndkVersion commented out in 0e28706; Flutter 3.47 needs NDK 28.2.13676358 Restored ndkVersion = flutter.ndkVersion
Dart compile: IconData is a final class font_awesome_flutter 10.x subclasses it Bumped to ^11.0.0. FaIcon sites take FaIconData; plain Icon sites use .data, so rendering is unchanged

It also adds two gradle.properties flags (android.builtInKotlin=false, android.newDsl=false). Flutter's migrator inserts these before every build. They have no effect on AGP 8.

3. Android CI and reproducible builds

The build was broken for six months without anyone noticing, because nothing built it and nothing pinned the toolchain.

Gap Fix
No CI job built Android. dart.yml only triggered on main and ran dart analyze/dart test, which can't pass on a Flutter app Replaced it with flutter.yml, which runs on PRs and pushes to dev/main: pub get --enforce-lockfile → analyze → test → build apk --debug → checks the APK's application ID is com.bookbridge.app
Unpinned Flutter SDK. This is what silently broke the build CI pins Flutter 3.47.4 and NDK 28.2.13676358. Bump them deliberately, in their own PR
pubspec.lock ignored by a blanket *.lock rule Committed; the un-ignore is scoped to the root lockfile only
org.gradle.java.home=/opt/android-studio/jbr, a path that exists on one machine only Removed. Flutter already finds Android Studio's bundled JDK

4. Release signing config

Release builds read the upload keystore from android/key.properties, which is gitignored along with *.jks and *.keystore. The key never enters the repo.

Situation Behavior
key.properties complete The release APK/AAB is signed with the upload key
key.properties present but missing fields Build fails, naming the missing keys
No key.properties Falls back to debug keys, so flutter run --release still works, and prints a warning on release builds only

Adds android/key.properties.example and a README "Release builds" section covering keystore generation, backup, and SHA-1 registration.

⚠️ Required before shipping (not in this PR)

Generate the upload keystore and back it up in at least two durable places outside your laptop, and share it with a second maintainer. Enable Play App Signing when you create the app. That makes a lost upload key recoverable through a reset request. Without it, a lost key means a new listing.

Firebase is still bound to the old package server-side (mobilesdk_app_id 1:243422993063:android:97feef…). Push notifications and Google Sign-In will fail in release builds until:

  1. New Android and iOS apps are registered under com.bookbridge.app in the bookbridge-c12fa Firebase project
  2. flutterfire configure is re-run to regenerate google-services.json, GoogleService-Info.plist and firebase_options.dart
  3. A new Google OAuth Android client is created with the new package and the upload key's SHA-1 (and, after the first Play upload, the Play App Signing SHA-1)

Test plan

  • CI passed on a clean GitHub runner (7 min): analyze, 9 tests, debug APK built, APK package: com.bookbridge.app
  • Local flutter build apk --debug from the exact committed state, on a fresh Gradle daemon with no java.home override
  • aapt2 dump badging: package: name='com.bookbridge.app', launchable-activity: com.bookbridge.app.MainActivity
  • The APK's dex contains Lcom/bookbridge/app/MainActivity; and no com/example/book_bridge references
  • flutter pub get --enforce-lockfile passes; actionlint passes on the new workflow
  • flutter analyze: only the 3 pre-existing issues
  • Signing verified with a throwaway keystore: flutter build appbundle --release and build apk --release are both signed by the test cert (apksigner / keytool -printcert SHA-256 matches the keystore)
  • Incomplete key.properties: the build fails with missing: storePassword, keyPassword
  • No key.properties: the release is debug-signed and prints the warning; debug builds print no warning
  • Release build with the real upload key: needs the keystore
  • iOS build: not possible on this Linux machine
  • Visual check of the social and contact icons on the Profile and Contact Us screens

Notes for reviewers

  • Local builds need NDK 28.2.13676358. Locally, sdkmanager delegated to the new android CLI, which stalled with zero bytes downloaded. A direct download from dl.google.com, checked against the SHA-1 in Google's repository2-3.xml, worked. On GitHub runners sdkmanager works fine.
  • Analysis in CI fails on errors only, because 2 warnings already exist. Switch to --fatal-warnings once they're fixed.
  • Once this merges, consider making "Analyze, test, build Android" a required check on dev.
  • Flutter 3.47.5 is out. Bump it separately, so CI checks the upgrade.
  • Kotlin 2.2.20 triggers a "support will soon be dropped" warning. It meets the minimum, so it's left for the AGP 9 migration.

Flutter's scaffold placeholder `com.example.*` is rejected by Google Play
and unsuitable for the App Store. Replace it with the production identifier
`com.bookbridge.app` across every platform target.

- android: applicationId + namespace, and move MainActivity.kt to the
  matching package path (com/bookbridge/app)
- android: google-services.json package_name, which the Google Services
  Gradle plugin requires to match applicationId
- ios/macos: PRODUCT_BUNDLE_IDENTIFIER for app and test targets
- dart: firebase_options.dart iosBundleId, which was also inconsistent
  with the iOS project (com.example.book_bridge vs com.example.bookBridge)
- linux/windows: APPLICATION_ID and company/copyright metadata

This also resolves the pre-existing Android/iOS identifier mismatch, so
all platforms now share a single identifier.

Note: the Firebase Android/iOS apps must be re-registered under the new
identifier and google-services.json regenerated before shipping; the
existing mobilesdk_app_id is still bound server-side to the old package.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@vercel

vercel Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
book-bridge Ready Ready Preview Sep 26, 2026 9:16am UTC

No Android build could complete. Three independent, pre-existing issues
blocked it; each surfaced only after the previous one was fixed.

- AGP 8.7.0 -> 8.13.2. AGP had been downgraded from 8.11.1 in a0026fa,
  below the 8.11.1 minimum enforced by Flutter 3.47. 8.13.2 is the latest
  8.x and avoids the separate AGP 9 migration (new DSL, built-in Kotlin).
- Restore `ndkVersion = flutter.ndkVersion`. It was commented out in
  0e28706, and the `:jni` plugin failed with "NDK not configured". Flutter
  3.47 requires NDK 28.2.13676358.
- font_awesome_flutter ^10.12.0 -> ^11.0.0. 10.x subclasses IconData,
  which is a final class in Flutter 3.47, so Dart compilation failed.
  11.0.0 wraps it in FaIconData instead: FaIcon call sites take
  FaIconData, and plain Icon call sites use `.data`, so rendering is
  unchanged.
- gradle.properties: add `android.builtInKotlin=false` and
  `android.newDsl=false`. Flutter's migrator inserts these before every
  build. They have no effect on AGP 8 and prepare for AGP 9.

Verified: `flutter build apk --debug` succeeds. aapt2 reports package
com.bookbridge.app and launchable activity
com.bookbridge.app.MainActivity, and the dex contains no
com.example.book_bridge references. `flutter analyze` shows only the 3
pre-existing issues.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@DCT-Berinyuy DCT-Berinyuy changed the title chore: rename app identifier from com.example to com.bookbridge.app Rename app identifier to com.bookbridge.app and restore Android build Sep 25, 2026
The Android build was broken for six months without anyone noticing,
because no CI job built it and nothing pinned the toolchain. This
closes those gaps.

- Replace the dead dart.yml with flutter.yml. The old workflow only
  triggered on `main` (work happens on `dev`) and ran `dart analyze` /
  `dart test`, which cannot pass on a Flutter app. The new job runs on
  PRs and pushes to dev/main and does: pub get --enforce-lockfile,
  analyze (fatal on errors), test, `flutter build apk --debug`, and
  asserts the APK's application ID is com.bookbridge.app.
- Pin Flutter 3.47.4 and NDK 28.2.13676358 in CI. The unpinned SDK is
  what silently broke the build (AGP/NDK minimums, final IconData).
- Commit pubspec.lock. It was ignored by a blanket `*.lock` rule, but
  applications should commit their lockfile so every machine and CI
  resolve identical versions. It is scoped to the root only.
- Remove `org.gradle.java.home=/opt/android-studio/jbr`, a machine-local
  path that breaks every other machine and CI runner. Flutter already
  finds Android Studio's bundled JDK and passes it to Gradle.

Verified locally: actionlint passes; `flutter pub get --enforce-lockfile`
succeeds; `flutter test` passes (9/9); `flutter build apk --debug`
succeeds on a fresh Gradle daemon without the java.home override.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@DCT-Berinyuy DCT-Berinyuy changed the title Rename app identifier to com.bookbridge.app and restore Android build Rename app identifier to com.bookbridge.app, restore Android build, add Android CI Sep 26, 2026
Release builds read the upload keystore from android/key.properties,
which is gitignored. An incomplete file fails the build and names the
missing keys. Without the file, release builds fall back to debug keys
and print a warning, so local `flutter run --release` keeps working.

Adds android/key.properties.example and README steps for generating,
backing up, and registering the upload key.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@DCT-Berinyuy DCT-Berinyuy changed the title Rename app identifier to com.bookbridge.app, restore Android build, add Android CI Rename app ID to com.bookbridge.app, restore Android build, add CI and release signing Sep 26, 2026

This branch was successfully deployed

1 active deployment
Preview — 712185fe Deployed Sep 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant