#!/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 "============================================"