agentsclimarketplace

Mobile deployment

Skill JaveedIshaq/ai-workflow-orchestrator/skills/ballee/mobile-deployment

Reusable Claude Code skills and agents for e-commerce, analytics, development, and project-specific workflowsFrom the repository description

Install
npx -y skills add JaveedIshaq/ai-workflow-orchestrator --skill mobile-deployment

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

14.7 KB, as published. Nobody here has run it

Mobile Deployment Skill

Comprehensive guide for deploying the Ballee mobile app to iOS (TestFlight/App Store) and Android (Play Store).

Overview

PlatformCI/CDLocal DeployDistribution
iOSXcode CloudFastlane / xcodebuildTestFlight, App Store
AndroidGitHub ActionsFastlane / GradleFirebase App Distribution, Play Store

Prerequisites

iOS Prerequisites

  1. Apple Developer Account with distribution certificate
  2. App Store Connect API Key at ~/.appstoreconnect/private_keys/AuthKey_LGU934Y2XR.p8
  3. Xcode installed with command line tools
  4. Ruby & Bundler for Fastlane
  5. CocoaPods for iOS dependencies

Key Identifiers:

ItemValue
Bundle IDco.ballee
Team IDA86CXY8H75
API Key IDLGU934Y2XR
API Issuer ID69a6de96-5d75-47e3-e053-5b8c7c11a4d1
Apple ID[email protected]

Android Prerequisites

  1. Release Keystore configured in apps/mobile/android/key.properties
  2. Google Play Console access with service account
  3. Java 11+ and Android SDK
  4. Flutter SDK installed

Key Identifiers:

ItemValue
Package Nameco.ballee
Min SDK24

iOS Deployment

Option 1: Xcode Cloud (Automated - Recommended)

Xcode Cloud automatically builds and deploys to TestFlight on push to main.

Trigger a build manually:

cd apps/mobile/ios/scripts
python3 xcode_cloud_cli.py trigger

Check build status:

python3 xcode_cloud_cli.py list

Environment variables (set in Xcode Cloud):

VariableDescription
SUPABASE_URLProduction Supabase URL
SUPABASE_ANON_KEYProduction anon key
SENTRY_DSNSentry DSN for crash reporting
MIXPANEL_TOKENAnalytics token
APP_STORE_CONNECT_API_KEY_IDAPI key ID
APP_STORE_CONNECT_API_ISSUER_IDIssuer ID
APP_STORE_CONNECT_API_KEY_CONTENTBase64-encoded .p8 key

CI Scripts:

  • ci_post_clone.sh - Installs Flutter, builds iOS app, runs code generation
  • ci_post_xcodebuild.sh - Uploads to TestFlight, uploads dSYMs to Sentry

Option 2: Fastlane (Local)

Setup (first time):

cd apps/mobile/ios
bundle install

Deploy to TestFlight:

cd apps/mobile/ios

# Option A: Manual signing (uses match provisioning profiles)
bundle exec fastlane beta

# Option B: Automatic signing (uses Xcode managed signing)
bundle exec fastlane beta_auto

# Option C: Build only (no upload)
bundle exec fastlane build_only

Available Lanes:

LaneDescription
betaBuild with manual signing + upload to TestFlight
beta_autoBuild with automatic signing + upload to TestFlight
build_onlyBuild IPA without uploading

Increment build number:

bundle exec fastlane beta increment_build:true

Option 3: Manual xcodebuild

Step 1: Build Flutter app

cd apps/mobile
flutter pub get
dart run build_runner build --delete-conflicting-outputs
flutter build ios --release --no-codesign \
    --dart-define=ENV=prod \
    --dart-define=BACKEND_URL="https://csjruhqyqzzqxnfeyiaf.supabase.co" \
    --dart-define=SUPABASE_TOKEN="$SUPABASE_ANON_KEY"

Step 2: Install pods

cd ios
pod install --repo-update

Step 3: Archive

xcodebuild -workspace Ballee.xcworkspace \
    -scheme Ballee \
    -sdk iphoneos \
    -configuration Release \
    -archivePath build/Ballee.xcarchive \
    archive

Step 4: Export and upload

xcodebuild -exportArchive \
    -archivePath build/Ballee.xcarchive \
    -exportOptionsPlist ExportOptions.plist \
    -exportPath build/export \
    -allowProvisioningUpdates \
    -authenticationKeyPath ~/.appstoreconnect/private_keys/AuthKey_LGU934Y2XR.p8 \
    -authenticationKeyID LGU934Y2XR \
    -authenticationKeyIssuerID 69a6de96-5d75-47e3-e053-5b8c7c11a4d1

iOS Quick Deploy Script

Use the provided script for one-command deployment:

./.claude/skills/mobile-deployment/scripts/deploy-ios.sh

Options:

  • --increment - Increment build number
  • --skip-upload - Build only, don't upload

Android Deployment

Setting Up Release Signing

Step 1: Create keystore (if needed)

./.claude/skills/mobile-deployment/scripts/setup-android-signing.sh

Or manually:

