Mobile Fastlane

Configure Android environmentsAndroid

Last updated 2026-10-07

The android block of fastlane/config/environments.yml defines how each environment is built and where it is distributed. You can generate it with fastlane init_project or write it by hand.

fastlane/config/environments.yml
android:
enabled: true
project_dir: "android"
use_flavors: false # true when build.gradle defines productFlavors
build:
clean_before_build: false # run `gradle clean` first
gradle_options: "" # e.g. "--no-daemon --stacktrace"
environments:
development:
gradle_task: "assembleRelease" # ★ source of truth – exact Gradle task
artifact:
type: "APK" # APK or AAB
glob: "android/app/build/outputs/apk/release/*.apk"
firebase:
enabled: true
app_id: "${FIREBASE_ANDROID_DEV_APP_ID}" # empty → read from google-services.json
groups: "${FIREBASE_ANDROID_DEV_GROUPS}" # tester group aliases, comma-separated
testers: "" # or tester e-mails, comma-separated
app_testing:
enabled: true # AI tests for this environment
release_notes: { enabled: true, source: "git", commit_count: 10 }
notifications: { teams: { enabled: true }, slack: { enabled: false } }

Key reference

KeyRequiredDescription
gradle_taskYesExact Gradle task to run. The framework never guesses this: it is the source of truth.
artifact.typeYesAPK or AAB. Passed to Firebase as android_artifact_type.
artifact.globYesGlob, relative to the project root, that matches the file Gradle produces.
flavor / build_typeNoInformational (shown by doctor/info), and used by the interactive setup.
firebase.app_idWhen enabledFirebase App ID (1:123…:android:abc…). Detected from google-services.json when empty.
firebase.groups / testersOne of themGroup aliases or e-mail addresses, comma-separated.
app_testing.enabledNoRuns the App Testing agent after upload (APK only).

No-flavor project

If Gradle only exposes assembleDebug, assembleRelease and bundleRelease, keep use_flavors: false and set gradle_task: "assembleRelease".

Note: in that case development, staging and production can all ship the same Release APK, and only the Firebase destination or group differs. That is intentional. For truly isolated environments (separate app IDs and backends), add product flavors.

Flavor project

If android/app/build.gradle defines product flavors, Gradle creates one task per flavor and build type combination:

android/app/build.gradle
android {
flavorDimensions "env"
productFlavors {
dev { dimension "env"; applicationIdSuffix ".dev" }
staging { dimension "env"; applicationIdSuffix ".staging" }
prod { dimension "env" }
}
}

Set use_flavors: true and configure each environment with the matching task:

YAML
staging:
flavor: "staging"
build_type: "release"
gradle_task: "assembleStagingRelease"
artifact:
type: "APK"
glob: "android/app/build/outputs/apk/staging/release/*.apk"

The explicit gradle_task always wins. To see every task your project actually has, ask Gradle:

my-app/android — zsh
~/my-app $ ./gradlew tasks --all | grep -E "^(assemble|bundle).*Release "
assembleDevRelease - Assembles main output for variant devRelease
assembleProdRelease - Assembles main output for variant prodRelease
assembleStagingRelease - Assembles main output for variant stagingRelease
bundleDevRelease - Assembles bundle for variant devRelease
bundleProdRelease - Assembles bundle for variant prodRelease
bundleStagingRelease - Assembles bundle for variant stagingRelease
On Windows use .\gradlew.bat tasks --all | Select-String Release.

Common Gradle task / glob combinations

Project typegradle_taskartifact.glob
No flavors, APKassembleReleaseandroid/app/build/outputs/apk/release/*.apk
No flavors, AABbundleReleaseandroid/app/build/outputs/bundle/release/*.aab
Flavor dev, APKassembleDevReleaseandroid/app/build/outputs/apk/dev/release/*.apk
Flavor prod, AABbundleProdReleaseandroid/app/build/outputs/bundle/prodRelease/*.aab
Custom variante.g. assembleInternalQaReleasematching output folder

APK or AAB?

APKAAB
Install directly from FirebaseYesOnly if the Firebase project is linked to Google Play
App Testing agent (AI tests)YesNo
Google Play uploadLegacy onlyRequired format (About App Bundles)
Tip: doctor checks that the task really exists (gradlew tasks --all) before a long build starts.

Next steps

Official documentation

Was this helpful?