# `mix mob.release`
[🔗](https://github.com/genericjam/mob_dev/blob/main/lib/mix/tasks/mob.release.ex#L1)

Builds a release-signed artifact ready to upload to the app store.

    mix mob.release                     # iOS .ipa (default)
    mix mob.release --ios               # iOS .ipa (explicit)
    mix mob.release --android           # Android .aab
    mix mob.release --security-gate     # run mix mob.security_scan first;
                                        # abort the release on any
                                        # critical/high/medium finding

## --security-gate

Runs the full security scan against the project (every layer:
Hex/Gradle/Swift dep CVEs, bundled-runtime drift, C/Kotlin/Swift
static analysis) **before** building or signing. If the scan
surfaces any critical/high/medium finding, the release aborts
with a non-zero exit code — nothing is built, nothing is signed.
Combine with the rest of your release flags as needed:

    mix mob.release --android --security-gate
    mix mob.release --ios --security-gate

Equivalent to running `mix mob.security_scan --strict` and only
proceeding to `mix mob.release` if the scan exits 0; the gate
flag just bundles the two into one command so a wrong-order
invocation can't slip through.

## --ios output

`_build/mob_release/<App>.ipa`

## --android output

`android/app/build/outputs/bundle/release/app-release.aab`

## --ios prerequisites

  1. Apple Developer Program membership (paid, $99/yr)
  2. An "Apple Distribution" certificate in your keychain
     (Xcode → Settings → Accounts → Manage Certificates → +)
  3. An App Store provisioning profile for your bundle ID, downloaded
     to `~/Library/Developer/Xcode/UserData/Provisioning Profiles/`.
     `mix mob.provision --distribution` automates the profile download.

## --android prerequisites

  1. `android/keystore.properties` filled in with your upload keystore
     credentials. `android/upload_jks.keystore` must exist. See
     `android/keystore.properties.example`.

## What --android does

  1. Ensures the Android OTP runtime is cached (`~/.mob/cache/otp-android-*`).
  2. Stages a temp tree: OTP runtime + app BEAMs + exqlite BEAMs.
  3. Runs `MobDev.OtpAssetBundle.build/2` to produce
     `android/app/src/main/assets/otp.zip` — stripped and compressed.
     `MobBridge.extractOtpIfNeeded()` extracts this on first launch.
  4. Runs `./gradlew bundleRelease` to produce the signed AAB.

Use `mix mob.publish --android` to upload to Google Play.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
