From 230bc2fa2f021afb5728d14169a21a7e440e45b4 Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Fri, 30 Jan 2026 10:18:57 +0900 Subject: [PATCH 1/7] Update Dockerfile and workflows for multi-architecture support --- Dockerfile | 10 +++++----- core | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index ae28c7462..95640ce88 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,11 +37,11 @@ RUN DPKG_ARCH=$(dpkg --print-architecture) && \ && rm -rf /var/lib/apt/lists/* # Install just from a pinned release. -RUN case ${TARGETARCH} in \ - amd64) JUST_TARGET="x86_64-unknown-linux-musl" ;; \ - arm64) JUST_TARGET="aarch64-unknown-linux-musl" ;; \ - *) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \ - esac && \ +RUN JUST_TARGET=$(case ${TARGETARCH} in \ + amd64) echo "x86_64-unknown-linux-musl" ;; \ + arm64) echo "aarch64-unknown-linux-musl" ;; \ + *) echo "x86_64-unknown-linux-musl" ;; \ + esac) && \ curl -fL \ "https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${JUST_TARGET}.tar.gz" \ -o /tmp/just.tar.gz && \ diff --git a/core b/core index 15329f3f0..4a0332e12 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 15329f3f0e5fb038f41d8040588c4edf890c5992 +Subproject commit 4a0332e12a81f6fb852ec845799de0fb8df1e2be From 968e849a300da0ed385b35d43b89bdb2c58da670 Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Fri, 30 Jan 2026 13:27:21 +0900 Subject: [PATCH 2/7] Update Dockerfile --- Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 95640ce88..ae28c7462 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,11 +37,11 @@ RUN DPKG_ARCH=$(dpkg --print-architecture) && \ && rm -rf /var/lib/apt/lists/* # Install just from a pinned release. -RUN JUST_TARGET=$(case ${TARGETARCH} in \ - amd64) echo "x86_64-unknown-linux-musl" ;; \ - arm64) echo "aarch64-unknown-linux-musl" ;; \ - *) echo "x86_64-unknown-linux-musl" ;; \ - esac) && \ +RUN case ${TARGETARCH} in \ + amd64) JUST_TARGET="x86_64-unknown-linux-musl" ;; \ + arm64) JUST_TARGET="aarch64-unknown-linux-musl" ;; \ + *) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \ + esac && \ curl -fL \ "https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${JUST_TARGET}.tar.gz" \ -o /tmp/just.tar.gz && \ From 6dfa455613cccc0833b714084030e3470702b8a4 Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:00:53 +0900 Subject: [PATCH 3/7] Add multi-arch apt setup script --- Dockerfile | 13 ++++------ scripts/setup-multiarch-apt.sh | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 scripts/setup-multiarch-apt.sh diff --git a/Dockerfile b/Dockerfile index ae28c7462..ff44d180a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,15 +26,10 @@ ENV ANDROID_SDK_URL=https://dl.google.com/android/repository/commandlinetools-li ENV PATH=${ANDROID_HOME}/cmdline-tools/bin:${ANDROID_HOME}/platform-tools:${PATH} # Runtime deps for build-tools/aapt2. -RUN DPKG_ARCH=$(dpkg --print-architecture) && \ - apt-get update && \ - apt-get install -y --no-install-recommends \ - libc6:${DPKG_ARCH} \ - libstdc++6:${DPKG_ARCH} \ - zlib1g:${DPKG_ARCH} \ - libtinfo6:${DPKG_ARCH} \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* +# On arm64 hosts, build-tools ship x86_64-only binaries (aapt2). Install amd64 +# libc/zlib so those binaries can run under emulation. +COPY scripts/setup-multiarch-apt.sh /usr/local/bin/setup-multiarch-apt +RUN chmod +x /usr/local/bin/setup-multiarch-apt && /usr/local/bin/setup-multiarch-apt # Install just from a pinned release. RUN case ${TARGETARCH} in \ diff --git a/scripts/setup-multiarch-apt.sh b/scripts/setup-multiarch-apt.sh new file mode 100644 index 000000000..bf2757a94 --- /dev/null +++ b/scripts/setup-multiarch-apt.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -euo pipefail + +arch="$(dpkg --print-architecture)" +extra="" + +if [ "$arch" = "arm64" ]; then + dpkg --add-architecture amd64 + + if ! grep -q '^Architectures:' /etc/apt/sources.list.d/ubuntu.sources; then + sed -i '/^Types: deb$/a Architectures: arm64' /etc/apt/sources.list.d/ubuntu.sources + fi + + . /etc/os-release + codename="${VERSION_CODENAME:-noble}" + + cat > /etc/apt/sources.list.d/ubuntu-amd64.sources < Date: Wed, 4 Feb 2026 15:06:23 +0900 Subject: [PATCH 4/7] Harden multi-arch setup --- Dockerfile | 4 +--- scripts/setup-multiarch-apt.sh | 8 ++++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index ff44d180a..676478e64 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,9 +25,7 @@ ENV ANDROID_SDK_ROOT=/opt/android-sdk ENV ANDROID_SDK_URL=https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_TOOLS_VERSION}_latest.zip ENV PATH=${ANDROID_HOME}/cmdline-tools/bin:${ANDROID_HOME}/platform-tools:${PATH} -# Runtime deps for build-tools/aapt2. -# On arm64 hosts, build-tools ship x86_64-only binaries (aapt2). Install amd64 -# libc/zlib so those binaries can run under emulation. +# Runtime deps for build-tools/aapt2; on arm64 install amd64 libs so x86_64-only aapt2 runs under emulation. COPY scripts/setup-multiarch-apt.sh /usr/local/bin/setup-multiarch-apt RUN chmod +x /usr/local/bin/setup-multiarch-apt && /usr/local/bin/setup-multiarch-apt diff --git a/scripts/setup-multiarch-apt.sh b/scripts/setup-multiarch-apt.sh index bf2757a94..d4bb3995b 100644 --- a/scripts/setup-multiarch-apt.sh +++ b/scripts/setup-multiarch-apt.sh @@ -12,7 +12,11 @@ if [ "$arch" = "arm64" ]; then fi . /etc/os-release - codename="${VERSION_CODENAME:-noble}" + codename="${VERSION_CODENAME:-${UBUNTU_CODENAME:-}}" + if [ -z "$codename" ]; then + echo "Missing Ubuntu codename in /etc/os-release" >&2 + exit 1 + fi cat > /etc/apt/sources.list.d/ubuntu-amd64.sources < Date: Wed, 4 Feb 2026 16:39:51 +0900 Subject: [PATCH 5/7] simplify chmod +x --- Dockerfile | 4 ++-- scripts/setup-multiarch-apt.sh | 0 2 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 scripts/setup-multiarch-apt.sh diff --git a/Dockerfile b/Dockerfile index 676478e64..21362ee66 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,9 +25,9 @@ ENV ANDROID_SDK_ROOT=/opt/android-sdk ENV ANDROID_SDK_URL=https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_TOOLS_VERSION}_latest.zip ENV PATH=${ANDROID_HOME}/cmdline-tools/bin:${ANDROID_HOME}/platform-tools:${PATH} -# Runtime deps for build-tools/aapt2; on arm64 install amd64 libs so x86_64-only aapt2 runs under emulation. +# Runtime deps for build-tools on arm64, amd64 libs are needed for x86_64-only binary (aapt2 etc) under emulation. COPY scripts/setup-multiarch-apt.sh /usr/local/bin/setup-multiarch-apt -RUN chmod +x /usr/local/bin/setup-multiarch-apt && /usr/local/bin/setup-multiarch-apt +RUN /usr/local/bin/setup-multiarch-apt # Install just from a pinned release. RUN case ${TARGETARCH} in \ diff --git a/scripts/setup-multiarch-apt.sh b/scripts/setup-multiarch-apt.sh old mode 100644 new mode 100755 From 60cf07bff23b4e583ce9dbfb92d75997dbaf6c86 Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:42:40 +0900 Subject: [PATCH 6/7] bump base image --- reproducible/base_image_tag.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reproducible/base_image_tag.txt b/reproducible/base_image_tag.txt index 3726ed137..ad246b8a5 100644 --- a/reproducible/base_image_tag.txt +++ b/reproducible/base_image_tag.txt @@ -1 +1 @@ -base-2026-01-30 +base-2026-02-04 From 3a94474e479146fef8ecac2b3289131ba4ed021f Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:01:36 +0900 Subject: [PATCH 7/7] Add DOCKER_PLATFORM and OUTPUTS_DIR vars --- justfile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index 98d3af298..faef0332c 100644 --- a/justfile +++ b/justfile @@ -48,6 +48,8 @@ build-base-image: TAG := env("TAG", "main") BUILD_MODE := env("BUILD_MODE", "") BUNDLE_TASK := env("BUNDLE_TASK", "clean :app:bundleGoogleRelease assembleUniversalRelease") +DOCKER_PLATFORM := env("DOCKER_PLATFORM", "linux/amd64") +OUTPUTS_DIR := env("OUTPUTS_DIR", "") GRADLE_WORKERS_MAX := env("GRADLE_WORKERS_MAX", "4") build-app-image: @@ -58,9 +60,9 @@ build-app-image: tag="{{TAG}}" if ! docker pull ghcr.io/gemwalletcom/gem-android-base:${base_tag} >/dev/null 2>&1; then echo "Base image ghcr.io/gemwalletcom/gem-android-base:${base_tag} not found; building locally..." >&2 - DOCKER_BUILDKIT=1 DOCKER_DEFAULT_PLATFORM=linux/amd64 docker build --platform linux/amd64 -t ghcr.io/gemwalletcom/gem-android-base:${base_tag} . + DOCKER_BUILDKIT=1 DOCKER_DEFAULT_PLATFORM="{{DOCKER_PLATFORM}}" docker build --platform "{{DOCKER_PLATFORM}}" -t ghcr.io/gemwalletcom/gem-android-base:${base_tag} . fi - DOCKER_BUILDKIT=1 DOCKER_DEFAULT_PLATFORM=linux/amd64 docker build --platform linux/amd64 \ + DOCKER_BUILDKIT=1 DOCKER_DEFAULT_PLATFORM="{{DOCKER_PLATFORM}}" docker build --platform "{{DOCKER_PLATFORM}}" \ --build-arg TAG="${tag}" \ --build-arg SKIP_SIGN=true \ --build-arg BUNDLE_TASK="${BUNDLE_TASK}" \ @@ -78,15 +80,20 @@ build-app-in-docker: container_name="gem-android-app-build" gradle_cache=$(mktemp -d) maven_cache=$(mktemp -d) + outputs_dir="{{OUTPUTS_DIR}}" trap 'rm -rf "${gradle_cache}" "${maven_cache}"; docker rm -f ${container_name} >/dev/null 2>&1 || true' EXIT docker rm -f ${container_name} >/dev/null 2>&1 || true - DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run --platform linux/amd64 --name ${container_name} \ + DOCKER_DEFAULT_PLATFORM="{{DOCKER_PLATFORM}}" docker run --platform "{{DOCKER_PLATFORM}}" --name ${container_name} \ -e SKIP_SIGN=true \ -e BUNDLE_TASK="${BUNDLE_TASK}" \ -v "${gradle_cache}":/root/.gradle \ -v "${maven_cache}":/root/.m2 \ gem-android-app-verify \ bash -lc 'cd /root/gem-android && ./gradlew ${BUNDLE_TASK} --no-daemon --build-cache -Dorg.gradle.workers.max={{GRADLE_WORKERS_MAX}}' + if [ -n "${outputs_dir}" ]; then + mkdir -p "${outputs_dir}" + docker cp "${container_name}":/root/gem-android/app/build/outputs/. "${outputs_dir}/" + fi core-upgrade: @git submodule update --recursive --remote