finish android task suite

This commit is contained in:
2026-06-02 08:14:00 -04:00
parent 6c4d77bbec
commit 36b087ae92
57 changed files with 7566 additions and 459 deletions

84
android/scripts/README.md Normal file
View File

@@ -0,0 +1,84 @@
# Android Build Scripts
Scripts for building, signing, and distributing the Kordant Android app.
## Scripts
### `generate-release-key.sh`
Generates a release keystore and configures signing for Google Play.
```bash
chmod +x scripts/generate-release-key.sh
./scripts/generate-release-key.sh
```
Creates:
- `kordant-release.keystore` — The keystore file (KEEP SECURE)
- `key.properties` — Gradle signing credentials (in `.gitignore`)
### `build-release-aab.sh`
Builds a signed Android App Bundle (AAB) for Google Play upload.
```bash
chmod +x scripts/build-release-aab.sh
./scripts/build-release-aab.sh # prodRelease (default)
./scripts/build-release-aab.sh --variant=devRelease
```
Requires:
- `key.properties` configured (copy from `key.properties.template`)
- Android SDK configured in `local.properties`
## Build Variants
| Variant | Application ID | API URL | Use Case |
|---------|---------------|---------|----------|
| `prodRelease` | `com.kordant.android` | `api.kordant.com` | Google Play production |
| `devRelease` | `com.kordant.android.dev` | `10.0.2.2:3000` | Internal testing |
| `prodDebug` | `com.kordant.android.debug` | `api.kordant.com` | Debug with prod config |
| `devDebug` | `com.kordant.android.dev.debug` | `10.0.2.2:3000` | Development |
## Gradle Commands
```bash
# Build release AAB (for Play Store)
./gradlew bundleProdRelease
# Build release APK (for sideloading)
./gradlew assembleProdRelease
# Build debug APK
./gradlew assembleDevDebug
# Run unit tests
./gradlew test
# Run instrumentation tests (requires device/emulator)
./gradlew connectedAndroidTest
# Generate baseline profile (for startup optimization)
./gradlew baselineProfileProdRelease
# Clean build
./gradlew clean
```
## Output Locations
| Build Type | Output Path |
|------------|-------------|
| AAB | `app/build/outputs/bundle/prodRelease/app-prod-release.aab` |
| APK | `app/build/outputs/apk/prod/release/app-prod-release.apk` |
| Test APK | `app/build/outputs/apk/androidTest/prod/debug/app-prod-debug-androidTest.apk` |
| ProGuard mapping | `app/build/outputs/mapping/prodRelease/mapping.txt` |
| Baseline profile | `app/build/outputs/baselineProfiles/prodRelease/baseline-prof.txt` |
## Signing
The app uses Google Play App Signing. The upload key is managed via `key.properties`:
1. Copy template: `cp key.properties.template key.properties`
2. Edit with your credentials
3. Build: `./gradlew bundleProdRelease`
The `key.properties` file is in `.gitignore` and should NEVER be committed.

View File

