Skip to content

feat(mobile): sign Android releases with the operator's key - #763

Merged
Medformatik merged 1 commit into
mainfrom
feat/mobile-android-release-signing
Nov 3, 2026
Merged

Medformatik merged 1 commit into
mainfrom
feat/mobile-android-release-signing

Conversation

@Medformatik

Copy link
Copy Markdown
Collaborator

What changed and why

Release builds of the Android app were signed with the wrong key. Expo's generated app/build.gradle signs the release build type with the template's debug.keystore, whose password is public, and release/build-android.mts copied the operator's signing properties into the project without Gradle ever reading them. The release docs listed this as an open gap.

  • Signing. A release prebuild now signs releases from release-signing.properties, the copy of the operator's mode-0600 file outside the repository. Without that file the release is unsigned; it never falls back to the debug key. A properties file missing a key fails the build and names the key. Development builds keep Expo's default, so contributors can still install a local release variant.
  • Signed APK for test phones. pnpm mobile:release:android --apk builds a signed APK instead of the AAB, to install directly on a phone. --unsigned now removes a signing copy left by an earlier build, and finds Gradle's app-release-unsigned.apk.
  • Docs. mobile-release.md describes the signing behaviour, the --apk option and using a separate local test key rather than the upload key.

Verification

  • apps/mobile vitest for the plugin: 40 passed, including 5 new tests for the transform (signs from the properties file, never with the debug key, debug type unchanged, idempotent, refuses an unrecognised build file). tsc, biome.
  • Release prebuild for Android, then --apk with a local test key. apksigner verify shows the test key's certificate; the APK holds the JS bundle and identifies as org.openmapx.app 1.0.0. None of its 1,183 entries contains signing material.
  • Installed on a Pixel (Android 17): the app starts without Metro, loads openmapx.com, and sign-in opens openmapx.com in the system browser.
  • The release config requires an Apple Team ID even for Android. I passed a placeholder; it only feeds iOS entitlements, and no APK entry contains it.
  • Not checked: the AAB path and iOS.

Release and upgrade impact

Product impact: ordinary

Expo's generated app/build.gradle signs the release build type with the
template's debug.keystore, whose password is public, and the release script
copied the signing properties into the project without Gradle reading them.

A release prebuild now signs releases from release-signing.properties, and
leaves them unsigned when that file is absent, never falling back to the
debug key. Development builds keep Expo's default. The release script gains
--apk for a signed APK to install on a test phone, removes a stale signing
copy for --unsigned, and finds Gradle's -unsigned APK name.
@Medformatik
Medformatik merged commit 7421c56 into main Nov 3, 2026
23 checks passed
@Medformatik
Medformatik deleted the feat/mobile-android-release-signing branch November 3, 2026 23:59
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant