feat(runner): add Android-augmented job image (#1)
Adds opt-in Android job image so workflows like exifcleaner-web's APK build skip the ~3-5 min cold Android SDK install per run. - runner-image-android/Dockerfile inherits forgejo-stack/job:latest, adds JDK 17 Temurin + Android cmdline-tools + platforms;android-35 + build-tools;35.0.0 - setup.sh builds forgejo-stack/job-android:latest after the main image (gated on RUNNER_BUILD_ANDROID_IMAGE, default true) - .env.example documents the new vars; .gitignore adds .worktrees/ Consumers opt in via container: forgejo-stack/job-android:latest at the job level. Default forgejo-stack/job:latest stays slim.
This commit is contained in:
parent
f363db42c7
commit
5c3e33ced3
4 changed files with 115 additions and 0 deletions
|
|
@ -32,6 +32,8 @@ RUNNER_IMAGE=code.forgejo.org/forgejo/runner:6
|
|||
RUNNER_NAME=local-runner
|
||||
# Override job container image (must be available locally; see runner-image/).
|
||||
# RUNNER_JOB_IMAGE=forgejo-stack/job:latest
|
||||
# RUNNER_BUILD_ANDROID_IMAGE=true # set false to skip the ~5 min android image build
|
||||
# RUNNER_ANDROID_JOB_IMAGE=forgejo-stack/job-android:latest
|
||||
# Concurrent jobs per runner. Each slot can saturate a CPU core during build —
|
||||
# size to host capacity. Default 6; set to `nproc` on a dedicated CI host, or
|
||||
# lower if the box is shared with workstation use.
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -3,3 +3,4 @@ data/
|
|||
docker-compose.caddy.yml
|
||||
docker-compose.*.local.yml
|
||||
*.swp
|
||||
.worktrees/
|
||||
|
|
|
|||
92
runner-image-android/Dockerfile
Normal file
92
runner-image-android/Dockerfile
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Job container image for Android workflows. Inherits forgejo-stack/job:latest
|
||||
# (Node 22 + yarn + Playwright stack) and adds JDK 17 + Android SDK so
|
||||
# Capacitor / Gradle workflows skip the ~3-5 min SDK install on every run.
|
||||
#
|
||||
# Built locally by setup.sh and tagged forgejo-stack/job-android:latest.
|
||||
# Workflows opt in via `container: forgejo-stack/job-android:latest` at the
|
||||
# job level — the main job image stays slim for non-Android jobs.
|
||||
#
|
||||
# Cold-build win vs. installing setup-java@v4 + setup-android@v3 per job:
|
||||
# - JDK 17 install: ~15s saved
|
||||
# - cmdline-tools download: ~30s saved
|
||||
# - platforms;android-35: ~1m saved
|
||||
# - build-tools;35.0.0: ~1m saved
|
||||
# - License acceptance: ~30s saved
|
||||
# Total saved per cold run: ~3-5 min
|
||||
#
|
||||
# Bump ANDROID_API_LEVEL + ANDROID_BUILD_TOOLS_VERSION when targeting newer
|
||||
# Android SDKs; bump CMDLINE_TOOLS_VERSION + CMDLINE_TOOLS_REVISION when
|
||||
# upstream Android cmdline-tools ships a new revision.
|
||||
FROM forgejo-stack/job:latest
|
||||
|
||||
USER root
|
||||
|
||||
# JDK 17 (Temurin) via Eclipse Adoptium apt repo. Capacitor 7 / AGP 8+
|
||||
# require JDK 17; JDK 21 also works but 17 is the LTS we standardise on.
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
wget gnupg ca-certificates apt-transport-https \
|
||||
&& wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public \
|
||||
| gpg --dearmor -o /usr/share/keyrings/adoptium.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/adoptium.gpg] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" \
|
||||
> /etc/apt/sources.list.d/adoptium.list \
|
||||
&& apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
temurin-17-jdk unzip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV JAVA_HOME=/usr/lib/jvm/temurin-17-jdk-amd64
|
||||
ENV PATH=$JAVA_HOME/bin:$PATH
|
||||
|
||||
# Sanity check — fail the build if JDK isn't reachable.
|
||||
RUN java -version && javac -version
|
||||
|
||||
# Android SDK. Path matches GitHub-hosted runner convention so workflows
|
||||
# written against that environment work without modification.
|
||||
ENV ANDROID_HOME=/usr/local/lib/android/sdk
|
||||
ENV ANDROID_SDK_ROOT=$ANDROID_HOME
|
||||
|
||||
# Pin the cmdline-tools revision so image rebuilds are reproducible. Bump
|
||||
# both values when refreshing — the URL changes alongside the in-archive
|
||||
# version label.
|
||||
ARG CMDLINE_TOOLS_VERSION=11076708
|
||||
ARG ANDROID_API_LEVEL=35
|
||||
ARG ANDROID_BUILD_TOOLS_VERSION=35.0.0
|
||||
|
||||
RUN mkdir -p "$ANDROID_HOME/cmdline-tools" \
|
||||
&& cd /tmp \
|
||||
&& wget -q "https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_TOOLS_VERSION}_latest.zip" -O cmdline-tools.zip \
|
||||
&& unzip -q cmdline-tools.zip -d "$ANDROID_HOME/cmdline-tools" \
|
||||
&& mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest" \
|
||||
&& rm cmdline-tools.zip
|
||||
|
||||
ENV PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH
|
||||
|
||||
# Accept all SDK licenses non-interactively, then install the platform +
|
||||
# build-tools the Capacitor 7 default targets (compileSdk 35).
|
||||
# `yes |` pipes acceptance to every license prompt sdkmanager raises.
|
||||
RUN yes | sdkmanager --licenses >/dev/null \
|
||||
&& sdkmanager --update >/dev/null \
|
||||
&& sdkmanager \
|
||||
"platform-tools" \
|
||||
"platforms;android-${ANDROID_API_LEVEL}" \
|
||||
"build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
|
||||
&& chmod -R a+rX "$ANDROID_HOME"
|
||||
|
||||
# Sanity check — fail the build if any of the three Android tools aren't
|
||||
# reachable. (aapt2 lives in build-tools; adb in platform-tools.)
|
||||
RUN sdkmanager --list_installed | grep -E "platforms;android-${ANDROID_API_LEVEL}|build-tools;${ANDROID_BUILD_TOOLS_VERSION}|platform-tools"
|
||||
|
||||
# Note on Gradle: we don't bake Gradle itself or AGP plugins into the image.
|
||||
# Consumer projects ship a Gradle wrapper (`gradlew`) that downloads the
|
||||
# project-pinned Gradle version on first use, and AGP plugins are pulled
|
||||
# transitively by `assembleDebug`. Workflows cache `~/.gradle` via
|
||||
# actions/cache@v4 — second runs on the same host are warm. We could
|
||||
# pre-warm AGP plugin metadata here, but doing it well requires coupling
|
||||
# the image to a specific AGP version; not worth the maintenance burden.
|
||||
|
||||
# Document the toolchain versions baked in (handy for `docker inspect`).
|
||||
LABEL org.metascrub.runner.jdk="17"
|
||||
LABEL org.metascrub.runner.android-api-level="35"
|
||||
LABEL org.metascrub.runner.android-build-tools="35.0.0"
|
||||
LABEL org.metascrub.runner.cmdline-tools="11076708"
|
||||
20
setup.sh
20
setup.sh
|
|
@ -79,6 +79,26 @@ else
|
|||
log_info "runner job image already present: $JOB_IMAGE_TAG"
|
||||
fi
|
||||
|
||||
# 4-android. Build the Android-augmented job image. Inherits the main image
|
||||
# (Node 22 + yarn + Playwright) and adds JDK 17 + Android SDK so workflows
|
||||
# that opt in via `container: forgejo-stack/job-android:latest` skip the
|
||||
# ~3-5 min cold Android SDK install per run. Default is opt-out for the
|
||||
# base job image — non-Android workflows pay no disk cost.
|
||||
#
|
||||
# Set RUNNER_BUILD_ANDROID_IMAGE=false to skip (e.g. CI hosts that don't
|
||||
# serve Android workflows).
|
||||
ANDROID_JOB_IMAGE_TAG="${RUNNER_ANDROID_JOB_IMAGE:-forgejo-stack/job-android:latest}"
|
||||
if [[ "${RUNNER_BUILD_ANDROID_IMAGE:-true}" == "true" ]]; then
|
||||
if ! docker image inspect "$ANDROID_JOB_IMAGE_TAG" >/dev/null 2>&1; then
|
||||
log_info "building android runner job image: $ANDROID_JOB_IMAGE_TAG (this takes ~5 min)"
|
||||
docker build -t "$ANDROID_JOB_IMAGE_TAG" runner-image-android/
|
||||
else
|
||||
log_info "android runner job image already present: $ANDROID_JOB_IMAGE_TAG"
|
||||
fi
|
||||
else
|
||||
log_info "skipping android runner job image (RUNNER_BUILD_ANDROID_IMAGE=false)"
|
||||
fi
|
||||
|
||||
# 4a. Seed the hostedtoolcache volume from the job image's baked
|
||||
# /opt/hostedtoolcache. Docker only auto-initialises a named volume from
|
||||
# the FIRST container that mounts it; runner-1 (image forgejo/runner:6)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue