feat: implement Android app signing setup and update .gitignore for keystore files
This commit is contained in:
8
android/.gitignore
vendored
8
android/.gitignore
vendored
@@ -52,10 +52,10 @@ captures/
|
|||||||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||||
.idea/navEditor.xml
|
.idea/navEditor.xml
|
||||||
|
|
||||||
# Keystore files
|
# Keystore files - NEVER commit these!
|
||||||
# Uncomment the following lines if you do not want to check your keystore files in.
|
*.jks
|
||||||
#*.jks
|
*.keystore
|
||||||
#*.keystore
|
keystore.properties
|
||||||
|
|
||||||
# External native build folder generated in Android Studio 2.2 and later
|
# External native build folder generated in Android Studio 2.2 and later
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
|
|||||||
61
android/SIGNING_SETUP.md
Normal file
61
android/SIGNING_SETUP.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Android App Signing Setup
|
||||||
|
|
||||||
|
## Why This Matters
|
||||||
|
Android requires apps to be signed with the same key for updates to work. Without proper signing, users cannot update your app - they must uninstall and reinstall, losing all data.
|
||||||
|
|
||||||
|
## Setup Instructions
|
||||||
|
|
||||||
|
### 1. Create a Keystore (if you don't have one)
|
||||||
|
|
||||||
|
Run this command in the `android/` directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
keytool -genkey -v -keystore paarrot-release.keystore -alias paarrot -keyalg RSA -keysize 2048 -validity 10000
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll be asked for:
|
||||||
|
- Keystore password (remember this!)
|
||||||
|
- Key password (remember this!)
|
||||||
|
- Your name, organization, etc.
|
||||||
|
|
||||||
|
**IMPORTANT**: Back up this keystore file and remember the passwords! If you lose either, you cannot update your app.
|
||||||
|
|
||||||
|
### 2. Create keystore.properties
|
||||||
|
|
||||||
|
Copy the example file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp keystore.properties.example keystore.properties
|
||||||
|
```
|
||||||
|
|
||||||
|
Then edit `keystore.properties` and fill in:
|
||||||
|
- `storeFile`: path to your keystore (e.g., `paarrot-release.keystore`)
|
||||||
|
- `storePassword`: the keystore password you set
|
||||||
|
- `keyAlias`: the alias (e.g., `paarrot`)
|
||||||
|
- `keyPassword`: the key password you set
|
||||||
|
|
||||||
|
### 3. Verify
|
||||||
|
|
||||||
|
The file `keystore.properties` should be gitignored (check `.gitignore`).
|
||||||
|
|
||||||
|
### 4. Build
|
||||||
|
|
||||||
|
Now your release builds will be properly signed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd android
|
||||||
|
./gradlew assembleRelease
|
||||||
|
```
|
||||||
|
|
||||||
|
The signed APK will be in: `app/build/outputs/apk/release/`
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "Updates not installing"
|
||||||
|
- You're using a different keystore than the original APK
|
||||||
|
- Solution: Use the same keystore that was used for the first release
|
||||||
|
|
||||||
|
### "keystore.properties not found"
|
||||||
|
- Normal for debug builds
|
||||||
|
- Only needed for release builds
|
||||||
|
- Create the file following step 2 above
|
||||||
@@ -1,9 +1,28 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
|
// Load keystore properties
|
||||||
|
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.paarrot.app"
|
namespace = "com.paarrot.app"
|
||||||
compileSdk = rootProject.ext.compileSdkVersion
|
compileSdk = rootProject.ext.compileSdkVersion
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
storeFile file(keystoreProperties['storeFile'])
|
||||||
|
storePassword keystoreProperties['storePassword']
|
||||||
|
keyAlias keystoreProperties['keyAlias']
|
||||||
|
keyPassword keystoreProperties['keyPassword']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.paarrot.app"
|
applicationId "com.paarrot.app"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
@@ -21,6 +40,9 @@ android {
|
|||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
|
|||||||
14
android/keystore.properties.example
Normal file
14
android/keystore.properties.example
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copy this file to keystore.properties and fill in your actual values
|
||||||
|
# NEVER commit keystore.properties to git!
|
||||||
|
|
||||||
|
# Path to your keystore file (relative to android/ directory)
|
||||||
|
storeFile=paarrot-release.keystore
|
||||||
|
|
||||||
|
# Keystore password
|
||||||
|
storePassword=your_keystore_password_here
|
||||||
|
|
||||||
|
# Key alias
|
||||||
|
keyAlias=paarrot
|
||||||
|
|
||||||
|
# Key password
|
||||||
|
keyPassword=your_key_password_here
|
||||||
Reference in New Issue
Block a user