# 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 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}" && \ rm -rf ${ANDROID_SDK_ROOT}/.android # 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. 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}" WORKDIR /workspace