Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions common/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SSH_CONFIG_DIR=$(CURDIR)/volumes/sshconfig
GIT_CONFIG_DIR=$(CURDIR)/volumes/gitconfig
GH_CONFIG_DIR=$(CURDIR)/volumes/ghconfig
WORKSPACES_DIR=$(CURDIR)/volumes/workspaces/$(CTX)
GRADLE_CACHE_DIR=$(CURDIR)/volumes/gradle-cache/$(CTX)
ORG?=$(CODEX_ORG)
REPO?=$(word 2,$(MAKECMDGOALS))
REPOS?=$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
Expand All @@ -28,6 +29,11 @@ HOST_REPO_MOUNT?=-v $(HOST_REPO_EXPANDED):/workspace/$(HOST_REPO_NAME)
HOST_REPO_WORKDIR?=/workspace/$(HOST_REPO_NAME)
EXTRA_REPOS?=$(LOCAL_EXTRA_REPOS)
EXTRA_DIR_FLAGS=$(foreach repo,$(EXTRA_REPOS),--add-dir /workspace/$(repo))
GRADLE_CACHE_MOUNT=

ifeq ($(CTX),android)
GRADLE_CACHE_MOUNT=-v $(GRADLE_CACHE_DIR):/home/sandbox/.gradle
endif

.PHONY: check-ctx check-org setup build-base build build-no-cache upgrade-tools run codex clone clean volume-fix-perms
.PHONY: $(LOCAL_REPO) $(LOCAL_EXTRA_REPOS)
Expand Down Expand Up @@ -103,6 +109,7 @@ run: check-ctx
-v $(SSH_CONFIG_DIR):/home/sandbox/.ssh \
-v $(GIT_CONFIG_DIR)/.gitconfig:/home/sandbox/.gitconfig \
-v $(GH_CONFIG_DIR):/home/sandbox/.config/gh \
$(GRADLE_CACHE_MOUNT) \
$(IMAGE) -c '$(RUN_CMD)'; \
else \
docker run -it --rm \
Expand All @@ -111,6 +118,7 @@ run: check-ctx
-v $(SSH_CONFIG_DIR):/home/sandbox/.ssh \
-v $(GIT_CONFIG_DIR)/.gitconfig:/home/sandbox/.gitconfig \
-v $(GH_CONFIG_DIR):/home/sandbox/.config/gh \
$(GRADLE_CACHE_MOUNT) \
$(IMAGE); \
fi

Expand Down Expand Up @@ -143,6 +151,7 @@ codex: check-ctx check-org
-v $(SSH_CONFIG_DIR):/home/sandbox/.ssh \
-v $(GIT_CONFIG_DIR)/.gitconfig:/home/sandbox/.gitconfig \
-v $(GH_CONFIG_DIR):/home/sandbox/.config/gh \
$(GRADLE_CACHE_MOUNT) \
$(IMAGE) -c '\
KEY_FILE="$$(ls /home/sandbox/.ssh/id_ed25519 /home/sandbox/.ssh/id_rsa /home/sandbox/.ssh/* 2>/dev/null | head -n 1)"; \
if [ -z "$$KEY_FILE" ]; then echo "No SSH key found in /home/sandbox/.ssh"; exit 1; fi; \
Expand All @@ -162,6 +171,7 @@ codex: check-ctx check-org
-v $(SSH_CONFIG_DIR):/home/sandbox/.ssh \
-v $(GIT_CONFIG_DIR)/.gitconfig:/home/sandbox/.gitconfig \
-v $(GH_CONFIG_DIR):/home/sandbox/.config/gh \
$(GRADLE_CACHE_MOUNT) \
-w /workspace/$(MAIN_REPO) \
$(IMAGE) -c '\
codex --profile full_access $(ADD_DIR_FLAGS) \
Expand Down
47 changes: 44 additions & 3 deletions contexts/android/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,54 @@
ARG BASE_IMAGE=codex-sandbox-base:latest
FROM ${BASE_IMAGE}

