---
title: Android release
description: How the Pipedash Android app is built, checked and released. Covers files, toolchain, versions, Fastlane lanes, workflows, tests and Play screenshots.
---

The Android app is the `crates/pipedash-desktop` Tauri app built for Android. Every build generates the Gradle project, and Git ignores `crates/pipedash-desktop/gen`. Everything Android needs lives in the `android` directory or in `crates/tauri-plugin-pipedash-native/android`. The [Mobile](/docs/deployment/mobile) page describes the app from the user side, and the [iOS release](/docs/resources/ios-release) page describes the matching iOS pipeline.

## Files

| Path | What it is |
|---|---|
| [`android/fastlane/Fastfile`](https://github.com/hcavarsan/pipedash/blob/main/android/fastlane/Fastfile) | Project setup, build, checks, smoke test, screenshots and release lanes |
| [`android/fastlane/android_project.rb`](https://github.com/hcavarsan/pipedash/blob/main/android/fastlane/android_project.rb) | Version config, manifest checks, 16 KB alignment check and Play metadata assembly |
| `android/fastlane/release_notes/` | Optional Play "What's New" text per version: `<version>.txt` |
| [`android/fastlane/metadata/android/en-US/`](https://github.com/hcavarsan/pipedash/tree/main/android/fastlane/metadata/android/en-US) | Store listing text and icon |
| [`crates/tauri-plugin-pipedash-native/android`](https://github.com/hcavarsan/pipedash/tree/main/crates/tauri-plugin-pipedash-native/android) | Kotlin plugin and the manifest entries that merge into the app |
| [`ios/app-store-screenshots`](https://github.com/hcavarsan/pipedash/blob/main/ios/app-store-screenshots) | Screenshot editor that also exports the Play images |

## Toolchain

| Tool | Version |
|---|---|
| JDK | 21 |
| Android SDK platform | 37 (`platforms;android-37.0`) |
| Build tools | 37.0.0 |
| NDK | 30.0.16248370, set as `NDK_HOME` |
| bundletool | 1.18.3, set as `BUNDLETOOL_JAR` |
| Rust targets | `aarch64-linux-android`, `armv7-linux-androideabi`, `x86_64-linux-android` |

The `setup-android` composite action installs this toolchain on CI and caches the Rust build. `bundle exec fastlane android prepare_project` generates the Gradle project, copies the launcher icons and makes the release build ship stripped native libraries with their symbol tables. Every lane that builds calls it first.

## Versions

- **`versionName`:** the same store version as iOS. The major number of the release version goes up by 1, so release `v0.5.0` ships as `1.5.0` on both stores.
- **`versionCode`:** assigned automatically by the release lanes. The `check` lane uses `1`.
- **Minimum Android:** 7.0 (API 24).

## Lanes

Run the lanes from the `android` directory with `bundle exec fastlane android <lane>`. The first three need no Google Play access.

| Lane | What it does |
|---|---|
| `check` | Builds an unsigned AAB, runs the Kotlin plugin tests and checks the manifest and the 16 KB alignment of the native libraries |
| `debug_apk` | Builds a debug APK for `x86_64` |
| `smoke` | Installs the debug APK on a running emulator, opens the app and fails on a crash in logcat |
| `beta` | Signs and uploads a build to the closed testing track |
| `release` | Signs and uploads a build to production with the store listing, images and "What's New" |
| `upload_screenshots` | Exports and uploads only the Play images |

The "What's New" text of `release` comes from `android/fastlane/release_notes/<version>.txt` or, without it, from the GitHub release of the tag. Google Play allows 500 characters.

## Workflows

- **`android-check.yml`:** runs on pull requests that touch the app. It runs the Ruby tests, the screenshot export tests and `check`, then boots an emulator and runs `smoke`.
- **`android.yml`:** runs `beta` on every `v*` tag and offers the other publishing lanes as manual runs.

## Disabled features

Android matches the iOS release build. The Android plugin reports build watching as unsupported, and the frontend hides it. Remote push stays iOS-only. Background notifications work through a periodic `JobScheduler` job in a separate process, and the [Notifications](/docs/features/notifications) page covers the behavior.

## Tests

Run the Ruby tests from the `android` directory:

```bash
bundle exec ruby -e 'Dir["fastlane/*_test.rb"].sort.each { |file| require_relative file }'
```

They cover the version config, the manifest and alignment checks, the version code choice and the lanes, with stubbed Google Play and GitHub calls.

## Play screenshots

`bun run export:play` in `ios/app-store-screenshots` exports the Play images. The [screenshot editor maintenance page](/docs/resources/app-store-screenshots#play-export) covers the sizes and output paths.
