7.0 KiB
Releasing Sauci Mobile App
This guide covers local release builds for Android and iOS.
Prerequisites
- Java JDK 17 - Required for Android Gradle builds
- Android Studio - For SDK and build tools (including Android SDK/NDK)
- Xcode - For iOS builds (macOS only)
- EAS CLI -
npm install -g eas-cli - Expo account - Run
eas loginto authenticate
EAS Build Local (Recommended)
The --local flag runs the EAS build process on your machine instead of Expo's cloud servers. This automatically handles signing credentials and produces the same output as cloud builds.
Quick Start
cd apps/mobile
# Android - produces .aab file (for Play Store)
eas build --platform android --profile production --local
# iOS - produces .ipa file (for App Store)
eas build --platform ios --profile production --local
Output files are placed in the current directory by default.
Building an APK (for Testing)
The production profile creates an AAB (Android App Bundle), which can't be directly installed on devices. To build an APK for testing:
# Use the preview profile (configured for APK output)
eas build --platform android --profile preview --local
Or add a custom profile to eas.json:
{
"build": {
"local-apk": {
"android": {
"buildType": "apk"
}
}
}
}
Then run:
eas build --platform android --profile local-apk --local
Installing the APK
# Via ADB (device connected via USB)
adb install ./build-*.apk
# Or drag-and-drop onto Android Emulator
Build Profiles
| Profile | Output | Use Case |
|---|---|---|
production |
.aab | Play Store / App Store submission |
preview |
.apk | Internal testing, device installation |
development |
.apk | Dev client with hot reload |
Environment Variables
Useful for debugging build issues:
| Variable | Purpose |
|---|---|
EAS_LOCAL_BUILD_SKIP_CLEANUP=1 |
Keep build directory after completion |
EAS_LOCAL_BUILD_WORKINGDIR=/path |
Custom build directory (default: /tmp) |
EAS_LOCAL_BUILD_ARTIFACTS_DIR=/path |
Output directory for build artifacts |
Example with debugging enabled:
EAS_LOCAL_BUILD_SKIP_CLEANUP=1 \
EAS_LOCAL_BUILD_WORKINGDIR=~/eas-builds \
eas build --platform android --profile production --local
Limitations of Local Builds
- Single platform only - Can't use
--platform all - Software versions ignored -
node,yarn,ndk,imagefields in eas.json are ignored - No caching - Each build starts fresh
- Secret env vars not available - Set them in your local environment instead
- macOS/Linux only - Windows requires WSL (unsupported)
Troubleshooting Local Builds
Java version mismatch:
# Check Java version (should be 17)
java -version
# On macOS, switch Java version
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
Gradle daemon issues:
cd android && ./gradlew --stop && cd ..
Clean build after dependency changes:
# Remove native folders and rebuild
rm -rf android ios
npx expo prebuild --clean
eas build --platform android --profile production --local
Out of memory:
# Increase Gradle memory
echo "org.gradle.jvmargs=-Xmx4g" >> android/gradle.properties
Manual Android Release Build
Step 1: Get the Production Keystore
The production keystore is stored in EAS. Download it:
cd apps/mobile
eas credentials --platform android
Select:
productionKeystoreDownload Keystore
Save the keystore file and note the password and alias shown.
Step 2: Configure Signing
Ensure android/gradle.properties has the keystore configuration:
MYAPP_UPLOAD_STORE_FILE=sauci-release.keystore
MYAPP_UPLOAD_KEY_ALIAS=<alias from EAS>
MYAPP_UPLOAD_STORE_PASSWORD=<password from EAS>
MYAPP_UPLOAD_KEY_PASSWORD=<password from EAS>
Important: Never commit these credentials to git.
Step 3: Prebuild (if needed)
If the android/ folder doesn't exist or native dependencies changed:
npx expo prebuild --platform android --clean
Step 4: Build the Release Bundle
cd android
./gradlew bundleRelease
The AAB file will be at:
android/app/build/outputs/bundle/release/app-release.aab
Step 5: Upload to Play Store
- Go to Google Play Console
- Select Sauci app
- Go to Production (or testing track)
- Create new release
- Upload the
.aabfile - Add release notes and submit
Verifying Keystore Fingerprint
To verify you're using the correct keystore:
keytool -list -v -keystore android/sauci-release.keystore -storepass <password>
Expected SHA1: C3:70:C5:8C:85:E5:B5:92:97:82:A9:B0:47:98:40:99:AC:C8:47:43
iOS Release Build
Step 1: Prebuild (if needed)
npx expo prebuild --platform ios --clean
Step 2: Install Pods
cd ios
pod install
cd ..
Step 3: Build Archive in Xcode
- Open
ios/Sauci.xcworkspacein Xcode - Select Any iOS Device (arm64) as the build target
- Go to Product → Archive
- Wait for the build to complete
Step 4: Upload to App Store
- In Xcode Organizer (Window → Organizer), select the archive
- Click Distribute App
- Select App Store Connect → Upload
- Follow the prompts to upload
Step 5: Submit in App Store Connect
- Go to App Store Connect
- Select Sauci
- Create a new version or select the uploaded build
- Fill in release notes and submit for review
Version Management
Version is managed by EAS with appVersionSource: "remote" in eas.json.
To sync or bump versions:
# Check current version
eas build:version:get
# Set version manually
eas build:version:set --platform android --version 1.0.1
eas build:version:set --platform ios --version 1.0.1
For local builds, you may need to update app.json version manually:
{
"expo": {
"version": "1.0.1"
}
}
And for Android, update android/app/build.gradle:
versionCode 2
versionName "1.0.1"
Troubleshooting
Wrong Keystore Error
If Play Store rejects with "signed with wrong key":
- Run
eas credentials --platform android - Download the correct keystore
- Verify fingerprint matches expected SHA1
- Replace your local keystore file
Build Failures After Dependency Changes
# Clean and rebuild
cd android && ./gradlew clean && cd ..
npx expo prebuild --platform android --clean
cd android && ./gradlew bundleRelease
iOS Signing Issues
Ensure your Apple Developer certificates and provisioning profiles are up to date in Xcode:
- Xcode → Settings → Accounts → Download Manual Profiles