CI/CD for an Android + Gradle + Robolectric App with GitHub Actions
Run Robolectric JVM tests without an emulator, lint, and assemble the APK.
Robolectric runs Android unit tests on the JVM, so most of your suite needs no emulator and stays fast in CI. This recipe runs lint and Robolectric tests, then assembles a debug APK.
What the pipeline does
- set up a JDK with Gradle caching
- run Android Lint
- run Robolectric unit tests on the JVM
- assemble the debug APK
- upload the APK artifact
The workflow
gradle/actions/setup-gradle caches Gradle and the build cache. testDebugUnitTest runs the Robolectric suite on the JVM, no emulator required.
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
build:
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 lintDebug
- run: ./gradlew testDebugUnitTest
- run: ./gradlew assembleDebug
- uses: actions/upload-artifact@v4
with:
name: app-debug
path: app/build/outputs/apk/debug/*.apkCaching and speed
setup-gradle restores the Gradle caches and reuses the build cache across runs. Robolectric tests are JVM-fast, but assembling the APK is heavier, so cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) keep the build affordable, and auto-retry covers a flaky dependency download.
Deploying
For internal builds, upload the debug APK as an artifact. For releases, sign assembleRelease with your keystore (stored as secrets) and upload the AAB to the Play Console, or hand off to fastlane for distribution.
Key takeaways
- Robolectric runs Android tests on the JVM, so no emulator is needed.
- testDebugUnitTest is the fast bulk of an Android test suite.
- setup-gradle caches the Gradle and build caches across runs.