Files
zooqueen 191682d8ff the android recipe provisions the toolchain it needs
The runner is bare: it carries node, and the reusable's JDK lane fires
only for a `client:` repo, so gradle had neither a JDK nor an SDK. Both
are fetched here, each behind a test for what gradle actually consumes —
javac on PATH, and the platforms directory — rather than for ANDROID_HOME,
which a partial SDK sets while still having nothing to build against.

RUNNER_TEMP is not set on this runner. Unset, it expanded to an empty
prefix and rooted the SDK at /, which is the silent exit the first run
took before it printed anything.

Heap and workers are bounded because these pods declare no memory
request; an unbounded gradle is killed by the kernel rather than failing
with something to read.
2026-08-16 17:32:53 -07:00

79 lines
3.6 KiB
YAML

# Canonical CI for hanzoai/mobile — the Expo/React Native client.
#
# No `images:` and no `deploy:`: a phone installs this, no cluster runs it. So
# the artifact is an APK, published through `binaries:` — the same lane that
# ships an executable a host installs, which is what an app is.
test:
- name: typecheck
# tsc is the build for this repo — there is no bundle step in CI, so a type
# error is the earliest honest signal that the app is broken.
run: |
set -e
corepack enable
pnpm install --frozen-lockfile
pnpm typecheck
- name: test
# Jest. Runs after typecheck so a red here means logic, not types.
run: |
set -e
corepack enable
pnpm install --frozen-lockfile
pnpm test
binaries:
- name: hanzo-android
# `android/` is generated, not tracked, so the icons and the manifest in the
# APK are whatever app.json says at this commit — there is no second copy to
# drift. Release is self-signed by the React Native template, which is enough
# to sideload; a store upload needs its own key and does not come from here.
run: |
set -eu
corepack enable
pnpm install --frozen-lockfile
# The runner is bare — it carries node and nothing else, and the
# reusable's own JDK lane only fires for a `client:` repo. So both
# halves of an Android toolchain are provisioned here, each behind a
# test for the thing gradle actually needs rather than for a variable
# that only suggests it. RUNNER_TEMP is not guaranteed on this runner;
# unset, it used to expand to an empty prefix and put the SDK at /.
TMP="${RUNNER_TEMP:-/tmp}"
# AGP 8 compiles against 17. Temurin publishes on the same host the
# runner already fetches jq and yq from, so this needs no new egress.
if ! command -v javac >/dev/null 2>&1; then
curl -fsSL -o "$TMP/jdk.tgz" \
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.13%2B11/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz
mkdir -p "$TMP/jdk"
tar -xzf "$TMP/jdk.tgz" -C "$TMP/jdk" --strip-components=1
JAVA_HOME="$TMP/jdk"; export JAVA_HOME
PATH="$JAVA_HOME/bin:$PATH"; export PATH
fi
# A partial SDK sets ANDROID_HOME and still has no platform to build
# against, so the test is for the platforms directory itself. Gradle
# downloads the platform and build-tools it wants once the licences
# are accepted, which is why only cmdline-tools is fetched here.
ANDROID_HOME="${ANDROID_HOME:-$TMP/android-sdk}"; export ANDROID_HOME
if [ ! -d "$ANDROID_HOME/platforms" ]; then
mkdir -p "$ANDROID_HOME/cmdline-tools"
curl -fsSL -o "$TMP/tools.zip" \
https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
unzip -q -o "$TMP/tools.zip" -d "$ANDROID_HOME/cmdline-tools"
rm -rf "$ANDROID_HOME/cmdline-tools/latest"
mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest"
yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licenses >/dev/null || true
fi
echo "toolchain: node $(node -v), $(java -version 2>&1 | head -1), sdk $ANDROID_HOME"
npx expo prebuild --platform android --no-install
# Bounded heap and one worker: these pods declare no memory request, so
# an unbounded gradle is the difference between a red step and a pod
# the kernel kills with no log to read.
./android/gradlew -p android --no-daemon --max-workers=2 \
-Dorg.gradle.jvmargs=-Xmx3g assembleRelease
out: android/app/build/outputs/apk/release/*.apk