Android Build & Deploy Pipeline
Mobile7 nodes · 7 edgesmobile
Visual
ex-android-build-deploy.osop.yaml
# Android Build & Deploy Pipeline
# From source checkout to Play Console distribution
osop_version: "2.0"
id: android-build-deploy
name: Android Build & Deploy Pipeline
nodes:
- id: checkout
type: git
purpose: Clone repository and checkout release branch
runtime:
action: checkout
repo: git@github.com:org/android-app.git
branch: "${BRANCH:-main}"
outputs: [source_dir]
- id: gradle_build
type: cli
purpose: Build release APK and AAB using Gradle
runtime:
os: linux
command: ./gradlew assembleRelease bundleRelease
inputs: [source_dir]
outputs: [apk_path, aab_path]
timeout_sec: 600
explain:
what: Compiles source, processes resources, generates APK and AAB
why: AAB is required for Play Store; APK kept for internal distribution
- id: unit_tests
type: cli
purpose: Run JUnit and Robolectric unit tests
runtime:
os: linux
command: ./gradlew testReleaseUnitTest
timeout_sec: 300
- id: instrumented_tests
type: cicd
purpose: Run Espresso instrumented tests on emulator farm
runtime:
platform: firebase_test_lab
command: >
gcloud firebase test android run
--type instrumentation
--app build/outputs/apk/release/app-release.apk
--test build/outputs/apk/androidTest/release/app-release-androidTest.apk
--device model=Pixel6,version=33
timeout_sec: 900
retry_policy:
max_retries: 2
backoff_sec: 60
explain:
what: Runs UI tests on real device profiles in Firebase Test Lab
why: Catches device-specific regressions that unit tests miss
- id: sign_apk
type: cli
purpose: Sign release artifacts with upload key
runtime:
os: linux
command: >
jarsigner -keystore ${KEYSTORE_PATH}
-storepass ${STORE_PASS}
build/outputs/bundle/release/app-release.aab release-key
security:
credentials: [KEYSTORE_PATH, STORE_PASS, KEY_ALIAS]
- id: upload_play_console
type: api
purpose: Upload signed AAB to Google Play Console internal track
runtime:
endpoint: google_play
method: POST
url: https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PACKAGE}/edits
inputs: [signed_aab_path]
outputs: [release_id, track]
timeout_sec: 300
- id: notify
type: api
purpose: Post build result to Slack and update JIRA ticket
runtime:
endpoint: slack
method: POST
url: https://hooks.slack.com/services/${WEBHOOK_ID}
inputs: [release_id, build_status]
edges:
- from: checkout
to: gradle_build
mode: sequential
- from: gradle_build
to: unit_tests
mode: sequential
- from: unit_tests
to: instrumented_tests
mode: sequential
- from: instrumented_tests
to: sign_apk
mode: sequential
- from: sign_apk
to: upload_play_console
mode: sequential
- from: upload_play_console
to: notify
mode: sequential
- from: instrumented_tests
to: notify
mode: error
condition: tests_failed