111 lines
5.7 KiB
Docker
111 lines
5.7 KiB
Docker
# Build environment for schwert_und_magie_on_pebble release artifacts:
|
|
# Android SDK/NDK (companion app) + Pebble SDK (watch app), matching the
|
|
# versions pinned in app/build.gradle.kts and validated on the maintainer's
|
|
# dev machine. Rebuild with ../build-image.sh whenever a version below, or
|
|
# the companion app's ndkVersion/compileSdk, changes.
|
|
#
|
|
# Does NOT contain the release keystore or any secrets — those are injected
|
|
# at job runtime from Gitea Actions secrets, never baked into this image.
|
|
FROM eclipse-temurin:21-jdk-jammy AS base
|
|
|
|
ARG ANDROID_CMDLINE_TOOLS_VERSION=11076708
|
|
ARG ANDROID_PLATFORM=android-36
|
|
ARG ANDROID_BUILD_TOOLS=36.1.0
|
|
ARG ANDROID_NDK=30.0.14904198
|
|
ARG ANDROID_CMAKE=3.22.1
|
|
ARG PEBBLE_TOOL_VERSION=5.0.35
|
|
ARG PEBBLE_SDK_CORE_VERSION=4.9.169
|
|
ARG NODE_VERSION=24.16.0
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive \
|
|
ANDROID_HOME=/opt/android-sdk \
|
|
ANDROID_SDK_ROOT=/opt/android-sdk \
|
|
ANDROID_NDK_HOME=/opt/android-sdk/ndk/30.0.14904198 \
|
|
PATH=/root/.local/bin:/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/platform-tools:${PATH}
|
|
|
|
# git/unzip/curl/jq: checkout, SDK downloads, and the release workflow's
|
|
# calls to the Gitea API (create release, upload assets).
|
|
# openssh-client: the release workflow's `sftp` upload to dl.ladkau.de.
|
|
# python3-venv: pebble-tool's `sdk install` creates a venv per SDK version.
|
|
# dos2unix/autoconf/automake/pkg-config/xa65/build-essential/gettext/flex/bison:
|
|
# host tools required by the companion app's build_vice.sh (see that file's
|
|
# own preflight check, plus flex/bison for VICE's AC_PROG_LEX/AC_PROG_YACC-
|
|
# based configure) to cross-compile VICE via autotools before NDK clang takes
|
|
# over for the actual target compilation.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl ca-certificates git unzip tar xz-utils python3 python3-venv file jq openssh-client \
|
|
dos2unix autoconf automake pkg-config xa65 build-essential gettext flex bison \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# --- Android SDK: cmdline-tools, platform, build-tools, NDK, CMake ---
|
|
# CMake version must match app/build.gradle.kts's externalNativeBuild.cmake.version
|
|
# — baking it in here avoids AGP installing it on first `docker run` instead.
|
|
RUN mkdir -p "$ANDROID_HOME/cmdline-tools" \
|
|
&& curl -sSL -o /tmp/cmdline-tools.zip \
|
|
"https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_CMDLINE_TOOLS_VERSION}_latest.zip" \
|
|
&& unzip -q /tmp/cmdline-tools.zip -d "$ANDROID_HOME/cmdline-tools" \
|
|
&& mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest" \
|
|
&& rm /tmp/cmdline-tools.zip \
|
|
&& yes | sdkmanager --licenses >/dev/null \
|
|
&& sdkmanager --install \
|
|
"platform-tools" \
|
|
"platforms;${ANDROID_PLATFORM}" \
|
|
"build-tools;${ANDROID_BUILD_TOOLS}" \
|
|
"ndk;${ANDROID_NDK}" \
|
|
"cmake;${ANDROID_CMAKE}" \
|
|
>/dev/null
|
|
|
|
# Node.js: `pebble sdk install` below runs `npm install` for the SDK-core's
|
|
# bundled webpack tooling — it does not bring its own node/npm, only the JS
|
|
# deps themselves. Version matches what's validated on the maintainer's
|
|
# machine; sdk-core's own bundled arm-none-eabi toolchain needs nothing extra.
|
|
RUN curl -sSL -o /tmp/node.tar.xz \
|
|
"https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \
|
|
&& tar -xJf /tmp/node.tar.xz -C /usr/local --strip-components=1 \
|
|
&& rm /tmp/node.tar.xz
|
|
|
|
# --- Pebble SDK: pebble-tool + sdk-core ---
|
|
RUN curl -LsSf https://astral.sh/uv/install.sh | sh \
|
|
&& /root/.local/bin/uv tool install "pebble-tool==${PEBBLE_TOOL_VERSION}" \
|
|
&& /root/.local/bin/pebble sdk install "${PEBBLE_SDK_CORE_VERSION}"
|
|
|
|
# --- Warm the Gradle dependency cache ---
|
|
# The companion app's real Gradle project files (not the generated build/
|
|
# output, and not the VICE/nibtools source tarballs — see .dockerignore) are
|
|
# COPYed into a throwaway location and built once here, so every actual
|
|
# `docker run` of this image (which bind-mounts a fresh checkout over
|
|
# /workspace) hits a warm ~/.gradle cache instead of re-downloading the same
|
|
# Maven dependencies from dl.google.com/mavenCentral every single run.
|
|
#
|
|
# buildVice/buildNibtools are excluded (their source tarballs aren't in the
|
|
# build context) — CMake already handles that gracefully, falling back to a
|
|
# placeholder (see vice_jni.c / build_vice.sh's own header comment) — so this
|
|
# stage only ever warms the Gradle/Maven dependency cache, never bakes in
|
|
# compiled VICE/nibtools output.
|
|
#
|
|
# packageRelease/signReleaseBundle are also excluded — they're the only tasks
|
|
# that need the release keystore, which never exists here (secrets are
|
|
# injected at job runtime, never baked into the image). Excluding them lets
|
|
# everything upstream (dependency resolution, Kotlin/native compilation,
|
|
# resource merging, dexing) still run and get cached, without two guaranteed,
|
|
# noisy "missing storeFile" failures cluttering every image build.
|
|
#
|
|
# This is a pure optimization: if the app's dependencies change after this
|
|
# image was built, Gradle just downloads the delta against the warm cache at
|
|
# `docker run` time — same as it would without this stage, just slower for
|
|
# that one run, never broken. `|| true` means a transient network failure
|
|
# here only costs a slower first `docker run`, never breaks the image build.
|
|
FROM base AS gradle-cache-warm
|
|
COPY SchwertUndMagieOnPebbleCompanionApp /tmp/warm/SchwertUndMagieOnPebbleCompanionApp
|
|
WORKDIR /tmp/warm/SchwertUndMagieOnPebbleCompanionApp
|
|
RUN chmod +x gradlew \
|
|
&& (./gradlew bundleRelease assembleRelease \
|
|
-x buildVice -x buildNibtools \
|
|
-x packageRelease -x signReleaseBundle \
|
|
--continue || true)
|
|
|
|
FROM base
|
|
COPY --from=gradle-cache-warm /root/.gradle /root/.gradle
|
|
|
|
WORKDIR /workspace
|