keytool -genkey -v \
    -keystore ~/ballee-release-key.jks \
    -keyalg RSA \
    -keysize 2048 \
    -validity 10000 \
    -alias ballee

Step 2: Create key.properties Create apps/mobile/android/key.properties:

storePassword=<keystore password>
keyPassword=<key password>
keyAlias=ballee
storeFile=/path/to/ballee-release-key.jks

Step 3: Enable release signing Uncomment the signing config in apps/mobile/android/app/build.gradle.kts:

signingConfigs {
    create("release") {
        keyAlias = keystoreProperties["keyAlias"] as String
        keyPassword = keystoreProperties["keyPassword"] as String
        storeFile = keystoreProperties["storeFile"]?.let { file(it) }
        storePassword = keystoreProperties["storePassword"] as String
    }
}

buildTypes {
    release {
        signingConfig = signingConfigs.getByName("release")
    }
}

Building Release APK/AAB

Build AAB (for Play Store):

cd apps/mobile
flutter build appbundle --release \
    --dart-define=ENV=prod \
    --dart-define=BACKEND_URL="https://csjruhqyqzzqxnfeyiaf.supabase.co" \
    --dart-define=SUPABASE_TOKEN="$SUPABASE_ANON_KEY"

Output: build/app/outputs/bundle/release/app-release.aab

Build APK (for direct install/testing):

flutter build apk --release \
    --dart-define=ENV=prod \
    --dart-define=BACKEND_URL="https://csjruhqyqzzqxnfeyiaf.supabase.co" \
    --dart-define=SUPABASE_TOKEN="$SUPABASE_ANON_KEY"

Output: build/app/outputs/flutter-apk/app-release.apk

Fastlane for Android

Setup (first time):

cd apps/mobile/android
bundle install

Available Lanes:

LaneDescription
build_apkBuild release APK
build_aabBuild release AAB
firebaseBuild and deploy to Firebase App Distribution
playstoreBuild and upload to Play Store (internal track)

Deploy to Firebase App Distribution:

bundle exec fastlane firebase

Deploy to Play Store:

bundle exec fastlane playstore

Manual Play Store Upload

  1. Go to Google Play Console
  2. Select "Ballee" app
  3. Go to Release > Production (or Testing tracks)
  4. Create new release
  5. Upload the AAB file from build/app/outputs/bundle/release/app-release.aab
  6. Add release notes
  7. Review and roll out

Android Quick Deploy Script

Use the provided script for one-command deployment:

./.claude/skills/mobile-deployment/scripts/deploy-android.sh

Options:

  • --apk - Build APK instead of AAB
  • --firebase - Deploy to Firebase App Distribution
  • --playstore - Deploy to Play Store

Android CI/CD with GitHub Actions

Overview

Android deployments are fully automated via GitHub Actions with:

  • Workload Identity Federation for keyless Google Cloud authentication
  • Automatic builds on push to main and dev
  • Firebase App Distribution for internal testing
  • Play Store deployment on version tags
  • Staged production rollouts (10% → 50% → 100%)

Workflow Triggers

