# GitHub Actions Setup Guide This guide explains how to set up the GitHub Actions workflow for automated APK builds with proper signing. ## Overview The workflow in `.github/workflows/build-production-apk.yml` automatically: - Builds signed APKs on every push to `main` - Generates version numbers using `YYYY.MM.DD` + build number - Creates 3 APK variants (universal, arm64-v8a, armeabi-v7a) - Creates GitHub releases with all APKs attached ## Prerequisites - GitHub CLI (`gh`) installed - Java 17+ installed (for keytool) - Git repository initialized with GitHub remote ## Step 1: Generate Signing Keystore ⚠️ **IMPORTANT**: Store the keystore securely! Without it, you cannot publish updates to your app. ```bash # Navigate to project root cd /path/to/simple-notes-sync # Generate keystore (replace values as needed) keytool -genkey -v \ -keystore android/app/simple-notes-release.jks \ -keyalg RSA \ -keysize 2048 \ -validity 10000 \ -alias simple-notes # You will be prompted for: # - Keystore password (remember this!) # - Key password (remember this!) # - Your name, organization, etc. ``` **Store these securely:** - Keystore password - Key password - Alias: `simple-notes` - Keystore file: `android/app/simple-notes-release.jks` ⚠️ **BACKUP**: Make a backup of the keystore file in a secure location (NOT in the repository). ## Step 2: Base64 Encode Keystore ```bash # Create base64 encoded version base64 android/app/simple-notes-release.jks > simple-notes-release.jks.b64 # Or on macOS: base64 -i android/app/simple-notes-release.jks -o simple-notes-release.jks.b64 ``` ## Step 3: Set GitHub Secrets Using GitHub CLI (recommended): ```bash # Set KEYSTORE_BASE64 secret gh secret set KEYSTORE_BASE64 < simple-notes-release.jks.b64 # Set KEYSTORE_PASSWORD (will prompt for input) gh secret set KEYSTORE_PASSWORD # Set KEY_PASSWORD (will prompt for input) gh secret set KEY_PASSWORD # Set KEY_ALIAS (value: simple-notes) printf "simple-notes" | gh secret set KEY_ALIAS ``` Or manually via GitHub web interface: 1. Go to repository Settings → Secrets and variables → Actions 2. Click "New repository secret" 3. Add these secrets: - `KEYSTORE_BASE64`: Paste content of `simple-notes-release.jks.b64` - `KEYSTORE_PASSWORD`: Your keystore password - `KEY_PASSWORD`: Your key password - `KEY_ALIAS`: `simple-notes` ## Step 4: Verify Setup ```bash # Check secrets are set gh secret list # Expected output: # KEYSTORE_BASE64 Updated YYYY-MM-DD # KEYSTORE_PASSWORD Updated YYYY-MM-DD # KEY_PASSWORD Updated YYYY-MM-DD # KEY_ALIAS Updated YYYY-MM-DD ``` ## Step 5: Cleanup ```bash # Remove sensitive files (they're in .gitignore, but double-check) rm simple-notes-release.jks.b64 rm -f android/key.properties # Generated by workflow # Verify keystore is NOT tracked by git git status | grep -i jks # Should return nothing ``` ## Step 6: Trigger First Build ```bash # Commit and push to main git add . git commit -m "🚀 feat: Add GitHub Actions deployment workflow" git push origin main # Or manually trigger workflow gh workflow run build-production-apk.yml ``` ## Verification 1. Go to GitHub repository → Actions tab 2. Check workflow run status 3. Once complete, go to Releases tab 4. Verify release was created with 3 APK variants 5. Download and test one of the APKs ## Troubleshooting ### Build fails with "Keystore not found" - Check `KEYSTORE_BASE64` secret is set correctly - Verify base64 encoding was done without line breaks ### Build fails with "Incorrect password" - Verify `KEYSTORE_PASSWORD` and `KEY_PASSWORD` are correct - Re-set secrets if needed ### APK files not found - Check build logs for errors in assembleRelease step - Verify APK output paths match workflow expectations ### Updates don't work - Ensure you're using the same keystore for all builds - Verify `applicationId` in build.gradle.kts matches ## Security Notes - ✅ Keystore is base64-encoded in GitHub secrets (secure) - ✅ Passwords are stored in GitHub secrets (encrypted) - ✅ `key.properties` and `.jks` files are in `.gitignore` - ⚠️ Never commit keystore files to repository - ⚠️ Keep backup of keystore in secure location - ⚠️ Don't share keystore passwords ## Versioning Versions follow this pattern: - **Version Name**: `YYYY.MM.DD` (e.g., `2025.01.15`) - **Version Code**: GitHub run number (e.g., `42`) - **Release Tag**: `vYYYY.MM.DD-prod.BUILD` (e.g., `v2025.01.15-prod.42`) This ensures: - Semantic versioning based on release date - Incremental version codes for Play Store compatibility - Clear distinction between builds ## APK Variants The workflow generates 3 APK variants: 1. **Universal APK** (~5 MB) - Works on all devices - Larger file size - Recommended for most users 2. **arm64-v8a APK** (~3 MB) - For modern devices (2018+) - Smaller, faster - 64-bit ARM processors 3. **armeabi-v7a APK** (~3 MB) - For older devices - 32-bit ARM processors Users can choose based on their device - Obtanium auto-updates work with all variants.