diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 7960f0b..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: ci - -on: - push: - branches: - - "master" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Build and push - uses: docker/build-push-action@v3 - with: - context: . - file: ./Dockerfile - push: true - tags: ${{ secrets.DOCKER_HUB_USERNAME }}/android-33:latest diff --git a/.github/workflows/publish-by-tag.yml b/.github/workflows/publish-by-tag.yml new file mode 100644 index 0000000..b3eac69 --- /dev/null +++ b/.github/workflows/publish-by-tag.yml @@ -0,0 +1,63 @@ +name: publish-by-tag + +on: + push: + tags: + - "build/*/v*" + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Parse build tag + id: parse + run: ./scripts/parse-build-tag.sh "${GITHUB_REF_NAME}" "${GITHUB_OUTPUT}" + + - name: Resolve variant + id: resolve + env: + DOCKER_USER: ${{ secrets.DOCKER_HUB_USERNAME }} + run: | + ./scripts/resolve-variant.sh \ + --variant-id "${{ steps.parse.outputs.variant_id }}" \ + --release "${{ steps.parse.outputs.release }}" \ + --docker-user "${DOCKER_USER}" \ + --output "${GITHUB_OUTPUT}" + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + platforms: ${{ steps.resolve.outputs.platforms }} + tags: ${{ steps.resolve.outputs.tags }} + build-args: | + UBUNTU_VERSION=${{ steps.resolve.outputs.ubuntu_version }} + APT_PROFILE=${{ steps.resolve.outputs.apt_profile }} + APT_PACKAGES_CSV=${{ steps.resolve.outputs.apt_packages_csv }} + JAVA_DEFAULT=${{ steps.resolve.outputs.java_default }} + SDK_PACKAGES_CSV=${{ steps.resolve.outputs.sdk_packages_csv }} + ENABLE_PROFILER=${{ steps.resolve.outputs.enable_profiler }} + ENABLE_PYTHON2=${{ steps.resolve.outputs.enable_python2 }} + ENABLE_GCC14=${{ steps.resolve.outputs.enable_gcc14 }} + ENABLE_EMULATOR=${{ steps.resolve.outputs.enable_emulator }} + ENABLE_MARATHON=${{ steps.resolve.outputs.enable_marathon }} + MARATHON_VERSION=${{ steps.resolve.outputs.marathon_version }} diff --git a/.github/workflows/release-all-missing.yml b/.github/workflows/release-all-missing.yml new file mode 100644 index 0000000..7064e3c --- /dev/null +++ b/.github/workflows/release-all-missing.yml @@ -0,0 +1,123 @@ +name: release-all-missing + +on: + workflow_dispatch: + inputs: + release: + description: "Release suffix in vN format (example: v6)" + required: true + type: string + dry_run: + description: "Build without pushing images" + required: true + default: true + type: boolean + max_parallel: + description: "Maximum number of parallel variant builds" + required: true + default: "3" + type: string + +concurrency: + group: release-all-${{ inputs.release }} + cancel-in-progress: false + +jobs: + discover: + runs-on: ubuntu-latest + outputs: + missing_count: ${{ steps.missing.outputs.missing_count }} + matrix: ${{ steps.missing.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Validate release format + run: | + if [[ ! "${{ inputs.release }}" =~ ^v[0-9]+$ ]]; then + echo "Invalid release format: ${{ inputs.release }} (expected vN)" >&2 + exit 1 + fi + + - name: Find missing variants + id: missing + env: + DOCKER_USER: ${{ secrets.DOCKER_HUB_USERNAME }} + run: | + ./scripts/list-missing-for-release.sh \ + --release "${{ inputs.release }}" \ + --docker-user "${DOCKER_USER}" \ + --output "${GITHUB_OUTPUT}" + + build-missing: + needs: discover + if: ${{ needs.discover.outputs.missing_count != '0' }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: ${{ fromJSON(inputs.max_parallel) }} + matrix: ${{ fromJson(needs.discover.outputs.matrix) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Resolve variant + id: resolve + env: + DOCKER_USER: ${{ secrets.DOCKER_HUB_USERNAME }} + run: | + ./scripts/resolve-variant.sh \ + --variant-id "${{ matrix.variant_id }}" \ + --release "${{ inputs.release }}" \ + --docker-user "${DOCKER_USER}" \ + --output "${GITHUB_OUTPUT}" + + - name: Build and optionally push + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: ${{ !inputs.dry_run }} + platforms: ${{ steps.resolve.outputs.platforms }} + tags: ${{ steps.resolve.outputs.tags }} + build-args: | + UBUNTU_VERSION=${{ steps.resolve.outputs.ubuntu_version }} + APT_PROFILE=${{ steps.resolve.outputs.apt_profile }} + APT_PACKAGES_CSV=${{ steps.resolve.outputs.apt_packages_csv }} + JAVA_DEFAULT=${{ steps.resolve.outputs.java_default }} + SDK_PACKAGES_CSV=${{ steps.resolve.outputs.sdk_packages_csv }} + ENABLE_PROFILER=${{ steps.resolve.outputs.enable_profiler }} + ENABLE_PYTHON2=${{ steps.resolve.outputs.enable_python2 }} + ENABLE_GCC14=${{ steps.resolve.outputs.enable_gcc14 }} + ENABLE_EMULATOR=${{ steps.resolve.outputs.enable_emulator }} + ENABLE_MARATHON=${{ steps.resolve.outputs.enable_marathon }} + MARATHON_VERSION=${{ steps.resolve.outputs.marathon_version }} + + nothing-missing: + needs: discover + if: ${{ needs.discover.outputs.missing_count == '0' }} + runs-on: ubuntu-latest + steps: + - name: No-op + run: echo "All variants already exist for release ${{ inputs.release }}" diff --git a/.github/workflows/validate-config.yml b/.github/workflows/validate-config.yml new file mode 100644 index 0000000..4578d9f --- /dev/null +++ b/.github/workflows/validate-config.yml @@ -0,0 +1,31 @@ +name: validate-config + +on: + pull_request: + push: + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate variants schema and content + run: ./scripts/validate-variants.sh + + - name: Validate build tag parser for all variants + run: | + for variant_id in $(jq -r '.variants | keys[]' variants.json); do + ./scripts/parse-build-tag.sh "build/${variant_id}/v9999" >/dev/null + done + + - name: Validate variant resolution for all variants + run: | + for variant_id in $(jq -r '.variants | keys[]' variants.json); do + ./scripts/resolve-variant.sh \ + --variant-id "${variant_id}" \ + --release "v9999" \ + --docker-user "example" \ + >/dev/null + done diff --git a/Dockerfile b/Dockerfile index 6b64291..f90752a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,41 +1,170 @@ -FROM ubuntu:23.04 +ARG UBUNTU_VERSION=23.04 +FROM ubuntu:${UBUNTU_VERSION} -ENV DEBIAN_FRONTEND noninteractive +ARG APT_PROFILE=ubuntu23_old_releases +ARG APT_PACKAGES_CSV +ARG JAVA_DEFAULT +ARG SDK_PACKAGES_CSV +ARG ENABLE_PROFILER=false +ARG ENABLE_PYTHON2=false +ARG ENABLE_GCC14=false +ARG ENABLE_EMULATOR=false +ARG ENABLE_MARATHON=false +ARG MARATHON_VERSION=0.10.1 +ARG PYTHON_VERSION=2.7.5 -ENV ANDROID_HOME /opt/android-sdk-linux -ENV ANDROID_SDK_HOME ${ANDROID_HOME} -ENV ANDROID_SDK_ROOT ${ANDROID_HOME} -ENV ANDROID_SDK ${ANDROID_HOME} +ENV DEBIAN_FRONTEND=noninteractive -ENV PATH "${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin" -ENV PATH "${PATH}:${ANDROID_HOME}/cmdline-tools/tools/bin" -ENV PATH "${PATH}:${ANDROID_HOME}/tools/bin" -ENV PATH "${PATH}:${ANDROID_HOME}/build-tools/30.0.3" -ENV PATH "${PATH}:${ANDROID_HOME}/platform-tools" -ENV PATH "${PATH}:${ANDROID_HOME}/emulator" -ENV PATH "${PATH}:${ANDROID_HOME}/bin" +ENV ANDROID_HOME=/opt/android-sdk-linux +ENV ANDROID_SDK_HOME=${ANDROID_HOME} +ENV ANDROID_SDK_ROOT=${ANDROID_HOME} +ENV ANDROID_SDK=${ANDROID_HOME} +ENV ANDROID_NDK=/opt/android-ndk-linux +ENV ANDROID_NDK_ROOT=${ANDROID_NDK} +ENV GRADLE_PROFILER_HOME=/opt/gradle-profiler -RUN dpkg --add-architecture i386 && \ - apt-get update -yqq && \ - apt-get install -y sudo openjdk-17-jdk curl expect git git-lfs libc6:i386 libgcc1:i386 libncurses5:i386 libstdc++6:i386 zlib1g:i386 openjdk-11-jdk wget unzip vim && \ - apt-get clean +ENV PATH="${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin" +ENV PATH="${PATH}:${ANDROID_HOME}/cmdline-tools/tools/bin" +ENV PATH="${PATH}:${ANDROID_HOME}/tools/bin" +ENV PATH="${PATH}:${ANDROID_HOME}/build-tools/30.0.3" +ENV PATH="${PATH}:${ANDROID_HOME}/build-tools/33.0.1" +ENV PATH="${PATH}:${ANDROID_HOME}/build-tools/34.0.0" +ENV PATH="${PATH}:${ANDROID_HOME}/build-tools/35.0.0" +ENV PATH="${PATH}:${ANDROID_HOME}/build-tools/35.0.1" +ENV PATH="${PATH}:${ANDROID_HOME}/build-tools/36.0.0" +ENV PATH="${PATH}:${ANDROID_HOME}/platform-tools" +ENV PATH="${PATH}:${ANDROID_HOME}/emulator" +ENV PATH="${PATH}:${ANDROID_HOME}/bin" +ENV PATH="${PATH}:${GRADLE_PROFILER_HOME}/bin" +ENV PATH="${PATH}:/opt/marathon/bin" -RUN sudo update-java-alternatives --set java-1.17.0-openjdk-amd64 +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN set -eux; \ + dpkg --add-architecture i386; \ + case "${APT_PROFILE}" in \ + ubuntu23_old_releases) \ + if [ -f /etc/apt/sources.list ]; then \ + sed -i -re 's/([a-z]{2}\\.)?archive.ubuntu.com|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list; \ + else \ + cat <<'SRC' >/etc/apt/sources.list +deb http://old-releases.ubuntu.com/ubuntu/ lunar main restricted universe multiverse +deb http://old-releases.ubuntu.com/ubuntu/ lunar-updates main restricted universe multiverse +deb http://old-releases.ubuntu.com/ubuntu/ lunar-security main restricted universe multiverse +SRC + fi; \ + echo "deb http://security.ubuntu.com/ubuntu focal-security main universe" >> /etc/apt/sources.list; \ + ;; + ubuntu25_i386_focal) \ + touch /etc/apt/sources.list.d/i386.list; \ + if [ -f /etc/apt/sources.list ]; then \ + sed -i 's/^deb http/deb [arch=armhf] http/' /etc/apt/sources.list; \ + fi; \ + echo "deb [arch=i386] http://security.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse" >> /etc/apt/sources.list.d/i386.list; \ + echo "deb [arch=i386] http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse" >> /etc/apt/sources.list.d/i386.list; \ + echo "deb [arch=i386] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse" >> /etc/apt/sources.list.d/i386.list; \ + echo "deb [arch=i386] http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse" >> /etc/apt/sources.list.d/i386.list; \ + echo "deb http://security.ubuntu.com/ubuntu focal-security main universe" >> /etc/apt/sources.list; \ + ;; + ubuntu24_toolchain) \ + if [ -f /etc/apt/sources.list ]; then \ + sed -i -re 's/([a-z]{2}\\.)?archive.ubuntu.com|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list; \ + fi; \ + echo "deb http://security.ubuntu.com/ubuntu focal-security main universe" >> /etc/apt/sources.list; \ + ;; + *) \ + echo "Unsupported APT_PROFILE: ${APT_PROFILE}"; \ + exit 1; \ + ;; + esac; \ + apt-get update -yqq; \ + if [[ "${APT_PACKAGES_CSV}" == *"amazon-corretto"* ]]; then \ + apt-get install -y --no-install-recommends wget gpg; \ + wget -O - https://apt.corretto.aws/corretto.key | gpg --dearmor -o /usr/share/keyrings/corretto-keyring.gpg; \ + echo "deb [signed-by=/usr/share/keyrings/corretto-keyring.gpg] https://apt.corretto.aws stable main" > /etc/apt/sources.list.d/corretto.list; \ + apt-get update -yqq; \ + fi; \ + if [[ "${APT_PROFILE}" == "ubuntu24_toolchain" ]]; then \ + apt-get install -y --no-install-recommends software-properties-common; \ + add-apt-repository ppa:ubuntu-toolchain-r/test -y; \ + apt-get update -yqq; \ + fi; \ + if [[ -z "${APT_PACKAGES_CSV}" ]]; then \ + echo "APT_PACKAGES_CSV is required"; \ + exit 1; \ + fi; \ + IFS=',' read -r -a apt_packages <<< "${APT_PACKAGES_CSV}"; \ + apt-get install -y --no-install-recommends "${apt_packages[@]}"; \ + apt-get clean; \ + rm -rf /var/lib/apt/lists/* + +RUN set -eux; \ + if [[ -n "${JAVA_DEFAULT}" ]]; then \ + update-java-alternatives --set "${JAVA_DEFAULT}"; \ + fi + +RUN set -eux; \ + if [[ "${ENABLE_GCC14}" == "true" ]]; then \ + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100 --slave /usr/bin/g++ g++ /usr/bin/g++-14; \ + fi RUN groupadd android && useradd -d /opt/android-sdk-linux -g android android COPY tools /opt/tools COPY licenses /opt/licenses +RUN set -eux; \ + if [[ "${ENABLE_PROFILER}" == "true" ]]; then \ + mkdir -p "${GRADLE_PROFILER_HOME}"; \ + cd "${GRADLE_PROFILER_HOME}"; \ + wget https://repo1.maven.org/maven2/org/gradle/profiler/gradle-profiler/0.20.0/gradle-profiler-0.20.0.zip; \ + unzip gradle-profiler-0.20.0.zip; \ + mv -v gradle-profiler-0.20.0/* .; \ + rm -rf gradle-profiler-0.20.0 gradle-profiler-0.20.0.zip; \ + fi + +RUN set -eux; \ + if [[ "${ENABLE_PYTHON2}" == "true" ]]; then \ + cd /tmp; \ + wget "https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz"; \ + tar --extract -f "Python-${PYTHON_VERSION}.tgz"; \ + cd "Python-${PYTHON_VERSION}"; \ + ./configure --enable-optimizations --prefix=/usr/local; \ + make; \ + make install; \ + cd /tmp; \ + rm -rf "Python-${PYTHON_VERSION}" "Python-${PYTHON_VERSION}.tgz"; \ + python --version; \ + fi + WORKDIR /opt/android-sdk-linux RUN /opt/tools/entrypoint.sh built-in -RUN /opt/android-sdk-linux/cmdline-tools/tools/bin/sdkmanager "tools" -RUN /opt/android-sdk-linux/cmdline-tools/tools/bin/sdkmanager "cmdline-tools;latest" -RUN /opt/android-sdk-linux/cmdline-tools/tools/bin/sdkmanager "build-tools;30.0.3" -RUN /opt/android-sdk-linux/cmdline-tools/tools/bin/sdkmanager "platform-tools" -RUN /opt/android-sdk-linux/cmdline-tools/tools/bin/sdkmanager "platforms;android-33" -RUN /opt/android-sdk-linux/cmdline-tools/tools/bin/sdkmanager "system-images;android-33;google_apis;x86_64" +RUN set -eux; \ + if [[ -z "${SDK_PACKAGES_CSV}" ]]; then \ + echo "SDK_PACKAGES_CSV is required"; \ + exit 1; \ + fi; \ + IFS=',' read -r -a sdk_packages <<< "${SDK_PACKAGES_CSV}"; \ + for package in "${sdk_packages[@]}"; do \ + /opt/android-sdk-linux/cmdline-tools/tools/bin/sdkmanager "${package}"; \ + done + +RUN set -eux; \ + if [[ "${ENABLE_MARATHON}" == "true" ]]; then \ + mkdir -p /opt/marathon; \ + cd /opt/marathon; \ + wget -q "https://github.com/MarathonLabs/marathon/releases/download/${MARATHON_VERSION}/marathon-${MARATHON_VERSION}.zip" -O marathon.zip; \ + unzip marathon.zip; \ + rm -f marathon.zip; \ + ln -sf "/opt/marathon/marathon-${MARATHON_VERSION}/bin/marathon" /usr/local/bin/marathon; \ + marathon version; \ + fi + +RUN set -eux; \ + if [[ "${ENABLE_EMULATOR}" == "true" ]]; then \ + command -v emulator >/dev/null; \ + fi CMD /opt/tools/entrypoint.sh built-in diff --git a/README.md b/README.md index bd45837..c9c8dd8 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,138 @@ -# Docker for Android SDK 31 +# Unified Android SDK Docker Builds -Docker for Android SDK 31 with preinstalled build tools and emulator image +This repository uses one branch and one parameterized `Dockerfile`. +All image variants are defined in `variants.json` and released by Git tag. -> Edit from [mindrunner/docker-android-sdk](https://github.com/mindrunner/docker-android-sdk) +## Existing Variants And Differences + +| Variant ID | Ubuntu | Platforms | Java default | Android APIs | NDK / CMake | Extra features | +| --- | --- | --- | --- | --- | --- | --- | +| `api33-34-j11-17` | `23.04` | `linux/amd64` | `java-1.17.0-openjdk-amd64` | `33,34` | `-` | `-` | +| `api33-34-j17-21` | `23.04` | `linux/amd64` | `java-1.21.0-openjdk-amd64` | `33,34` | `-` | `-` | +| `api33-34-j11-17-u25-ma` | `25.04` | `linux/amd64,linux/arm64` | `java-1.17.0-openjdk-amd64` | `33,34` | `-` | `multi-arch` | +| `api33-34-j11-17-profiler` | `23.04` | `linux/amd64` | `java-1.17.0-openjdk-amd64` | `33,34` | `-` | `gradle-profiler` | +| `api34-35-j23-openjdk` | `23.04` | `linux/amd64` | `java-1.23.0-openjdk-amd64` | `34,35` | `-` | `-` | +| `api34-35-j17-21-23-ndk26` | `23.04` | `linux/amd64` | `java-23-amazon-corretto` | `34,35` | `ndk 26.2.11394342`, `cmake 3.18.1/3.22.1` | `python2` | +| `api34-35-j17-21-23-ndk26-emu-api35` | `23.04` | `linux/amd64` | `java-23-amazon-corretto` | `34,35` (+ `system-image 35`) | `ndk 26.2.11394342`, `cmake 3.18.1/3.22.1` | `python2`, `emulator`, `marathon 0.10.1` | +| `api34-35-j17-23` | `23.04` | `linux/amd64` | `java-23-amazon-corretto` | `34,35` | `-` | `-` | +| `api34-35-j17-23-ndk26` | `23.04` | `linux/amd64` | `java-23-amazon-corretto` | `34,35` | `ndk 26.2.11394342`, `cmake 3.18.1/3.22.1` | `python2` | +| `api34-35-j23-corretto` | `23.04` | `linux/amd64` | `java-23-amazon-corretto` | `34,35` | `-` | `-` | +| `api35-36-j17-23` | `23.04` | `linux/amd64` | `java-23-amazon-corretto` | `35,36` | `-` | `-` | +| `api35-36-j17-23-ndk29-u24-gcc14` | `24.04` | `linux/amd64` | `java-23-amazon-corretto` | `35,36` | `ndk 29.0.14033849`, `cmake 4.1.1` | `python2`, `gcc14` | + +## Release By Git Tag + +Push a Git tag in this format: -**Installed Packages** ```bash -# sdkmanager --list - Path | Version | Description | Location - ------- | ------- | ------- | ------- - build-tools;30.0.3 | 30.0.3 | Android SDK Build-Tools 33 | build-tools/30.0.3 - cmdline-tools;latest | 6.0 | Android SDK Command-line Tools (latest) | cmdline-tools/latest - emulator | 31.2.8 | Android Emulator | emulator - patcher;v4 | 1 | SDK Patch Applier v4 | patcher/v4 - platform-tools | latest | Android SDK Platform-Tools | platform-tools - platforms;android-31 | 1 | Android SDK Platform 33 | platforms/android-33 - system-images;android-31;google_apis;x86_64 | 8 | Google APIs Intel x86 Atom_64 System Image | system-images/android-33/google_apis/x86_64 +build//vN ``` -**Usage** - -- Interactive way - ```bash - $ docker run -it --rm --device /dev/kvm androidsdk/android-31:latest bash - # check installed packages - $ sdkmanager --list - # create and run emulator - $ avdmanager create avd -n first_avd --abi google_apis/x86_64 -k "system-images;android-33;google_apis;x86_64" - $ emulator -avd first_avd -no-window -no-audio & - $ adb devices - # You can also run other Android platform tools, which are all added to the PATH environment variable - ``` - - To connect the emulator using `adb` on the docker host machine, start the container with `--network host` as well. - You could also use [`scrcpy`](https://github.com/Genymobile/scrcpy) to do a screencast of the emulator. - -- Non-interactive way - ```bash - # check installed packages - $ docker run -it --rm androidsdk/android-33:latest sdkmanager --list - # list existing emulators - $ docker run -it --rm androidsdk/android-33:latest avdmanager list avd - # You can also run other Android platform tools, which are all added to the PATH environment variable - ``` \ No newline at end of file +Example: + +```bash +git tag build/api34-35-j17-23-ndk26/v5 +git push origin build/api34-35-j17-23-ndk26/v5 +``` + +This triggers `.github/workflows/publish-by-tag.yml` and publishes: + +- `DOCKER_HUB_USERNAME/android-sdk:` +- `DOCKER_HUB_USERNAME/android-sdk:-vN` + +## Manual Release For Missing Variants + +Use `.github/workflows/release-all-missing.yml` (`workflow_dispatch`) with inputs: + +- `release`: `vN` +- `dry_run`: `true` or `false` +- `max_parallel`: parallel build limit + +Behavior: + +- Checks each variant for `android-sdk:-vN` +- Skips existing tags +- Builds only missing variants +- Pushes only when `dry_run=false` + +## Tools And Licenses + +- `tools/` now supports built-in mode only (legacy `lazy-dl` flow removed). +- Removed outdated legacy package lists and unused emulator wait script. +- `licenses/` is kept and copied into images to preserve non-interactive SDK license acceptance. +- `/opt/tools/entrypoint.sh` initializes SDK state at container start. +- `/opt/tools/android-sdk-update.sh` bootstraps commandline tools, updates SDK metadata, and accepts licenses. +- `/opt/tools/android-env.sh` exports Android env vars and provides `update_sdk` / `andep`. +- `/opt/tools/android-accept-licenses.sh` is an `expect` wrapper that auto-confirms SDK license prompts. + +### Runtime Usage In Container + +```bash +source /opt/android-sdk-linux/bin/android-env.sh +sdkmanager --list +andep "platforms;android-36" +update_sdk +``` + +## Java Switching (Variants With Multiple Installed JDKs) + +Use this to see available Java alternatives in a container: + +```bash +update-java-alternatives --list +``` + +Use this to switch active system Java: + +```bash +update-java-alternatives --set +java -version +``` + +If you run as a non-root user, switch Java for the current shell with: + +```bash +export JAVA_HOME= +export PATH="${JAVA_HOME}/bin:${PATH}" +java -version +``` + +Multi-JDK variants: + +| Variant ID | Installed Java packages | Default Java | Example switches | +| --- | --- | --- | --- | +| `api33-34-j11-17` | `openjdk-11-jdk`, `openjdk-17-jdk` | `java-1.17.0-openjdk-amd64` | `update-java-alternatives --set java-1.11.0-openjdk-amd64` | +| `api33-34-j17-21` | `openjdk-17-jdk`, `openjdk-21-jdk` | `java-1.21.0-openjdk-amd64` | `update-java-alternatives --set java-1.17.0-openjdk-amd64` | +| `api33-34-j11-17-u25-ma` | `openjdk-11-jdk`, `openjdk-17-jdk` | `java-1.17.0-openjdk-amd64` | `update-java-alternatives --set java-1.11.0-openjdk-amd64` | +| `api33-34-j11-17-profiler` | `openjdk-11-jdk`, `openjdk-17-jdk` | `java-1.17.0-openjdk-amd64` | `update-java-alternatives --set java-1.11.0-openjdk-amd64` | +| `api34-35-j17-21-23-ndk26` | `openjdk-17-jdk`, `java-21-amazon-corretto-jdk`, `java-23-amazon-corretto-jdk` | `java-23-amazon-corretto` | `update-java-alternatives --set java-21-amazon-corretto`, `update-java-alternatives --set java-1.17.0-openjdk-amd64` | +| `api34-35-j17-21-23-ndk26-emu-api35` | `openjdk-17-jdk`, `java-21-amazon-corretto-jdk`, `java-23-amazon-corretto-jdk` | `java-23-amazon-corretto` | `update-java-alternatives --set java-21-amazon-corretto`, `update-java-alternatives --set java-1.17.0-openjdk-amd64` | +| `api34-35-j17-23` | `openjdk-17-jdk`, `java-23-amazon-corretto-jdk` | `java-23-amazon-corretto` | `update-java-alternatives --set java-1.17.0-openjdk-amd64` | +| `api34-35-j17-23-ndk26` | `openjdk-17-jdk`, `java-23-amazon-corretto-jdk` | `java-23-amazon-corretto` | `update-java-alternatives --set java-1.17.0-openjdk-amd64` | +| `api35-36-j17-23` | `openjdk-17-jdk`, `java-23-amazon-corretto-jdk` | `java-23-amazon-corretto` | `update-java-alternatives --set java-1.17.0-openjdk-amd64` | +| `api35-36-j17-23-ndk29-u24-gcc14` | `openjdk-17-jdk`, `java-23-amazon-corretto-jdk` | `java-23-amazon-corretto` | `update-java-alternatives --set java-1.17.0-openjdk-amd64` | + +## Local Validation + +```bash +./scripts/validate-variants.sh + +for id in $(jq -r '.variants | keys[]' variants.json); do + ./scripts/parse-build-tag.sh "build/${id}/v9999" >/dev/null + ./scripts/resolve-variant.sh --variant-id "${id}" --release v9999 --docker-user example >/dev/null +done +``` + +## Files + +- `variants.json`: variant source of truth +- `Dockerfile`: parameterized build template +- `tools/`: bootstrap and SDK helper scripts used inside image build/runtime +- `licenses/`: Android SDK license hashes copied into the image +- `scripts/parse-build-tag.sh`: validates/parses `build//vN` +- `scripts/resolve-variant.sh`: resolves build args + output tags from `variants.json` +- `scripts/list-missing-for-release.sh`: finds variants missing `-vN` image tags +- `scripts/validate-variants.sh`: schema/content validation +- `.github/workflows/publish-by-tag.yml`: release by Git tag +- `.github/workflows/release-all-missing.yml`: manual release missing variants only +- `.github/workflows/validate-config.yml`: CI config validation diff --git a/scripts/list-missing-for-release.sh b/scripts/list-missing-for-release.sh new file mode 100755 index 0000000..a1e8f8a --- /dev/null +++ b/scripts/list-missing-for-release.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat >&2 <<'USAGE' +Usage: + list-missing-for-release.sh --release --docker-user [--variants-file ] [--output ] +USAGE +} + +release="" +docker_user="${DOCKER_USER:-}" +variants_file="${VARIANTS_FILE:-variants.json}" +output_file="${GITHUB_OUTPUT:-}" + +while [[ $# -gt 0 ]]; do + case "$1" in + --release) + release="$2" + shift 2 + ;; + --docker-user) + docker_user="$2" + shift 2 + ;; + --variants-file) + variants_file="$2" + shift 2 + ;; + --output) + output_file="$2" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 1 + ;; + esac +done + +if [[ -z "${release}" || -z "${docker_user}" ]]; then + usage + exit 1 +fi + +if [[ ! "${release}" =~ ^v[0-9]+$ ]]; then + echo "Invalid release format: ${release} (expected vN)" >&2 + exit 1 +fi + +if [[ ! -f "${variants_file}" ]]; then + echo "Variants file not found: ${variants_file}" >&2 + exit 1 +fi + +if ! command -v docker >/dev/null 2>&1; then + echo "docker command is required" >&2 + exit 1 +fi + +image_repo="$(jq -r '.image_repo' "${variants_file}")" + +missing_ids=() +while IFS= read -r variant_id; do + candidate_tag="${docker_user}/${image_repo}:${variant_id}-${release}" + if docker buildx imagetools inspect "${candidate_tag}" >/dev/null 2>&1; then + echo "existing: ${candidate_tag}" >&2 + else + echo "missing: ${candidate_tag}" >&2 + missing_ids+=("${variant_id}") + fi +done < <(jq -r '.variants | keys[]' "${variants_file}") + +if [[ ${#missing_ids[@]} -eq 0 ]]; then + matrix='{"include":[]}' +else + matrix="$(printf '%s\n' "${missing_ids[@]}" | jq -R . | jq -cs '{include: map({variant_id: .})}')" +fi + +missing_count="${#missing_ids[@]}" +missing_csv="$(IFS=','; echo "${missing_ids[*]:-}")" + +if [[ -n "${output_file}" ]]; then + { + echo "missing_count=${missing_count}" + echo "missing_csv=${missing_csv}" + echo "matrix=${matrix}" + } >>"${output_file}" +else + echo "missing_count=${missing_count}" + echo "missing_csv=${missing_csv}" + echo "matrix=${matrix}" +fi diff --git a/scripts/parse-build-tag.sh b/scripts/parse-build-tag.sh new file mode 100755 index 0000000..16b8236 --- /dev/null +++ b/scripts/parse-build-tag.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + echo "Usage: $0 [output_file]" >&2 + echo "Example: $0 build/api34-35-j17-23-ndk26/v5" >&2 +} + +tag="${1:-}" +output_file="${2:-${GITHUB_OUTPUT:-}}" + +if [[ -z "${tag}" ]]; then + usage + exit 1 +fi + +if [[ "${tag}" =~ ^build/([a-z0-9][a-z0-9-]*)/(v[0-9]+)$ ]]; then + variant_id="${BASH_REMATCH[1]}" + release="${BASH_REMATCH[2]}" +else + echo "Invalid build tag: ${tag}" >&2 + echo "Expected format: build//vN" >&2 + exit 1 +fi + +if [[ -n "${output_file}" ]]; then + { + echo "build_tag=${tag}" + echo "variant_id=${variant_id}" + echo "release=${release}" + } >>"${output_file}" +else + echo "build_tag=${tag}" + echo "variant_id=${variant_id}" + echo "release=${release}" +fi diff --git a/scripts/resolve-variant.sh b/scripts/resolve-variant.sh new file mode 100755 index 0000000..0299322 --- /dev/null +++ b/scripts/resolve-variant.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat >&2 <<'USAGE' +Usage: + resolve-variant.sh --variant-id --release [--docker-user ] [--variants-file ] [--output ] +USAGE +} + +variant_id="" +release="" +docker_user="${DOCKER_USER:-}" +variants_file="${VARIANTS_FILE:-variants.json}" +output_file="${GITHUB_OUTPUT:-}" + +while [[ $# -gt 0 ]]; do + case "$1" in + --variant-id) + variant_id="$2" + shift 2 + ;; + --release) + release="$2" + shift 2 + ;; + --docker-user) + docker_user="$2" + shift 2 + ;; + --variants-file) + variants_file="$2" + shift 2 + ;; + --output) + output_file="$2" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 1 + ;; + esac +done + +if [[ -z "${variant_id}" || -z "${release}" ]]; then + usage + exit 1 +fi + +if [[ ! "${release}" =~ ^v[0-9]+$ ]]; then + echo "Invalid release format: ${release} (expected vN)" >&2 + exit 1 +fi + +if [[ -z "${docker_user}" ]]; then + docker_user="example" +fi + +if [[ ! -f "${variants_file}" ]]; then + echo "Variants file not found: ${variants_file}" >&2 + exit 1 +fi + +variant_json="$(jq -ce --arg id "${variant_id}" '.variants[$id]' "${variants_file}")" || { + echo "Variant not found: ${variant_id}" >&2 + exit 1 +} + +image_repo="$(jq -r '.image_repo' "${variants_file}")" +platforms="$(jq -r '.platforms | join(",")' <<<"${variant_json}")" +ubuntu_version="$(jq -r '.docker.ubuntu' <<<"${variant_json}")" +apt_profile="$(jq -r '.docker.apt_profile' <<<"${variant_json}")" +apt_packages_csv="$(jq -r '.docker.apt_packages | join(",")' <<<"${variant_json}")" +java_default="$(jq -r '.docker.java_default' <<<"${variant_json}")" +sdk_packages_csv="$(jq -r '.docker.sdk_packages | join(",")' <<<"${variant_json}")" +enable_profiler="$(jq -r '.docker.features.profiler' <<<"${variant_json}")" +enable_python2="$(jq -r '.docker.features.python2' <<<"${variant_json}")" +enable_gcc14="$(jq -r '.docker.features.gcc14' <<<"${variant_json}")" +enable_emulator="$(jq -r '.docker.features.emulator // false' <<<"${variant_json}")" +enable_marathon="$(jq -r '.docker.features.marathon // false' <<<"${variant_json}")" +marathon_version="$(jq -r '.docker.marathon_version // ""' <<<"${variant_json}")" + +canonical_tag="${docker_user}/${image_repo}:${variant_id}" +release_tag="${docker_user}/${image_repo}:${variant_id}-${release}" + +if [[ -n "${output_file}" ]]; then + { + echo "variant_id=${variant_id}" + echo "release=${release}" + echo "image_repo=${image_repo}" + echo "platforms=${platforms}" + echo "ubuntu_version=${ubuntu_version}" + echo "apt_profile=${apt_profile}" + echo "apt_packages_csv=${apt_packages_csv}" + echo "java_default=${java_default}" + echo "sdk_packages_csv=${sdk_packages_csv}" + echo "enable_profiler=${enable_profiler}" + echo "enable_python2=${enable_python2}" + echo "enable_gcc14=${enable_gcc14}" + echo "enable_emulator=${enable_emulator}" + echo "enable_marathon=${enable_marathon}" + echo "marathon_version=${marathon_version}" + echo "canonical_tag=${canonical_tag}" + echo "release_tag=${release_tag}" + echo "tags<>"${output_file}" +else + cat <&2 + exit 1 +fi + +if ! command -v jq >/dev/null 2>&1; then + echo "jq is required" >&2 + exit 1 +fi + +expected_ids_json='[ + "api33-34-j11-17", + "api33-34-j11-17-profiler", + "api33-34-j11-17-u25-ma", + "api33-34-j17-21", + "api34-35-j17-21-23-ndk26", + "api34-35-j17-21-23-ndk26-emu-api35", + "api34-35-j17-23", + "api34-35-j17-23-ndk26", + "api34-35-j23-corretto", + "api34-35-j23-openjdk", + "api35-36-j17-23", + "api35-36-j17-23-ndk29-u24-gcc14" +]' + +jq -e '.image_repo | type == "string" and length > 0' "${variants_file}" >/dev/null +jq -e '.variants | type == "object" and length > 0' "${variants_file}" >/dev/null +jq -e --argjson expected_ids "${expected_ids_json}" ' + (.variants | keys | sort) == ($expected_ids | sort) +' "${variants_file}" >/dev/null + +jq -e ' + .variants + | to_entries + | all( + (.key | test("^[a-z0-9][a-z0-9-]*$")) + and (.value.platforms | type == "array" and length > 0 and all(test("^linux/(amd64|arm64)$"))) + and (.value.docker.ubuntu | type == "string" and test("^[0-9]+\\.[0-9]+$")) + and (.value.docker.apt_profile | IN("ubuntu23_old_releases", "ubuntu25_i386_focal", "ubuntu24_toolchain")) + and (.value.docker.apt_packages | type == "array" and length > 0 and length == (unique | length) and all(type == "string" and length > 0 and (contains(",") | not))) + and (.value.docker.java_default | type == "string" and length > 0) + and (.value.docker.sdk_packages | type == "array" and length > 0 and length == (unique | length) and all(type == "string" and length > 0 and (contains(",") | not))) + and (.value.docker.features | type == "object") + and (.value.docker.features.profiler | type == "boolean") + and (.value.docker.features.python2 | type == "boolean") + and (.value.docker.features.gcc14 | type == "boolean") + and (.value.docker.features.emulator | type == "boolean") + and (.value.docker.features.marathon | type == "boolean") + and ( + if .value.docker.features.marathon + then (.value.docker.marathon_version | type == "string" and test("^[0-9]+\\.[0-9]+\\.[0-9]+$")) + else ((.value.docker | has("marathon_version")) | not) + end + ) + ) +' "${variants_file}" >/dev/null + +echo "Variants configuration is valid: ${variants_file}" diff --git a/tools/android-env.sh b/tools/android-env.sh index 35e9888..97690b0 100644 --- a/tools/android-env.sh +++ b/tools/android-env.sh @@ -9,28 +9,20 @@ export PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin export PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/tools/bin export PATH=${PATH}:${ANDROID_HOME}/tools/bin export PATH=${PATH}:${ANDROID_HOME}/build-tools/30.0.3 +export PATH=${PATH}:${ANDROID_HOME}/build-tools/33.0.1 +export PATH=${PATH}:${ANDROID_HOME}/build-tools/34.0.0 +export PATH=${PATH}:${ANDROID_HOME}/build-tools/35.0.0 +export PATH=${PATH}:${ANDROID_HOME}/build-tools/35.0.1 +export PATH=${PATH}:${ANDROID_HOME}/build-tools/36.0.0 export PATH=${PATH}:${ANDROID_HOME}/platform-tools export PATH=${PATH}:${ANDROID_HOME}/emulator export PATH=${PATH}:${ANDROID_HOME}/bin -function print_header() { - figlet SBB CFF FFS - figlet welcome to - figlet andep - echo '' - echo '' - echo '' -} - function help() { - figlet "usage:" - echo "update_sdk: Updates the SDK" - echo "andep: Installs one or more android Packets." - echo " -Example: anddep \"platforms;android-26\"" - echo "help: Shows this help" - echo '' - echo '' - echo '' + echo "usage:" + echo " update_sdk Updates installed Android SDK metadata" + echo " andep \"\" Installs one Android SDK package" + echo " help Shows this help" } function update_sdk() { @@ -38,11 +30,11 @@ function update_sdk() { } function andep() { - if [ -z ${1} ]; then + if [ -z "${1:-}" ]; then help return 1 fi - android-accept-licenses.sh "sdkmanager ${1}" + android-accept-licenses.sh "sdkmanager ${1}" } export -f help diff --git a/tools/android-sdk-update.sh b/tools/android-sdk-update.sh index 11f6f99..0ce203d 100755 --- a/tools/android-sdk-update.sh +++ b/tools/android-sdk-update.sh @@ -1,65 +1,43 @@ -#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail + +mode="${1:-built-in}" +if [[ "${mode}" != "built-in" ]]; then + echo "Only 'built-in' mode is supported" >&2 + exit 1 +fi mkdir -p /opt/android-sdk-linux/bin/ cp /opt/tools/android-env.sh /opt/android-sdk-linux/bin/ source /opt/android-sdk-linux/bin/android-env.sh -built_in_sdk=1 - - -echo $# - -echo $1 - -if [ $# -ge 0 ] && [ "$1" == "lazy-dl" ] -then - echo "Using Lazy Download Flavour" - built_in_sdk=0 -elif [ $# -ge 0 ] && [ "$1" == "built-in" ] -then - echo "Using Built-In SDK Flavour" - built_in_sdk=1 -else - echo "Please use either built-in or lazy-dl as parameter" - exit 1 -fi - -cd ${ANDROID_HOME} +cd "${ANDROID_HOME}" echo "Set ANDROID_HOME to ${ANDROID_HOME}" -if [ -f commandlinetools-linux.zip ] -then +if [[ -f commandlinetools-linux.zip ]]; then echo "SDK Tools already bootstrapped. Skipping initial setup" else echo "Bootstrapping SDK-Tools" wget -q https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip -O commandlinetools-linux.zip unzip commandlinetools-linux.zip - mkdir cmdline-tools + mkdir -p cmdline-tools mv tools cmdline-tools/ rm commandlinetools-linux.zip fi -echo "Make sure repositories.cfg exists" +echo "Ensuring repositories.cfg exists" mkdir -p ~/.android/ touch ~/.android/repositories.cfg -echo "Copying Licences" -cp -rv /opt/licenses ${ANDROID_HOME}/licenses +echo "Copying licenses" +cp -rv /opt/licenses "${ANDROID_HOME}/licenses" -echo "Copying Tools" -mkdir -p ${ANDROID_HOME}/bin -cp -v /opt/tools/*.sh ${ANDROID_HOME}/bin - -echo "Installing packages" -if [ $built_in_sdk -eq 1 ] -then - android-accept-licenses.sh "sdkmanager --package_file=/opt/tools/package-list-minimal.txt --verbose" -else - android-accept-licenses.sh "sdkmanager --package_file=/opt/tools/package-list.txt --verbose" -fi +echo "Copying tools" +mkdir -p "${ANDROID_HOME}/bin" +cp -v /opt/tools/*.sh "${ANDROID_HOME}/bin" -echo "Updating SDK" +echo "Updating SDK metadata" update_sdk -echo "Accepting Licenses" +echo "Accepting SDK licenses" android-accept-licenses.sh "sdkmanager --licenses --verbose" diff --git a/tools/android-wait-for-emulator.sh b/tools/android-wait-for-emulator.sh deleted file mode 100755 index 0219687..0000000 --- a/tools/android-wait-for-emulator.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -set +e - -bootcomplete="" -failcounter=0 -timeout=600 -sleeptime=10 -maxfail=$((timeout / sleeptime)) - -until [[ "${bootcomplete}" =~ "1" ]]; do - bootcomplete=`adb -e shell getprop dev.bootcomplete 2>&1 &` - if [[ "${bootcomplete}" =~ "" ]]; then - ((failcounter += 1)) - echo "Waiting for emulator to start" - if [[ ${failcounter} -gt ${maxfail} ]]; then - echo "Timeout ($timeout seconds) reached; failed to start emulator" - while pkill -9 "emulator" >/dev/null 2>&1; do - echo "Killing emulator proces...." - pgrep "emulator" - done - echo "Process terminated" - pgrep "emulator" - exit 1 - fi - fi - sleep ${sleeptime} -done - -echo "Emulator is ready" diff --git a/tools/entrypoint.sh b/tools/entrypoint.sh index 74a629b..38d3dfc 100755 --- a/tools/entrypoint.sh +++ b/tools/entrypoint.sh @@ -1,11 +1,8 @@ -#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail function checkbin() { - type -P su-exec -} - -function su_mt_user() { - su android -c '"$0" "$@"' -- "$@" + type -P su-exec >/dev/null 2>&1 } chown android:android /opt/android-sdk-linux @@ -13,12 +10,5 @@ chown android:android /opt/android-sdk-linux if checkbin; then exec su-exec android:android /opt/tools/android-sdk-update.sh "$@" else - su_mt_user /opt/tools/android-sdk-update.sh ${1} + exec su android -s /bin/bash -c '/opt/tools/android-sdk-update.sh "$@"' -- "$@" fi - - - - - - - diff --git a/tools/package-list-minimal.txt b/tools/package-list-minimal.txt deleted file mode 100644 index 3cf9455..0000000 --- a/tools/package-list-minimal.txt +++ /dev/null @@ -1,23 +0,0 @@ -add-ons;addon-google_apis-google-26 -add-ons;addon-google_apis-google-27 -build-tools;26.0.3 -build-tools;27.0.0 -cmake;3.6.4111459 -emulator -extras;android;gapid;1 -extras;android;gapid;3 -extras;android;m2repository -extras;google;auto -extras;google;google_play_services -extras;google;instantapps -extras;google;m2repository -extras;google;market_apk_expansion -extras;google;market_licensing -extras;google;simulators -extras;google;webdriver -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.2 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.2 -lldb;2.3 -platforms;android-26 -platforms;android-27 -tools diff --git a/tools/package-list.txt b/tools/package-list.txt deleted file mode 100644 index 60709b2..0000000 --- a/tools/package-list.txt +++ /dev/null @@ -1,182 +0,0 @@ -add-ons;addon-google_apis-google-15 -add-ons;addon-google_apis-google-16 -add-ons;addon-google_apis-google-17 -add-ons;addon-google_apis-google-18 -add-ons;addon-google_apis-google-19 -add-ons;addon-google_apis-google-21 -add-ons;addon-google_apis-google-22 -add-ons;addon-google_apis-google-23 -add-ons;addon-google_apis-google-24 -add-ons;addon-google_gdk-google-19 -build-tools;19.1.0 -build-tools;20.0.0 -build-tools;21.1.2 -build-tools;22.0.1 -build-tools;23.0.1 -build-tools;23.0.2 -build-tools;23.0.3 -build-tools;24.0.0 -build-tools;24.0.1 -build-tools;24.0.2 -build-tools;24.0.3 -build-tools;25.0.0 -build-tools;25.0.1 -build-tools;25.0.2 -build-tools;25.0.3 -build-tools;26.0.0 -build-tools;26.0.2 -build-tools;26.0.3 -build-tools;27.0.0 -cmake;3.6.4111459 -emulator -extras;android;gapid;1 -extras;android;gapid;3 -extras;android;m2repository -extras;google;auto -extras;google;google_play_services -extras;google;instantapps -extras;google;m2repository -extras;google;market_apk_expansion -extras;google;market_licensing -extras;google;simulators -extras;google;webdriver -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha2 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha3 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha4 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha5 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha6 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha7 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha8 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha9 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta1 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta2 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta3 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta4 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta5 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.1 -extras;m2repository;com;android;support;constraint;constraint-layout;1.0.2 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha2 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha3 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha4 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha5 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha6 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha7 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha8 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha9 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-beta1 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-beta2 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-beta3 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-beta4 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-beta5 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.1 -extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.2 -lldb;2.3 -platforms;android-10 -platforms;android-11 -platforms;android-12 -platforms;android-13 -platforms;android-14 -platforms;android-15 -platforms;android-16 -platforms;android-17 -platforms;android-18 -platforms;android-19 -platforms;android-20 -platforms;android-21 -platforms;android-22 -platforms;android-23 -platforms;android-24 -platforms;android-25 -platforms;android-26 -platforms;android-7 -platforms;android-8 -platforms;android-9 -sources;android-15 -sources;android-16 -sources;android-17 -sources;android-18 -sources;android-19 -sources;android-20 -sources;android-21 -sources;android-22 -sources;android-23 -sources;android-24 -sources;android-25 -sources;android-26 -sources;android-27 -system-images;android-10;default;armeabi-v7a -system-images;android-10;default;x86 -system-images;android-10;google_apis;armeabi-v7a -system-images;android-10;google_apis;x86 -system-images;android-14;default;armeabi-v7a -system-images;android-15;default;armeabi-v7a -system-images;android-15;default;mips -system-images;android-15;default;x86 -system-images;android-15;google_apis;armeabi-v7a -system-images;android-15;google_apis;x86 -system-images;android-16;default;armeabi-v7a -system-images;android-16;default;mips -system-images;android-16;default;x86 -system-images;android-16;google_apis;x86 -system-images;android-17;default;armeabi-v7a -system-images;android-17;default;mips -system-images;android-17;default;x86 -system-images;android-17;google_apis;armeabi-v7a -system-images;android-17;google_apis;x86 -system-images;android-18;default;armeabi-v7a -system-images;android-18;default;x86 -system-images;android-18;google_apis;armeabi-v7a -system-images;android-18;google_apis;x86 -system-images;android-19;default;armeabi-v7a -system-images;android-19;default;x86 -system-images;android-19;google_apis;armeabi-v7a -system-images;android-19;google_apis;x86 -system-images;android-21;android-tv;armeabi-v7a -system-images;android-21;android-tv;x86 -system-images;android-21;default;armeabi-v7a -system-images;android-21;default;x86 -system-images;android-21;default;x86_64 -system-images;android-21;google_apis;armeabi-v7a -system-images;android-21;google_apis;x86 -system-images;android-21;google_apis;x86_64 -system-images;android-22;android-tv;armeabi-v7a -system-images;android-22;android-tv;x86 -system-images;android-22;default;armeabi-v7a -system-images;android-22;default;armeabi-v7a -system-images;android-22;default;x86 -system-images;android-22;default;x86_64 -system-images;android-22;google_apis;armeabi-v7a -system-images;android-22;google_apis;x86 -system-images;android-22;google_apis;x86_64 -system-images;android-23;android-tv;armeabi-v7a -system-images;android-23;android-tv;x86 -system-images;android-23;android-wear;armeabi-v7a -system-images;android-23;android-wear;x86 -system-images;android-23;default;x86 -system-images;android-23;default;x86_64 -system-images;android-23;google_apis;armeabi-v7a -system-images;android-23;google_apis;x86 -system-images;android-23;google_apis;x86_64 -system-images;android-24;android-tv;x86 -system-images;android-24;default;arm64-v8a -system-images;android-24;default;armeabi-v7a -system-images;android-24;default;x86 -system-images;android-24;default;x86_64 -system-images;android-24;google_apis;arm64-v8a -system-images;android-24;google_apis;armeabi-v7a -system-images;android-24;google_apis_playstore;x86 -system-images;android-24;google_apis;x86 -system-images;android-24;google_apis;x86_64 -system-images;android-25;android-tv;x86 -system-images;android-25;android-wear;armeabi-v7a -system-images;android-25;android-wear;x86 -system-images;android-25;google_apis;armeabi-v7a -system-images;android-25;google_apis;x86 -system-images;android-25;google_apis;x86_64 -system-images;android-26;android-tv;x86 -system-images;android-26;android-wear;x86 -system-images;android-26;google_apis_playstore;x86 -system-images;android-26;google_apis;x86 -tools diff --git a/variants.json b/variants.json new file mode 100644 index 0000000..113b647 --- /dev/null +++ b/variants.json @@ -0,0 +1,615 @@ +{ + "image_repo": "android-sdk", + "variants": { + "api33-34-j11-17": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "openjdk-17-jdk", + "openjdk-11-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libgcc1:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq" + ], + "java_default": "java-1.17.0-openjdk-amd64", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;30.0.3", + "build-tools;33.0.1", + "build-tools;34.0.0", + "platform-tools", + "platforms;android-33", + "platforms;android-34", + "system-images;android-33;google_apis;x86_64", + "system-images;android-34;google_apis;x86_64" + ], + "features": { + "profiler": false, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api33-34-j17-21": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "openjdk-21-jdk", + "openjdk-17-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq" + ], + "java_default": "java-1.21.0-openjdk-amd64", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;30.0.3", + "build-tools;33.0.1", + "build-tools;34.0.0", + "platform-tools", + "platforms;android-33", + "platforms;android-34", + "system-images;android-33;google_apis;x86_64", + "system-images;android-34;google_apis;x86_64" + ], + "features": { + "profiler": false, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api33-34-j11-17-u25-ma": { + "platforms": [ + "linux/amd64", + "linux/arm64" + ], + "docker": { + "ubuntu": "25.04", + "apt_profile": "ubuntu25_i386_focal", + "apt_packages": [ + "sudo", + "openjdk-17-jdk", + "openjdk-11-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libgcc1:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq" + ], + "java_default": "java-1.17.0-openjdk-amd64", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;30.0.3", + "build-tools;33.0.1", + "build-tools;34.0.0", + "platform-tools", + "platforms;android-33", + "platforms;android-34", + "system-images;android-33;google_apis;x86_64", + "system-images;android-34;google_apis;x86_64" + ], + "features": { + "profiler": false, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api33-34-j11-17-profiler": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "openjdk-17-jdk", + "openjdk-11-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libgcc1:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "zip", + "vim", + "jq" + ], + "java_default": "java-1.17.0-openjdk-amd64", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;33.0.1", + "build-tools;34.0.0", + "platform-tools", + "platforms;android-33", + "platforms;android-34" + ], + "features": { + "profiler": true, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api34-35-j23-openjdk": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "openjdk-23-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq" + ], + "java_default": "java-1.23.0-openjdk-amd64", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;34.0.0", + "build-tools;35.0.1", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-34", + "platforms;android-35", + "system-images;android-34;google_apis;x86_64", + "system-images;android-35;google_apis;x86_64" + ], + "features": { + "profiler": false, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api34-35-j17-21-23-ndk26": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "rsync", + "openjdk-17-jdk", + "java-21-amazon-corretto-jdk", + "java-23-amazon-corretto-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq", + "net-tools", + "ccache", + "g++", + "gcc", + "make", + "openssl" + ], + "java_default": "java-23-amazon-corretto", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;34.0.0", + "build-tools;35.0.0", + "build-tools;35.0.1", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-34", + "platforms;android-35", + "system-images;android-34;google_apis;x86_64", + "system-images;android-35;google_apis;x86_64", + "cmake;3.18.1", + "cmake;3.22.1", + "ndk;26.2.11394342" + ], + "features": { + "profiler": false, + "python2": true, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api34-35-j17-23": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "rsync", + "openjdk-17-jdk", + "java-23-amazon-corretto-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq" + ], + "java_default": "java-23-amazon-corretto", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;34.0.0", + "build-tools;35.0.0", + "build-tools;35.0.1", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-34", + "platforms;android-35", + "system-images;android-34;google_apis;x86_64", + "system-images;android-35;google_apis;x86_64" + ], + "features": { + "profiler": false, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api34-35-j17-23-ndk26": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "rsync", + "openjdk-17-jdk", + "java-23-amazon-corretto-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq", + "net-tools", + "ccache", + "g++", + "gcc", + "make", + "openssl" + ], + "java_default": "java-23-amazon-corretto", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;34.0.0", + "build-tools;35.0.0", + "build-tools;35.0.1", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-34", + "platforms;android-35", + "system-images;android-34;google_apis;x86_64", + "system-images;android-35;google_apis;x86_64", + "cmake;3.18.1", + "cmake;3.22.1", + "ndk;26.2.11394342" + ], + "features": { + "profiler": false, + "python2": true, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api34-35-j23-corretto": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "java-23-amazon-corretto-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq" + ], + "java_default": "java-23-amazon-corretto", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;34.0.0", + "build-tools;35.0.1", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-34", + "platforms;android-35", + "system-images;android-34;google_apis;x86_64", + "system-images;android-35;google_apis;x86_64" + ], + "features": { + "profiler": false, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api35-36-j17-23": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "rsync", + "openjdk-17-jdk", + "java-23-amazon-corretto-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq" + ], + "java_default": "java-23-amazon-corretto", + "sdk_packages": [ + "cmdline-tools;latest", + "build-tools;35.0.0", + "build-tools;35.0.1", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-35", + "platforms;android-36", + "system-images;android-35;google_apis;x86_64", + "system-images;android-36;google_apis;x86_64" + ], + "features": { + "profiler": false, + "python2": false, + "gcc14": false, + "emulator": false, + "marathon": false + } + } + }, + "api35-36-j17-23-ndk29-u24-gcc14": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "24.04", + "apt_profile": "ubuntu24_toolchain", + "apt_packages": [ + "sudo", + "openjdk-17-jdk", + "java-23-amazon-corretto-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq", + "net-tools", + "ccache", + "make", + "openssl", + "gcc-14", + "g++-14" + ], + "java_default": "java-23-amazon-corretto", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "build-tools;35.0.0", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-35", + "platforms;android-36", + "system-images;android-35;google_apis;x86_64", + "system-images;android-36;google_apis;x86_64", + "cmake;4.1.1", + "ndk;29.0.14033849" + ], + "features": { + "profiler": false, + "python2": true, + "gcc14": true, + "emulator": false, + "marathon": false + } + } + }, + "api34-35-j17-21-23-ndk26-emu-api35": { + "platforms": [ + "linux/amd64" + ], + "docker": { + "ubuntu": "23.04", + "apt_profile": "ubuntu23_old_releases", + "apt_packages": [ + "sudo", + "rsync", + "openjdk-17-jdk", + "java-21-amazon-corretto-jdk", + "java-23-amazon-corretto-jdk", + "curl", + "expect", + "git", + "git-lfs", + "libc6:i386", + "libncurses5:i386", + "libstdc++6:i386", + "zlib1g:i386", + "wget", + "unzip", + "vim", + "jq", + "net-tools", + "socat", + "libglu1", + "libpulse0", + "libx11-6", + "libxcb1", + "libxdamage1", + "libnss3", + "libxcomposite1", + "libxcursor1", + "libxi6", + "libxext6", + "libxfixes3", + "lib32stdc++6", + "ccache", + "g++", + "gcc", + "make", + "openssl" + ], + "java_default": "java-23-amazon-corretto", + "sdk_packages": [ + "tools", + "cmdline-tools;latest", + "emulator", + "build-tools;34.0.0", + "build-tools;35.0.0", + "build-tools;35.0.1", + "build-tools;36.0.0", + "platform-tools", + "platforms;android-34", + "platforms;android-35", + "system-images;android-35;google_apis;x86_64", + "cmake;3.18.1", + "cmake;3.22.1", + "ndk;26.2.11394342" + ], + "features": { + "profiler": false, + "python2": true, + "gcc14": false, + "emulator": true, + "marathon": true + }, + "marathon_version": "0.10.1" + } + } + } +}