Skip to content
Latchkey

CI/CD for an Android Jetpack Compose App with GitHub Actions

Build with Gradle, run unit and Compose UI tests on an emulator, and assemble a release APK.

This recipe builds an Android Jetpack Compose app. CI runs unit tests with Gradle, runs Compose instrumented UI tests on an emulator via reactivecircus/android-emulator-runner, then assembles a release APK.

What the pipeline does

  • set up the JDK and Gradle cache
  • run unit tests with ./gradlew test
  • boot an emulator and run connected Compose UI tests
  • assemble the release APK
  • upload the APK artifact

The workflow

android-emulator-runner boots an AVD with KVM acceleration and runs connectedCheck for the Compose UI tests. assembleRelease produces the signed APK.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: "17"
      - uses: gradle/actions/setup-gradle@v4
      - run: ./gradlew test
      - uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: 34
          arch: x86_64
          script: ./gradlew connectedCheck
      - run: ./gradlew assembleRelease
      - uses: actions/upload-artifact@v4
        with:
          name: app-release
          path: app/build/outputs/apk/release/*.apk

Caching and speed

gradle/actions/setup-gradle caches the Gradle dependency and build cache. The emulator boot plus Compose instrumented tests are the slowest stage; cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) with nested virtualization keep emulator runs fast and auto-retry a flaky AVD boot.

Deploying

Sign the release with a keystore stored in secrets (decode it in a step) and the signing config in build.gradle. Upload the signed APK or AAB as an artifact, or add a distribution step to push it to a Play Store internal track.

Key takeaways

  • Run Compose UI tests on an emulator via android-emulator-runner.
  • Cache the Gradle dependency and build cache to speed runs.
  • Decode the signing keystore from a secret for the release build.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →