Release and Publishing
Your first independent mobile game release—several days of continuous stress: certificate signing issues in the last moment, screenshots don't meet App Store requirements, review gets rejected over an EULA clause nobody read. Studios that've been through this once build a process to never repeat it. That's the process we're basing on from day one.
CI/CD for Mobile Builds
Manual builds and publishing aren't a process—it's a lottery. "Works on my machine" isn't a release criterion. Automating the pipeline solves three problems: build reproducibility, iteration speed, and eliminating human error in signing and uploads.
Pipeline Tools
GameCI — open-source Docker images for Unity builds. Works on top of GitHub Actions, GitLab CI, or any other CI provider. Key components:
-
unity-builder— builds project for target platform (Android, iOS, WebGL, Standalone) -
unity-test-runner— runs Unity Test Framework before build -
unity-return-license— returns Unity license after task completes (critical for Pro licenses)
Unity Cloud Build — cloud solution from Unity. Simpler setup, doesn't require your own CI server, but less flexible and pricier with high build volume. Good for small studios without DevOps expertise.
Fastlane — standard for automating final steps: signing, uploads to stores, metadata management. Works as add-on to GameCI or Unity Cloud Build.
Typical Pipeline
# .github/workflows/build-mobile.yml (simplified)
jobs:
test:
name: Run Unity Tests
uses: game-ci/unity-test-runner@v4
with:
unityVersion: 2022.3.20f1
testMode: playmode
build-android:
name: Build Android
needs: test
uses: game-ci/unity-builder@v4
with:
targetPlatform: Android
androidKeystoreName: release.keystore
androidKeystoreBase64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
androidKeystorePass: ${{ secrets.KEYSTORE_PASSWORD }}
androidKeyaliasName: ${{ secrets.KEY_ALIAS }}
androidKeyaliasPass: ${{ secrets.KEY_PASSWORD }}
upload-to-play:
name: Upload to Google Play (Internal Track)
needs: build-android
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
packageName: com.yourcompany.yourgame
releaseFiles: build/Android/*.aab
track: internal
Key details of this scheme:
Secrets, not variables. Keystore, certificates, service account JSON—all stored in CI provider secrets, not in repository. Keystore in git = potential key compromise.
AAB instead of APK for Google Play. App Bundle is mandatory since 2021 for new apps. It's smaller and lets Play Dynamic Delivery deliver only needed native libraries per device.
Release tracks. Google Play has four tracks: internal → closed testing → open testing → production. Each auto build goes to internal. Moving between tracks is manual or via Fastlane supply promote.
iOS Specifics
iOS builds are more complex due to Apple's strict signing requirements.
Xcode and Provisioning Profiles. Unity builds an Xcode project, then compiles via xcodebuild. For CI you need:
- Signing certificate (Distribution Certificate) in agent keychain
- Provisioning Profile (App Store Distribution) attached to Bundle ID
Fastlane Match solves certificate distribution: all certs and profiles stored in encrypted git repo, each developer and CI agent syncs via fastlane match.
# Fastfile
lane :build_ios do
match(type: "appstore", readonly: true)
build_app(
workspace: "Unity-iPhone.xcworkspace",
scheme: "Unity-iPhone",
export_method: "app-store"
)
upload_to_testflight
end
App Store Connect API Key — replaces Apple ID login for CI. Fastlane and xcodebuild support API Key auth, more reliable and doesn't break with two-factor auth.
Review Process: Common Rejection Reasons
App Store (Apple)
Apple rejects roughly 30-40% of first submissions from new studios. Most common reasons:
Metadata and marketing materials:
- Screenshots contain device UI or third-party brands
- Description mentions competitors or other platforms ("also available on Android")
- Icon violates guidelines (no alpha channel, wrong size)
Technical requirements:
- App crashes during review (Apple tests on iPad even if game is iPhone-only)
- Missing IPv6 support—Apple required this since 2016, still rejecting for it
- No "Sign in with Apple" when third-party auth exists (Google, Facebook)
Content and policies:
- In-app purchases not disclosed in metadata (need "In-App Purchases" flag)
- Missing Privacy Policy link directly in App Store Connect (not in-game)
- Loot boxes without probability disclosure in required jurisdictions
Practice: before first submission, read App Store Review Guidelines start to finish. 2-3 hours that save 2-3 weeks.
Google Play
Google Play is more lenient and automated. Typical rejection reasons:
-
Target API Level — Google requires current
targetSdkVersion. 2024: minimum API 34. Unity 2022.3+ sets this automatically. - Permissions — requesting excessive permissions (READ_EXTERNAL_STORAGE without justification)
- Data Policy — Data Safety Form in Play Console must match actual app behavior. If using Firebase Analytics—declare it explicitly.
Marketing Materials
Technically not development, but without proper materials, neither store will approve. Requirements:
App Store:
- Screenshots: 6.7" (iPhone 15 Pro Max), 12.9" iPad Pro—mandatory sizes
- Preview video: 15-30 seconds, H.264 or HEVC format
- Icon: 1024×1024 PNG without rounded corners (iOS rounds automatically)
Google Play:
- Feature Graphic: 1024×500 (top banner)—often overlooked
- Screenshots: minimum 2, maximum 8 per device type
- Icon: 512×512 PNG with alpha channel
App Store Optimization (ASO): keywords in title and Keywords field (iOS) or description (Android) directly impact organic installs. Tools: AppFollow, Sensor Tower, data.ai.
Localization and Regional Requirements
If launching in multiple regions, localization goes beyond text and affects publishing:
- Store metadata needs localization separately—App Store Connect and Google Play Console support language-specific translations
- Age ratings differ: IARC (global), ESRB (USA), PEGI (Europe), CERO (Japan). Built-in IARC questionnaire in both stores
- Chinese market requires separate licensing (ICP license, regulatory review)—separate 6+ month project
Post-Launch: Monitoring and Updates
Launch isn't the end. First 72 hours are critical:
- Crash rate monitored through Firebase Crashlytics. Acceptable mobile level—below 1%. If higher—need hotfix.
- ANR rate in Google Play Console—below 0.47% (else Play may limit visibility).
- Reviews in first days—real feedback. Often reveal device or OS-specific issues.
Phased rollout — gradual deployment — mandatory for significant updates. Google Play lets you release to 10%, then 50%, then 100%. App Store supports phased release similarly. This catches critical bugs before they hit everyone.