TriggerAction
Push to devBuild and validate
Push to mainBuild + Deploy to Firebase
PR to main/devBuild and validate
Tag v*.*.*Build + Deploy to Play Store (internal)
Tag release/*Promote to Production (10% rollout)
Manual dispatchConfigurable deployment

Setup Scripts

Run these scripts to set up Android CI/CD:

# 1. Create release keystore and local key.properties
./scripts/setup-android-keystore.sh

# 2. Set up Workload Identity Federation (requires gcloud CLI)
./scripts/setup-gcloud-wif.sh

# 3. Configure GitHub repository secrets
./scripts/setup-android-secrets.sh

Required GitHub Secrets

SecretDescriptionHow to Obtain
ANDROID_KEYSTORE_BASE64Base64-encoded keystoreopenssl base64 < keystore.jks
ANDROID_KEYSTORE_PASSWORDKeystore passwordSet during keystore creation
ANDROID_KEY_ALIASKey aliasUsually ballee
ANDROID_KEY_PASSWORDKey passwordSet during keystore creation
SUPABASE_URLProduction Supabase URL.env.local
SUPABASE_ANON_KEYProduction anon key.env.local
FIREBASE_APP_ID_ANDROIDFirebase App IDFirebase Console
FIREBASE_SERVICE_ACCOUNTFirebase SA JSONFirebase Console
PLAY_STORE_SERVICE_ACCOUNTPlay Store SA JSONGoogle Play Console

Workload Identity Federation (Keyless Auth)

Instead of storing long-lived service account JSON keys, we use OIDC-based keyless authentication:

  • No secrets to rotate - Short-lived credentials (1 hour expiry)
  • Fine-grained scoping - Restricted to specific repository/branch
  • Google's recommended approach - More secure than service account keys

The setup-gcloud-wif.sh script automates the WIF setup:

  1. Creates Workload Identity Pool
  2. Creates OIDC Provider for GitHub
  3. Creates service account with proper IAM bindings

Manual Workflow Trigger

Trigger a deployment manually via GitHub CLI:

# Deploy to Firebase
gh workflow run android-deploy.yml -f deploy_target=firebase

# Deploy to Play Store (internal)
gh workflow run android-deploy.yml -f deploy_target=playstore-internal

# Promote to production
gh workflow run android-deploy.yml -f deploy_target=playstore-production

Staged Rollouts

Production releases use staged rollouts for safety:

# Promote with 10% rollout (default)
fastlane promote_to_production

# Increase to 50%
fastlane increase_rollout rollout:0.5

# Full rollout
fastlane increase_rollout rollout:1.0

CI/CD Files

FilePurpose
.github/workflows/android-deploy.ymlMain CI/CD workflow
scripts/setup-android-keystore.shKeystore creation script
scripts/setup-gcloud-wif.shWorkload Identity Federation setup
scripts/setup-android-secrets.shGitHub secrets configuration

First-Time Setup Checklist

  1. Run ./scripts/setup-android-keystore.sh to create keystore
  2. Back up keystore file to 1Password
  3. Run ./scripts/setup-gcloud-wif.sh (requires gcloud CLI)
  4. Link service account in Google Play Console (Settings → API access)
  5. Run ./scripts/setup-android-secrets.sh to configure GitHub
  6. Do first manual Play Store release (Google requirement)
  7. Test workflow with manual dispatch

Environment Variables

Production Environment

All environment variables are passed via --dart-define at build time:

VariableDescriptioniOSAndroid
ENVEnvironment (prod, staging, dev)YesYes
BACKEND_URLSupabase URLYesYes
SUPABASE_TOKENSupabase anon keyYesYes
SENTRY_DSNSentry DSNYesYes
MIXPANEL_TOKENMixpanel tokenYesYes
APP_STORE_IDApp Store ID (iOS only)YesNo

Production Values

SUPABASE_URL="https://csjruhqyqzzqxnfeyiaf.supabase.co"
SUPABASE_ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNzanJ1aHF5cXp6cXhuZmV5aWFmIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTgzNDkxOTQsImV4cCI6MjA3MzkyNTE5NH0.wyDYf6UpJr2trbGOzWx-Sf0p5pSbnTWcQOCFnvtN5lI"

File Reference

iOS Files

FilePurpose
apps/mobile/ios/fastlane/FastfileFastlane lane definitions
apps/mobile/ios/fastlane/AppfileApp Store Connect config
apps/mobile/ios/GemfileRuby dependencies
apps/mobile/ios/ci_scripts/ci_post_clone.shXcode Cloud setup script
apps/mobile/ios/ci_scripts/ci_post_xcodebuild.shPost-build upload script
apps/mobile/ios/scripts/xcode_cloud_cli.pyCLI for Xcode Cloud API
apps/mobile/ios/ExportOptions.plistExport configuration
apps/mobile/ios/Ballee/Info.plistApp configuration

Android Files

FilePurpose
apps/mobile/android/app/build.gradle.ktsGradle build config
apps/mobile/android/key.propertiesSigning credentials (not in git)
apps/mobile/android/fastlane/FastfileFastlane lane definitions
apps/mobile/android/fastlane/AppfilePlay Store config

Troubleshooting

iOS Issues

"Preparing build for App Store Connect failed" (Xcode Cloud)

  • This is often an Apple infrastructure issue
  • Try changing Xcode version in workflow settings
  • Fallback: Use local Fastlane deployment

"No signing certificate found" / "Revoked certificate"

  • Check Xcode > Settings > Accounts for valid certificates
  • Create new distribution certificate in Apple Developer Portal
  • For Xcode Cloud: Certificates are managed automatically

"Missing purpose string in Info.plist"

  • Add required NS*UsageDescription keys to Info.plist
  • Common ones: NSPhotoLibraryUsageDescription, NSCameraUsageDescription

Podfile.lock out of sync

cd apps/mobile/ios
rm -rf Pods Podfile.lock
pod install --repo-update

Build number already exists

# Increment via Fastlane
bundle exec fastlane beta increment_build:true

# Or manually in Xcode
# Ballee.xcodeproj > Build Settings > Current Project Version

Android Issues

"Keystore was tampered with, or password was incorrect"

  • Verify passwords in key.properties match keystore
  • Regenerate keystore if lost

"No key with alias 'ballee' found in keystore"

  • Check keyAlias in key.properties matches alias used during keystore creation

Release build not signed

  • Ensure key.properties exists and paths are correct
  • Uncomment signing config in build.gradle.kts

App crashes on release but not debug

  • Check ProGuard/R8 rules
  • Verify environment variables are passed correctly

General Flutter Issues

"pub get failed"

flutter clean
flutter pub get

"build_runner failed"

dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs

Related Skills

  • xcode-cloud-cicd - Detailed Xcode Cloud CI/CD documentation
  • flutter-development - Flutter development patterns
  • flutter-testing - Testing patterns for mobile

Quick Reference

Deploy iOS to TestFlight

cd apps/mobile/ios && bundle exec fastlane beta_auto

Deploy Android to Play Store

cd apps/mobile/android && bundle exec fastlane playstore

Trigger Xcode Cloud Build

cd apps/mobile/ios/scripts && python3 xcode_cloud_cli.py trigger

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.