All checks were successful
build-android-builder-image / build-image (push) Successful in 3m15s
ndk { debugSymbolLevel = "SYMBOL_TABLE" } needs the NDK's llvm-objcopy
to extract native symbol tables into the .aab's BUNDLE-METADATA. The
image shipped no NDK, so AGP silently skipped the step and Play warned
"no debug symbols" on every bundle with native code (confirmed by
inspecting Dade's 0.0.2 .aab: onnxruntime .so present, debugsymbols
metadata dir absent).
Install ndk;27.0.12077973 (AGP 8.13's default, so app repos need no
android.ndkVersion), export ANDROID_NDK_ROOT/HOME, and add llvm-objcopy
to the image sanity check so an arch/version mismatch fails the image
build instead of silently dropping symbols downstream.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
78 lines
4.0 KiB
Docker
78 lines
4.0 KiB
Docker
# Native linux/amd64 Android build toolchain for CI.
|
|
# Builds release artifacts only — no emulator, no test/system images.
|
|
# Must be amd64: Google publishes the Linux build-tools (aapt2, d8, …) for
|
|
# x86_64 only — there is no arm64 Linux build-tools package — so packaging
|
|
# cannot run natively on an aarch64 runner. The APK output is architecture-
|
|
# neutral regardless of the build host.
|
|
FROM eclipse-temurin:21-jdk-noble
|
|
|
|
# --- Version pins (bump deliberately; this is what your app repos trust) ---
|
|
# cmdline-tools: find the current build number at
|
|
# https://developer.android.com/studio#command-line-tools-only
|
|
ARG CMDLINE_TOOLS_VERSION=13114758
|
|
ARG BUILD_TOOLS_VERSION=36.0.0
|
|
ARG PLATFORM_VERSION=android-36
|
|
# NDK: required for `ndk { debugSymbolLevel }` — AGP shells out to the NDK's
|
|
# llvm-objcopy to extract native symbol tables into the .aab's BUNDLE-METADATA.
|
|
# Without it AGP silently skips the step and Play warns "no debug symbols". Pin
|
|
# to AGP's default NDK (r27 for AGP 8.13) so app repos need no `ndkVersion`.
|
|
# Check the default at https://developer.android.com/build/releases/gradle-plugin
|
|
ARG NDK_VERSION=27.0.12077973
|
|
|
|
ENV ANDROID_SDK_ROOT=/opt/android-sdk \
|
|
ANDROID_HOME=/opt/android-sdk \
|
|
DEBIAN_FRONTEND=noninteractive
|
|
|
|
# git is needed by some Gradle plugins; unzip/curl for SDK install.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl unzip git ca-certificates && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Node is required for Gitea Actions JS actions (actions/checkout,
|
|
# upload-artifact, ...) to run when this image is used as a job container —
|
|
# the runner exec's `node` inside the container. Noble's apt nodejs is v18;
|
|
# pull the current Node 24 from NodeSource instead.
|
|
ARG NODE_MAJOR=24
|
|
RUN curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash - && \
|
|
apt-get install -y --no-install-recommends nodejs && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install the command-line tools into the canonical "latest" location.
|
|
RUN mkdir -p ${ANDROID_SDK_ROOT}/cmdline-tools && \
|
|
curl -fsSL -o /tmp/tools.zip \
|
|
"https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_TOOLS_VERSION}_latest.zip" && \
|
|
unzip -q /tmp/tools.zip -d ${ANDROID_SDK_ROOT}/cmdline-tools && \
|
|
mv ${ANDROID_SDK_ROOT}/cmdline-tools/cmdline-tools ${ANDROID_SDK_ROOT}/cmdline-tools/latest && \
|
|
rm /tmp/tools.zip
|
|
|
|
ENV PATH=${PATH}:${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin:${ANDROID_SDK_ROOT}/platform-tools
|
|
|
|
# Accept licenses and bake the SDK packages into the image so prod builds
|
|
# don't depend on Google's endpoint at job time. The build-tools binaries
|
|
# (aapt2, d8) are x86_64 ELF — this is why the image must be amd64.
|
|
RUN yes | sdkmanager --licenses >/dev/null && \
|
|
sdkmanager --install \
|
|
"platform-tools" \
|
|
"platforms;${PLATFORM_VERSION}" \
|
|
"build-tools;${BUILD_TOOLS_VERSION}" \
|
|
"ndk;${NDK_VERSION}" && \
|
|
rm -rf ${ANDROID_SDK_ROOT}/.android
|
|
|
|
# Point AGP at the baked-in NDK. AGP auto-discovers ndk;<ver> under the SDK
|
|
# root, but exporting these makes it explicit and lets the debugSymbolLevel
|
|
# step resolve llvm-objcopy without an app-side android.ndkVersion.
|
|
ENV ANDROID_NDK_ROOT=${ANDROID_SDK_ROOT}/ndk/${NDK_VERSION} \
|
|
ANDROID_NDK_HOME=${ANDROID_SDK_ROOT}/ndk/${NDK_VERSION}
|
|
|
|
# Sanity: fail the image build if the toolchain isn't actually usable.
|
|
# Execute aapt2 (not just --version a tool) so an arch mismatch in the
|
|
# build-tools binaries fails the image build here, not in every app build.
|
|
# Execute the NDK's llvm-objcopy too — it is the exact binary the bundle's
|
|
# debug-symbol extraction shells out to, so an arch/version mismatch fails
|
|
# here rather than silently dropping symbols from every app's .aab.
|
|
RUN java -version && sdkmanager --version && node --version && \
|
|
"${ANDROID_SDK_ROOT}/build-tools/${BUILD_TOOLS_VERSION}/aapt2" version && \
|
|
test -d "${ANDROID_SDK_ROOT}/platforms/${PLATFORM_VERSION}" && \
|
|
"${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objcopy" --version
|
|
|
|
WORKDIR /workspace |