From 352ad0217dd9ae418be223aa276a59a5b4c3d8d8 Mon Sep 17 00:00:00 2001 From: Jan Mottl Date: Thu, 9 Jul 2026 23:53:00 +0200 Subject: [PATCH 1/6] Update Java to 21 --- CHANGELOG.MD | 2 ++ Dockerfile | 26 ++++++++++---------------- README.MD | 2 +- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 54ab555..9dba159 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Updated Java from 17 to 21 (Eclipse Temurin `21.0.11+10`) ## [v3.0.2] - 2026-03-12 ### Fixed diff --git a/Dockerfile b/Dockerfile index a12c085..d6a07ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,9 +10,8 @@ ARG DANGER_JS_VERSION="12.3.4" ARG DANGER_KOTLIN_VERSION="1.3.4" ARG DANGER_KOTLIN_CHECKSUM="sha256:232b11680cdfe50c64a6cef1d96d3cd09a857422da1e2dd0464f80c8ddb1afac" -# If you need to update major Java version, you will need to adjust the version in the download link as well -ARG JAVA_VERSION="17.0.18_8" -ARG JAVA_CHECKSUM="sha256:0c94cbb54325c40dcf026143eb621562017db5525727f2d9131a11250f72c450" +# JAVA_VERSION selects both the Temurin base image tag (`-jdk`) and the JAVA_HOME dir name. +ARG JAVA_VERSION="21.0.11_10" # Needed for danger-kotlin ARG KOTLINC_VERSION="2.2.21" @@ -75,20 +74,15 @@ RUN npm config set ignore-scripts true # == java-installation == -FROM build AS java-installation - -ARG JAVA_CHECKSUM -ARG JAVA_VERSION +# The JDK is copied from Adoptium's official Temurin image instead of downloading and unpacking the +# tarball ourselves. `ADD --unpack` corrupts the large (~142MB) Java 21 module image when the build +# runs under QEMU emulation (e.g. building linux/amd64 on Apple Silicon): lib/modules ends up with +# zero-filled pages and fails at runtime with "ClassFormatError: Incompatible magic value 0". +# COPY --from is a native BuildKit op that copies the pre-extracted, known-good bytes. +FROM eclipse-temurin:${JAVA_VERSION}-jdk AS temurin-jdk -ARG JAVA_TEMP_DIR="java" -# Replace _ with + in version for download link -ENV JAVA_VERSION_PLUS="${JAVA_VERSION/_/+}" -ADD --checksum="$JAVA_CHECKSUM" --unpack=true \ - "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-$JAVA_VERSION_PLUS/OpenJDK17U-jdk_x64_linux_hotspot_$JAVA_VERSION.tar.gz" \ - "$JAVA_TEMP_DIR" -RUN mkdir -p "$JAVA_HOME" && \ - # Temp dir contains unpacked JDK folder, we want to move its contents to JAVA_HOME - mv "$JAVA_TEMP_DIR"/*/* "$JAVA_HOME" +FROM build AS java-installation +COPY --from=temurin-jdk /opt/java/openjdk "$JAVA_HOME" diff --git a/README.MD b/README.MD index b26f882..7d0398b 100644 --- a/README.MD +++ b/README.MD @@ -4,7 +4,7 @@ Docker image providing a complete environment for running Android builds on GitL ## Contents -- Java 17 (OpenJDK from Eclipse Temurin) +- Java 21 (OpenJDK from Eclipse Temurin) - Android SDK (cmdline-tools, platform tools, build-tools) - danger-kotlin + danger-js + Kotlin compiler - Node.js (system package, required by danger-js) From 18c37d514c67bdfae91c6909075cec3657887a4b Mon Sep 17 00:00:00 2001 From: Jan Mottl Date: Fri, 10 Jul 2026 00:03:14 +0200 Subject: [PATCH 2/6] Fix npm config path Co-Authored-By: Claude Opus 4.8 (1M context) --- Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Dockerfile b/Dockerfile index d6a07ee..2bb4549 100644 --- a/Dockerfile +++ b/Dockerfile @@ -128,8 +128,14 @@ ARG KOTLINC_BASE_PATH ARG KOTLINC_CHECKSUM ARG KOTLINC_VERSION +# Recent hardened Debian base images removed /usr/local, so we need to create it ourselves +RUN mkdir -p "$DANGER_BASE_PATH" # chown of directories where danger will be installed, so nonroot npm process can write there RUN chown -R nonroot:nonroot "$DANGER_BASE_PATH" +# Recent hardened Debian base images no longer pin npm's global prefix to /usr/local, so npm +# defaults to /usr (installs to /usr/lib/node_modules, not writable by nonroot). Pin it back to +# $DANGER_BASE_PATH so `npm install -g` and `npm root -g` target the chowned, expected location. +ENV npm_config_prefix="$DANGER_BASE_PATH" # Change to nonroot user for npm install to reduce attack surface if compromised USER nonroot From cb391ea83ee3a0f8cc67ed24588dd65c7673ddf1 Mon Sep 17 00:00:00 2001 From: Jan Mottl Date: Fri, 10 Jul 2026 00:09:07 +0200 Subject: [PATCH 3/6] Fix npm ignore-scripts not applying to nonroot install Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.MD | 3 +++ Dockerfile | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9dba159..6bbcaf6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Updated Java from 17 to 21 (Eclipse Temurin `21.0.11+10`) +### Security +- npm `ignore-scripts` is now set via `ENV` (`npm_config_ignore_scripts`) instead of `npm config set`, so the supply-chain protection also applies to the `nonroot` Danger install. Previously the setting was written to root's `~/.npmrc` and silently bypassed after the `USER nonroot` switch, leaving the one third-party install unprotected. + ## [v3.0.2] - 2026-03-12 ### Fixed - Fixed missing `fontconfig` dependency for EasyLauncher plugin diff --git a/Dockerfile b/Dockerfile index 2bb4549..ace752a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -67,8 +67,10 @@ RUN apt update && apt install -y --no-install-recommends \ unzip # Disables npm preinstall, postintall and other scripts that might run when any npm package is installed, -# which is usually exploited by supply chain attacks like shai-hulud -RUN npm config set ignore-scripts true +# which is usually exploited by supply chain attacks like shai-hulud. Set via ENV rather than +# `npm config set` so it applies to every user (incl. the nonroot install in danger-installation), +# instead of being written to a single user's ~/.npmrc that a USER switch would bypass. +ENV npm_config_ignore_scripts=true From 0e7415827a566e955ed813d12faeeff88dbc39d4 Mon Sep 17 00:00:00 2001 From: Jan Mottl Date: Fri, 10 Jul 2026 14:12:09 +0200 Subject: [PATCH 4/6] Update kotlinc --- CHANGELOG.MD | 1 + Dockerfile | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6bbcaf6..440aa85 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed - Updated Java from 17 to 21 (Eclipse Temurin `21.0.11+10`) +- Updated Kotlin compiler for danger-kotlin from `2.2.21` to `2.4.0` ### Security - npm `ignore-scripts` is now set via `ENV` (`npm_config_ignore_scripts`) instead of `npm config set`, so the supply-chain protection also applies to the `nonroot` Danger install. Previously the setting was written to root's `~/.npmrc` and silently bypassed after the `USER nonroot` switch, leaving the one third-party install unprotected. diff --git a/Dockerfile b/Dockerfile index ace752a..4bc065e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,6 @@ # == Versions == ARG ANDROID_CMDLINE_TOOLS_VERSION="14742923" -ARG ANDROID_BUILD_TOOLS_VERSION="36.1.0" -ARG ANDROID_PLATFORM_VERSION="36" ARG DANGER_JS_VERSION="12.3.4" ARG DANGER_KOTLIN_VERSION="1.3.4" @@ -14,8 +12,8 @@ ARG DANGER_KOTLIN_CHECKSUM="sha256:232b11680cdfe50c64a6cef1d96d3cd09a857422da1e2 ARG JAVA_VERSION="21.0.11_10" # Needed for danger-kotlin -ARG KOTLINC_VERSION="2.2.21" -ARG KOTLINC_CHECKSUM="sha256:a623871f1cd9c938946948b70ef9170879f0758043885bbd30c32f024e511714" +ARG KOTLINC_VERSION="2.4.0" +ARG KOTLINC_CHECKSUM="sha256:ba1b9e6eb6ddc3275079224f2e9ea4a2b02eef7d59ce2d38404f04b22613c20a" # == Others == @@ -93,9 +91,7 @@ COPY --from=temurin-jdk /opt/java/openjdk "$JAVA_HOME" # Installs Android SDK. Requires Java to be already installed. FROM java-installation AS android-sdk-installation -ARG ANDROID_BUILD_TOOLS_VERSION ARG ANDROID_CMDLINE_TOOLS_VERSION -ARG ANDROID_PLATFORM_VERSION ARG CMDLINE_TOOLS_DIR ARG CMDLINE_TOOLS_VERSION_DIR From f253df61a87b128568cac9abc31ad5e248698d3f Mon Sep 17 00:00:00 2001 From: Jan Mottl Date: Fri, 10 Jul 2026 16:33:08 +0200 Subject: [PATCH 5/6] Fix git foreign owned repo --- CHANGELOG.MD | 3 +++ Dockerfile | 8 ++++++++ image-test.sh | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 440aa85..c2e218f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated Java from 17 to 21 (Eclipse Temurin `21.0.11+10`) - Updated Kotlin compiler for danger-kotlin from `2.2.21` to `2.4.0` +### Fixed +- Git commands no longer fail with "detected dubious ownership" (exit 128) in repositories owned by a different UID than the container user, e.g. projects bind-mounted from the host. This broke Gradle builds using the Ackee plugin, which derives version code via `git rev-list HEAD --count`. Fixed by setting `safe.directory = *` in the system gitconfig, which is safe in a single-user container. + ### Security - npm `ignore-scripts` is now set via `ENV` (`npm_config_ignore_scripts`) instead of `npm config set`, so the supply-chain protection also applies to the `nonroot` Danger install. Previously the setting was written to root's `~/.npmrc` and silently bypassed after the `USER nonroot` switch, leaving the one third-party install unprotected. diff --git a/Dockerfile b/Dockerfile index 4bc065e..9754af5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -230,6 +230,14 @@ ARG GIT_LFS_PATH="/usr/bin/git-lfs" COPY --from=git-lfs-installation "$GIT_LFS_PATH" "$GIT_LFS_PATH" RUN git lfs install +# Repositories are often owned by a different UID than the runtime user, e.g. projects bind-mounted +# from the host (Docker Desktop passes the host UID through) or CI checkouts made under another +# user. Git >= 2.35.2 then refuses any repo operation with "detected dubious ownership" (exit 128), +# which breaks Gradle plugins that read git state, like the Ackee plugin deriving version code from +# `git rev-list HEAD --count`. The ownership check protects multi-user machines, which this +# single-user container is not, so trust all directories. +RUN git config --system safe.directory '*' + # Remove binaries that might allow privilege escalation RUN rm -f /bin/su RUN rm -f /usr/bin/apt /usr/bin/apt-get /usr/bin/apt-cache diff --git a/image-test.sh b/image-test.sh index 814e5f4..b05f9de 100755 --- a/image-test.sh +++ b/image-test.sh @@ -31,6 +31,23 @@ check_command_exists() { fi } +check_git_foreign_owned_repo() { + local repo + repo=$(mktemp -d) + git init -q "$repo" + # GIT_TEST_ASSUME_DIFFERENT_OWNER makes git treat the repo as owned by another user, the same + # situation as a project bind-mounted from the host or checked out by CI under a different UID. + # Without safe.directory=* in the system gitconfig, git refuses to work in such repos with + # "detected dubious ownership" (exit 128), breaking e.g. Gradle plugins that read git state. + if GIT_TEST_ASSUME_DIFFERENT_OWNER=1 git -C "$repo" rev-parse --git-dir > /dev/null; then + echo "git works in repos owned by another user ✅" + else + echo "git fails in repos owned by another user (safe.directory not set?) ❌" >&2 + exit 1 + fi + rm -rf "$repo" +} + check_dir() { local dir=$1 if [[ -d "$dir" ]]; then @@ -76,6 +93,7 @@ check_command_missing "sudo" echo echo "Required custom SW check" check_command_exists "git" +check_git_foreign_owned_repo check_command_exists "git-lfs" check_command_exists "java" From ca12aa3221e196915af0b7f8eb6cf2f30a0c2065 Mon Sep 17 00:00:00 2001 From: Jan Mottl Date: Fri, 10 Jul 2026 16:35:50 +0200 Subject: [PATCH 6/6] Update version in CHANGELOG --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c2e218f..033ad98 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## [v4.0.0] - TBD ### Changed - Updated Java from 17 to 21 (Eclipse Temurin `21.0.11+10`) - Updated Kotlin compiler for danger-kotlin from `2.2.21` to `2.4.0`