ARG ANDROID_CMDLINE_TOOLS_ZIP=commandlinetools-linux-14742923_latest.zip
ARG ANDROID_CMDLINE_TOOLS_SHA256=04453066b540409d975c676d781da1477479dde3761310f1a7eb92a1dfb15af7
ARG ANDROID_SDK_TOOLS_ARM64_URL=https://github.com/lzhiyong/android-sdk-tools/releases/download/35.0.2/android-sdk-tools-static-aarch64.zip
ARG ANDROID_SDK_TOOLS_ARM64_SHA256=db1cea2c4454d5f9c5a802646b2d1cf560b4ee7badbe23e51ab8e1881bb50fc2
ARG ANDROID_BUILD_TOOLS_VERSION=36.0.0
ARG ANDROID_PLATFORM_VERSION=36

ENV ANDROID_SDK_ROOT=/opt/android-sdk
ENV ANDROID_HOME=/opt/android-sdk
ENV PATH=$PATH:/opt/android-sdk/platform-tools:/opt/android-sdk/cmdline-tools/latest/bin

USER root
RUN apt-get update \
&& apt-get install -y openjdk-17-jdk \
&& apt-get install -y openjdk-17-jdk curl unzip ca-certificates \
&& rm -rf /var/lib/apt/lists/*
USER sandbox
RUN mkdir -p /opt/tools /opt/android-sdk/cmdline-tools \
&& chown -R sandbox:sandbox /opt/tools
RUN curl -fsSLo /tmp/${ANDROID_CMDLINE_TOOLS_ZIP} \
https://dl.google.com/android/repository/${ANDROID_CMDLINE_TOOLS_ZIP} \
&& echo "${ANDROID_CMDLINE_TOOLS_SHA256} /tmp/${ANDROID_CMDLINE_TOOLS_ZIP}" | sha256sum -c - \
&& unzip -q /tmp/${ANDROID_CMDLINE_TOOLS_ZIP} -d /opt/android-sdk/cmdline-tools \
&& mv /opt/android-sdk/cmdline-tools/cmdline-tools /opt/android-sdk/cmdline-tools/latest \
&& rm -f /tmp/${ANDROID_CMDLINE_TOOLS_ZIP} \
&& yes | sdkmanager --licenses >/dev/null \
&& sdkmanager \
"platform-tools" \
"platforms;android-${ANDROID_PLATFORM_VERSION}" \
"build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
&& yes | sdkmanager --licenses >/dev/null \
&& if [ "$(uname -m)" = "aarch64" ]; then \
curl -fsSLo /tmp/android-sdk-tools-static-aarch64.zip "${ANDROID_SDK_TOOLS_ARM64_URL}" \
&& echo "${ANDROID_SDK_TOOLS_ARM64_SHA256} /tmp/android-sdk-tools-static-aarch64.zip" | sha256sum -c - \
&& mkdir -p /tmp/android-sdk-tools-arm64 \
&& unzip -q /tmp/android-sdk-tools-static-aarch64.zip -d /tmp/android-sdk-tools-arm64 \
&& install -m 0755 /tmp/android-sdk-tools-arm64/build-tools/aapt /opt/android-sdk/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/aapt \
&& install -m 0755 /tmp/android-sdk-tools-arm64/build-tools/aapt2 /opt/android-sdk/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/aapt2 \
&& install -m 0755 /tmp/android-sdk-tools-arm64/build-tools/aidl /opt/android-sdk/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/aidl \
&& install -m 0755 /tmp/android-sdk-tools-arm64/build-tools/dexdump /opt/android-sdk/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/dexdump \
&& install -m 0755 /tmp/android-sdk-tools-arm64/build-tools/zipalign /opt/android-sdk/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/zipalign \
&& install -m 0755 /tmp/android-sdk-tools-arm64/build-tools/split-select /opt/android-sdk/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/split-select \
&& install -m 0755 /tmp/android-sdk-tools-arm64/platform-tools/adb /opt/android-sdk/platform-tools/adb \
&& install -m 0755 /tmp/android-sdk-tools-arm64/platform-tools/fastboot /opt/android-sdk/platform-tools/fastboot \
&& rm -rf /tmp/android-sdk-tools-arm64 /tmp/android-sdk-tools-static-aarch64.zip; \
fi \
&& chown -R sandbox:sandbox /opt/android-sdk

# Install toolset (managed via volumes/tools/android)
WORKDIR /opt/tools
COPY volumes/tools/android/package.json volumes/tools/android/package-lock.json ./
COPY --chown=sandbox:sandbox volumes/tools/android/package.json volumes/tools/android/package-lock.json ./
USER sandbox
RUN npm install --omit=dev
49 changes: 49 additions & 0 deletions docs/specs/android-dockerfile-sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Android SDK in Dockerfile Spec

## Context
We need the `android` container image to include the Android SDK because Android Studio is not available in the container. Builds should work without mounting a host SDK.

## Goals
- Install Android SDK Platform 36 and Build-Tools 36.x in the `android` image.
- Keep the image deterministic and reproducible across rebuilds.
- Ensure Gradle finds the SDK automatically inside the container.

## Non-goals
- Installing Android Studio in the container.
- Running the Android emulator in the container.
- Setting up CI pipelines or publishing artifacts.

## Constraints
- Image size should be reasonable (avoid downloading unused components).
- SDK license acceptance must be automated for non-interactive builds.
- Docker builds should cache well across runs.

## Proposed Dockerfile Changes
- Install Android SDK command line tools in the `android` image.
- Set `ANDROID_SDK_ROOT` and `ANDROID_HOME` (e.g., `/opt/android-sdk`).
- Use `sdkmanager` to install:
- `platforms;android-36`
- `build-tools;36.0.0` (latest 36.x at time of writing; update intentionally)
- `platform-tools`
- Accept SDK licenses during image build.
- Add `platform-tools` and `cmdline-tools/latest/bin` to `PATH`.
- Add a Gradle cache mount for faster builds (e.g., mount to `/home/sandbox/.gradle`).
- On ARM64, replace `aapt2` (and related build-tools binaries) with ARM64-compatible versions.

## Implementation Notes
- Download the command line tools zip from the official source and verify checksum (no vendoring).
- Unzip to `/opt/android-sdk/cmdline-tools/latest`.
- Run `yes | sdkmanager --licenses` during build.
- Consider adding `--no_https` only if build environment blocks SSL.
- Use `ARG ANDROID_SDK_VERSION` / `ARG ANDROID_BUILD_TOOLS_VERSION` to allow overrides.
- Use a vetted ARM64 build-tools bundle to supply `aapt2` on ARM64 hosts.

## Verification
- `sdkmanager --list` shows Platform 36 and Build-Tools 36.x installed.
- `adb version` works in the container.
- `./gradlew :app:assembleDebug` succeeds in a container session.

## Decisions
- Pin Build-Tools to `36.0.0` and update intentionally when a newer 36.x is released.
- Add a Gradle cache mount for faster builds.
- Do not add a separate target for updating SDK components outside the image rebuild.
1 change: 1 addition & 0 deletions scripts/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mkdir -p "${repo_root}/volumes/gitconfig"
mkdir -p "${repo_root}/volumes/ghconfig"
mkdir -p "${repo_root}/volumes/tools/${ctx}"
mkdir -p "${repo_root}/volumes/workspaces/${ctx}"
mkdir -p "${repo_root}/volumes/gradle-cache/${ctx}"
chmod 700 "${repo_root}/volumes/sshconfig"

tools_package="${repo_root}/volumes/tools/${ctx}/package.json"
Expand Down