Files
punktfunk/ci/android-ci.Dockerfile
T
enricobuehlerandClaude Fable 5 9cda05dffb feat(ci): android gets a baked builder image; apple gets sccache and a pinned DerivedData
Android was the last job still downloading its world every run: ~3 GB of
SDK/NDK/CMake from Google, a from-source cargo-ndk build, and one monolithic
cache key where a gradle edit invalidated the cargo registry and the Rust
target/ with it. punktfunk-android-ci (content-keyed, LAN registry) bakes
JDK 21 + SDK + NDK + cargo-ndk + sccache; the workflow shrinks to checkout →
two caches → gradle. The cargo-home cache joins the fleet-wide namespace
(same lockfile, same layout — it was the same bytes under a private key),
gradle gets its own key shared with android-screenshots (which stored the
identical content under a second name), and target/ leaves the cache —
sccache covers the three ABI builds now.

Apple: sccache (self-healing ~/.local/bin install + already provisioned on
the mini) covers every cargo invocation build-xcframework.sh makes across
the swift job, the screenshots job and release.yml — three jobs that each
recompiled the same core. screenshots.sh learns PF_SHOT_DERIVED_DATA so CI
pins one stable DerivedData root instead of cold-building into two throwaway
mktemp trees per run (release.yml's disease, same cure), and the Simulators
get shut down after capture (the 846-leaked-sims lesson).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 21:20:59 +02:00

60 lines
3.2 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Android CI builder: JDK 21 + Android SDK/NDK/CMake + pinned Rust with the three shipping
# Android targets + cargo-ndk + sccache. Everything android.yml used to download per run
# (~3 GB of NDK + SDK packages from Google, plus a from-source cargo-ndk build) is baked
# here instead; the image is content-keyed and rebuilt only when the ci/ tree changes
# (docker.yml `builders`).
#
# docker build -f ci/android-ci.Dockerfile -t punktfunk-android-ci ci
#
# Version pins mirror what android.yml installed via sdkmanager: AGP 9.3 wants JDK 1721;
# cmake;3.22.1 because kit/build.gradle.kts prepends $ANDROID_SDK/cmake/3.22.1/bin to PATH
# for cargo-ndk's audiopus_sys (libopus) CMake build; platforms;android-37 is deliberately
# absent (AGP auto-downloads it if a build ever needs it — same note as the old workflow).
FROM ubuntu:26.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl git unzip zip python3 openjdk-21-jdk-headless \
build-essential pkg-config \
&& rm -rf /var/lib/apt/lists/*
ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
# Android SDK: cmdline-tools must land under cmdline-tools/latest for sdkmanager to
# find its own root.
ENV ANDROID_HOME=/opt/android-sdk \
ANDROID_SDK_ROOT=/opt/android-sdk
ARG CMDLINE_TOOLS=13114758
RUN mkdir -p "$ANDROID_HOME/cmdline-tools" \
&& curl -fsSL -o /tmp/clt.zip "https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_TOOLS}_latest.zip" \
&& unzip -q /tmp/clt.zip -d "$ANDROID_HOME/cmdline-tools" \
&& mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest" \
&& rm /tmp/clt.zip
ENV PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH
RUN yes | sdkmanager --licenses >/dev/null \
&& sdkmanager "platform-tools" "platforms;android-36" "build-tools;37.0.0" \
"ndk;30.0.14904198" "cmake;3.22.1" \
&& chmod -R a+rX "$ANDROID_HOME"
# Toolchain shared across CI users (jobs may run as different uids) — same shape as
# rust-ci.Dockerfile, plus the Android cross targets and cargo-ndk. The registry/git
# download caches are stripped after the cargo-ndk install: jobs restore those from the
# shared actions cache, and baking them would only bloat every pull.
ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo \
PATH=/usr/local/cargo/bin:$PATH
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --no-modify-path --profile minimal \
&& rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android \
&& cargo install cargo-ndk --locked \
&& rm -rf "$CARGO_HOME/registry" "$CARGO_HOME/git" \
&& chmod -R a+w "$RUSTUP_HOME" "$CARGO_HOME" \
&& rustc --version && cargo-ndk --version
# Shared compile cache: jobs set RUSTC_WRAPPER=sccache (backend = RustFS S3 on the LAN,
# see .gitea/workflows — the env lives there so dev use of this image stays uncached).
ARG SCCACHE_VERSION=0.10.0
RUN curl -fsSL "https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl.tar.gz" \
| tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' \
&& sccache --version