feat(build): add Docker-based reproducible build system

Adds docker/ with two Dockerfiles and a build.sh interactive script that
builds all three release targets (Windows exe, Linux binary, Android APK)
inside pinned Docker containers — no SDK required on the host.

Key design decisions:
- Source mounted read-only; build runs on an in-container copy so bin/obj
  never pollute the working tree.
- NuGet packages cached in a named Docker volume (plm-nuget-cache) across
  runs to avoid re-downloading on each build.
- Single-file desktop publishes use IncludeNativeLibrariesForSelfExtract so
  Avalonia's native libs (Skia, HarfBuzz, ANGLE) are embedded — without this
  flag the exe/binary silently fails to start.
- Android Dockerfile pins platform API 36 (dictated by the .NET 10 android
  workload, error XA5207 if mismatched) and bakes the full Android SDK +
  workload into the image layer.
- Artifacts are chown'd back to the host user so dist/ files are never
  owned by root.

All three targets verified end-to-end from a clean docker system prune -a:
Windows PE32+ exe (103 MB), Linux single-file binary launches on this host,
Android APK installs and renders UI on API-34 x86_64 emulator.
This commit is contained in:
2026-07-02 10:45:37 +02:00
parent 4d730d7860
commit 6a5daa0c18
4 changed files with 434 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0
# ── Java (required by the Android SDK tools) ─────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
openjdk-17-jdk-headless \
wget \
unzip \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
ENV ANDROID_HOME=/opt/android-sdk
# .NET 10 android workload compiles against API level 36 (see error XA5207
# if this drifts: the workload's Xamarin.Android.Tooling.targets dictates it).
ENV ANDROID_SDK_PLATFORM=36
ENV ANDROID_SDK_BUILD_TOOLS=36.0.0
# ── Android command-line tools ────────────────────────────────────────────────
# Pin the build number to a known-good release; update when Google breaks the URL.
# Latest as of 2025: commandlinetools-linux-11076708_latest.zip (cmdline-tools 12.0)
RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" && \
wget -q "https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip" \
-O /tmp/cmdtools.zip && \
unzip -q /tmp/cmdtools.zip -d "${ANDROID_HOME}/cmdline-tools" && \
mv "${ANDROID_HOME}/cmdline-tools/cmdline-tools" "${ANDROID_HOME}/cmdline-tools/latest" && \
rm /tmp/cmdtools.zip
ENV PATH="${JAVA_HOME}/bin:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${PATH}"
# ── Android SDK packages ──────────────────────────────────────────────────────
RUN yes | sdkmanager --licenses > /dev/null && \
sdkmanager \
"platform-tools" \
"platforms;android-${ANDROID_SDK_PLATFORM}" \
"build-tools;${ANDROID_SDK_BUILD_TOOLS}"
# ── dotnet android workload (~1 GB, baked into this layer) ───────────────────
RUN dotnet workload install android
WORKDIR /tmp/build