onionwire/scripts/build-android-local.sh
apk-dev 672f2c9990
All checks were successful
ci / test (pull_request) Successful in 3m22s
feat(android): SDK AAR (UniFFI) + Compose APK, Arti rustls feature split
Adds the Android product alongside the existing Linux TUI, in one repo.

SDK — crates/onionwire-sdk is a UniFFI facade over the very same `onionwire`
crate the TUI runs on. Identity, invite, friend upsert, send/receive, rotate
and wipe all delegate; no protocol is reimplemented, so an Android peer and a
Linux peer interoperate. It is its own Cargo workspace because Arti's TLS
backends are non-additive: the TUI keeps native-tls (OpenSSL), Android needs
rustls + static-sqlite (no OpenSSL, no system libsqlite3 in the NDK).

android/ — Gradle project. :sdk produces the AAR (Kotlin bindings generated at
build time + libonionwire_sdk.so via cargo-ndk), :app is a Kotlin/Compose/M3
messenger depending on :sdk only. minSdk 26, targetSdk/compileSdk 36,
INTERNET-only, data in filesDir, backups excluded.

Root Cargo.toml grows `native-tls` (default) and `rustls` features so exactly
one Arti TLS backend is selected per build graph. The default build is
unchanged: same backend, ratatui still a normal dependency, src/tui.rs
untouched.

Also: Store::self_fingerprint/set_petname + Node wrappers (additive only),
scripts/build-android-local.sh, README sections, .gitignore for local SDK paths.
2026-09-10 18:20:19 -04:00

66 lines
2.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Build the Android artifacts on this host and publish them to a Forgejo
# release. There is no Android toolchain in CI: .forgejo/workflows/release.yml
# runs on an aarch64 Linux container and cannot produce an APK. This is the
# Android path, exactly like scripts/build-release-local.sh is the x86_64 path
# for the Linux binary.
#
# Usage:
# scripts/build-android-local.sh [version] # build + checksums only
# PUBLISH_TAG=v0.3.0 scripts/build-android-local.sh # also upload
#
# Requires: ANDROID_HOME (or android/local.properties), an installed NDK, the
# Rust android targets, cargo-ndk, JDK 17+, and a working `cargo` on PATH.
# Does not create or push tags: creating the tag is a human decision.
set -euo pipefail
root="$(cd "$(dirname "$0")/.." && pwd)"
cd "$root"
version="${1:-$(sed -n 's/.*versionName = "\(.*\)".*/\1/p' android/app/build.gradle.kts | head -1)}"
[ -n "$version" ] || { echo "could not determine version" >&2; exit 1; }
abi="${ONIONWIRE_ANDROID_ABI:-arm64-v8a}"
gradlew="$root/android/gradlew"
echo "==> android build: version $version, abi $abi"
( cd android && "./gradlew" --no-daemon \
"-Ponionwire.abis=$abi" \
:sdk:assembleRelease :app:assembleRelease )
mkdir -p dist
apk_src="android/app/build/outputs/apk/release/app-release.apk"
aar_src="android/sdk/build/outputs/aar/sdk-release.aar"
apk="dist/onionwire-$version-android-$abi.apk"
aar="dist/onionwire-sdk-$version.aar"
for f in "$apk_src" "$aar_src"; do
[ -s "$f" ] || { echo "missing or empty build output: $f" >&2; exit 1; }
done
cp "$apk_src" "$apk"
cp "$aar_src" "$aar"
# Refuse 0-byte release assets before they ever reach a release.
for f in "$apk" "$aar"; do
bytes=$(wc -c < "$f")
[ "$bytes" -gt 0 ] || { echo "refusing to ship empty $f" >&2; exit 1; }
( cd dist && sha256sum "$(basename "$f")" > "$(basename "$f").sha256" )
done
echo "==> verify"
( cd dist && sha256sum -c ./*.sha256 )
file "$apk" "$aar"
ls -l "$apk" "$aar" "$apk.sha256" "$aar.sha256"
if [ -n "${PUBLISH_TAG:-}" ]; then
: "${FORGEJO_TOKEN:?FORGEJO_TOKEN required to publish}"
echo "==> publishing to release $PUBLISH_TAG"
scripts/publish-release.sh "$PUBLISH_TAG" "OnionWire $PUBLISH_TAG" \
scripts/release-body.md \
"$apk" "$apk.sha256" "$aar" "$aar.sha256"
else
echo "==> not publishing (set PUBLISH_TAG=<tag> and FORGEJO_TOKEN to upload)"
fi