@@ -0,0 +1,136 @@
#!/usr/bin/env bash
# ============================================================
# Kordant Release AAB Builder
# ============================================================
#
# Builds a signed Android App Bundle (AAB) for Google Play.
#
# Usage:
# ./scripts/build-release-aab.sh
# ./scripts/build-release-aab.sh --variant=prodRelease
# ./scripts/build-release-aab.sh --variant=devRelease
#
# Prerequisites:
# - key.properties configured (see key.properties.template)
# - Android SDK and build tools installed
# - Google Services JSON file in app/ (if using Firebase)
#
# Output:
# - app/build/outputs/bundle/prodRelease/app-prod-release.aab
# - app/build/outputs/bundle/devRelease/app-dev-release.aab
# ============================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
VARIANT="prodRelease"
# Parse arguments
for arg in "$@"; do
case $arg in
--variant=*)
VARIANT="${arg#*=}"
shift
;;
--help|-h)
echo "Usage: $0 [--variant=prodRelease|devRelease]"
echo ""
echo "Options:"
echo " --variant Build variant (default: prodRelease)"
echo " --help Show this help message"
exit 0
;;
esac
done
cd "$PROJECT_DIR"
echo "============================================"
echo " Kordant Release AAB Builder"
echo "============================================"
echo ""
echo "Variant: $VARIANT"
echo ""
# Check for key.properties
if [ ! -f "key.properties" ]; then
echo "ERROR: key.properties not found."
echo ""
echo "Create it from the template:"
echo " cp key.properties.template key.properties"
echo " # Then edit key.properties with your credentials"
echo ""
echo "Or generate a new keystore:"
echo " ./scripts/generate-release-key.sh"
exit 1
fi
# Check for google-services.json (needed for Firebase)
if [ ! -f "app/google-services.json" ]; then
echo "WARNING: google-services.json not found in app/"
echo "Firebase features (FCM, Crashlytics) will not work."
echo "Download from Firebase Console → Project Settings → Your apps"
echo ""
fi
# Run the build
echo "Building $VARIANT..."
echo ""
./gradlew "bundle${VARIANT}" \
--no-daemon \
--parallel \
--build-cache \
-Pandroid.injected.signing.storefile="$(pwd)/kordant-release.keystore" \
2>&1 | tail -50
BUILD_STATUS=$?
if [ $BUILD_STATUS -ne 0 ]; then
echo ""
echo "ERROR: Build failed with exit code $BUILD_STATUS"
echo ""
echo "Common issues:"
echo " 1. key.properties has wrong credentials"
echo " 2. Keystore file missing or corrupted"
echo " 3. Android SDK not configured in local.properties"
echo " 4. google-services.json missing"
exit $BUILD_STATUS
fi
# Find the AAB
AAB_PATH="app/build/outputs/bundle/${VARIANT}/app-${VARIANT}.aab"
if [ -f "$AAB_PATH" ]; then
AAB_SIZE=$(du -h "$AAB_PATH" | cut -f1)
echo ""
echo "✓ Build successful!"
echo ""
echo "AAB: $AAB_PATH"
echo "Size: $AAB_SIZE"
echo ""
echo "Upload to Google Play Console:"
echo " 1. Go to Play Console → Testing → Internal testing"
echo " 2. Click 'Create new release'"
echo " 3. Upload $AAB_PATH"
echo ""
else
echo ""
echo "ERROR: AAB not found at expected path: $AAB_PATH"
echo ""
echo "Looking for any AAB files..."
find app/build/outputs/bundle -name "*.aab" 2>/dev/null || echo "No AAB files found."
exit 1
fi
# Generate bundle report
echo "Bundle contents:"
echo ""
if command -v bundletool &> /dev/null; then
bundletool dump manifest --module-path="$AAB_PATH" --dump-mode=MERGED_MANIFEST 2>/dev/null | head -30 || true
else
echo "(bundletool not installed — install with: sdkmanager \"bundle-tools\")"
fi
echo ""
echo "============================================"

View File

@@ -0,0 +1,157 @@
#!/usr/bin/env bash
# ============================================================
# Kordant Release Keystore Generator
# ============================================================
#
# Generates a release keystore and upload key for Google Play.
# Also creates the key.properties file for Gradle signing.
#
# Usage:
# ./scripts/generate-release-key.sh
#
# Output:
# - kordant-release.keystore (in android/ directory)
# - key.properties (in android/ directory, added to .gitignore)
#
# Security:
# - Store the keystore in a secure location (password manager, HSM)
# - Back up the keystore — losing it means losing ability to update the app
# - The upload key is ONLY for uploading to Play Console
# - Google Play App Signing manages the actual app signing key
# ============================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
KEYSTORE_PATH="$PROJECT_DIR/kordant-release.keystore"
KEY_PROPS_PATH="$PROJECT_DIR/key.properties"
KEY_ALIAS="kordant-release-key"
KEY_VALIDITY=25550 # ~70 years (max for Java keytool)
echo "============================================"
echo " Kordant Release Keystore Generator"
echo "============================================"
echo ""
# Check if keytool is available
if ! command -v keytool &> /dev/null; then
echo "ERROR: keytool not found. Install Java JDK."
exit 1
fi
# Check if keystore already exists
if [ -f "$KEYSTORE_PATH" ]; then
echo "WARNING: Keystore already exists at $KEYSTORE_PATH"
echo ""
read -p "Overwrite existing keystore? (y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Aborted. Keystore not overwritten."
exit 0
fi
fi
# Collect keystore information
echo "Enter keystore details:"
echo ""
read -p " Keystore password: " STORE_PASSWORD
read -p " Confirm password: " STORE_PASSWORD_CONFIRM
if [ "$STORE_PASSWORD" != "$STORE_PASSWORD_CONFIRM" ]; then
echo "ERROR: Passwords do not match."
exit 1
fi
read -p " Key password (enter for same as keystore): " KEY_PASSWORD
KEY_PASSWORD="${KEY_PASSWORD:-$STORE_PASSWORD}"
read -p " Your name: " CN
read -p " Organization unit (OU): " OU
read -p " Organization (O): " O
read -p " City/Locality (L): " L
read -p " State/Province (ST): " ST
read -p " Country code (C, e.g., US): " C
# Generate the keystore
echo ""
echo "Generating keystore..."
keytool -genkeypair \
-v \
-keystore "$KEYSTORE_PATH" \
-alias "$KEY_ALIAS" \
-keyalg RSA \
-keysize 2048 \
-sigalg SHA256withRSA \
-storetype JKS \
-storepass "$STORE_PASSWORD" \
-keypass "$KEY_PASSWORD" \
-validity "$KEY_VALIDITY" \
-dname "CN=$CN, OU=$OU, O=$O, L=$L, ST=$ST, C=$C"
echo ""
echo "✓ Keystore generated: $KEYSTORE_PATH"
# Extract the public key hash for Google Play App Signing
echo ""
echo "Extracting certificate fingerprint..."
CERT_SHA256=$(keytool -list -v \
-keystore "$KEYSTORE_PATH" \
-alias "$KEY_ALIAS" \
-storepass "$STORE_PASSWORD" \
-keypass "$KEY_PASSWORD" \
2>/dev/null | grep "SHA256:" | awk '{print $2}')
echo " SHA-256: $CERT_SHA256"
# Generate key.properties
echo ""
echo "Creating key.properties..."
cat > "$KEY_PROPS_PATH" << EOF
# ============================================================
# Kordant Release Keystore Configuration
# Auto-generated on $(date -u +"%Y-%m-%dT%H:%M:%SZ")
# ============================================================
#
# IMPORTANT: This file contains sensitive credentials.
# NEVER commit this file to version control.
# ============================================================
storeFile=../kordant-release.keystore
storePassword=$STORE_PASSWORD
keyAlias=$KEY_ALIAS
keyPassword=$KEY_PASSWORD
EOF
echo "✓ key.properties created: $KEY_PROPS_PATH"
# Verify the keystore
echo ""
echo "Verifying keystore..."
keytool -list -v \
-keystore "$KEYSTORE_PATH" \
-storepass "$STORE_PASSWORD" \
2>/dev/null | head -20
echo ""
echo "============================================"
echo " Next Steps"
echo "============================================"
echo ""
echo "1. Back up the keystore securely:"
echo " - Store in password manager (1Password, Bitwarden, etc.)"
echo " - Keep an offline copy in a safe"
echo " - DO NOT commit to version control"
echo ""
echo "2. Upload to Google Play Console:"
echo " - Go to Play Console → Setup → App integrity → App signing"
echo " - Upload the keystore or its certificate"
echo " - Enable Google Play App Signing"
echo ""
echo "3. Build the release AAB:"
echo " cd android && ./gradlew bundleProdRelease"
echo ""
echo "4. Upload the AAB to Play Console:"
echo " - Play Console → Testing → Internal testing → Create release"
echo " - Upload app/bundle/release/app-prod-release.aab"
echo ""
echo "============================================"