From b8800ee30ee1a0bdd9619c4470fc268168059473 Mon Sep 17 00:00:00 2001 From: Jason Ernst Date: Wed, 20 May 2026 12:49:47 -0700 Subject: [PATCH 1/2] Skip Android SDK preview platforms in update automation The previous fix moved COMPILE_SDK to 37.0, but the build still failed: platforms;android-37.0 is a *preview* package. It is tagged channel-0 (stable) in the repository manifest yet carries a element, so sdkmanager prompts for the separate "Android SDK Preview" license at install time, which the unattended Docker build can't accept. Because the preview is tagged channel-0, `sdkmanager --list` shows it as if it were stable, so the detection step had no way to filter it out. - Dockerfile: COMPILE_SDK=37.0 -> 36.1 (latest *stable* platform) - check-sdk-updates: detect the platform from the repository manifest and skip any package that has a element (the reliable preview marker), instead of trusting the channel tag in `sdkmanager --list` Verified against Google's manifest: latest stable platform is android-36.1; android-37.0 is correctly excluded as a preview. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/check-sdk-updates.yml | 20 +++++++++++++++----- Dockerfile | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-sdk-updates.yml b/.github/workflows/check-sdk-updates.yml index 078a7dd..0b20de7 100644 --- a/.github/workflows/check-sdk-updates.yml +++ b/.github/workflows/check-sdk-updates.yml @@ -73,11 +73,21 @@ jobs: exit 0 fi - # Get latest available versions - # Platform packages now use MAJOR.MINOR versioning (e.g. android-36.1, - # android-37.0). Capture the optional minor component and sort by version - # so we don't truncate "37.0" to a non-existent "platforms;android-37". - LATEST_PLATFORM=$(echo "$PACKAGES" | grep 'platforms;android-' | grep -oP 'android-\K[0-9]+(\.[0-9]+)?' | sort -V | tail -1) + # Get latest available versions. + # + # Platforms must come from the repository manifest, not `sdkmanager --list`: + # preview platforms such as android-37.0 are tagged channel-0 (stable) but + # carry a element, so they appear in --list as if stable yet + # require the separate Android SDK Preview license at install time, which + # breaks the unattended Docker build. The presence of a element + # is the reliable preview marker, so we parse the manifest and skip any + # platform that has one. Versions are MAJOR.MINOR (e.g. 36.1, 37.0). + if ! wget -q "https://dl.google.com/android/repository/repository2-3.xml" -O /tmp/android-repo.xml; then + echo "Failed to download SDK repository manifest" + echo "updated=false" >> $GITHUB_OUTPUT + exit 0 + fi + LATEST_PLATFORM=$(perl -0777 -ne 'while(/(.*?)<\/remotePackage>/sg){my($v,$b)=($1,$2); next if $b=~//; print "$v\n"}' /tmp/android-repo.xml | sort -V | tail -1) LATEST_BUILD_TOOLS=$(echo "$PACKAGES" | grep 'build-tools;' | grep -oP 'build-tools;\K[0-9.]+' | sort -V | tail -1) LATEST_NDK=$(echo "$PACKAGES" | grep -P '^\s+ndk;' | grep -oP 'ndk;\K[0-9.]+' | sort -V | tail -1) diff --git a/Dockerfile b/Dockerfile index fd975a7..7fbf9ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ ARG VERSION=2.334.0-ubuntu-noble ARG JAVA_VERSION=21 -ARG COMPILE_SDK=37.0 +ARG COMPILE_SDK=36.1 ARG BUILD_TOOLS=37.0.0 ARG NDK_VERSION=30.0.14904198 ARG SDK_TOOLS=8512546_latest From 6e05dfc27f4993ee8d0c9297da517b9f229473f3 Mon Sep 17 00:00:00 2001 From: Jason Ernst Date: Wed, 20 May 2026 13:00:39 -0700 Subject: [PATCH 2/2] Address review: parse manifest with ElementTree instead of regex The previous platform-detection used a Perl regex that assumed `` had no other attributes (the manifest also emits ``) and matched the literal `` token (missing self-closing forms). Replace it with a real XML parser (Python stdlib ElementTree): iterate remotePackage elements, skip obsolete ones, match numeric platform paths, and treat the presence of any descendant as the preview marker. Namespace-agnostic via local-name matching. Verified against the live manifest: still yields 36.1, with android-37.0 excluded as a preview. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/check-sdk-updates.yml | 30 ++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-sdk-updates.yml b/.github/workflows/check-sdk-updates.yml index 0b20de7..7aa47f1 100644 --- a/.github/workflows/check-sdk-updates.yml +++ b/.github/workflows/check-sdk-updates.yml @@ -80,14 +80,38 @@ jobs: # carry a element, so they appear in --list as if stable yet # require the separate Android SDK Preview license at install time, which # breaks the unattended Docker build. The presence of a element - # is the reliable preview marker, so we parse the manifest and skip any - # platform that has one. Versions are MAJOR.MINOR (e.g. 36.1, 37.0). + # is the reliable preview marker, so we parse the manifest with a real XML + # parser and skip any platform that has one. Versions are MAJOR.MINOR + # (e.g. 36.1, 37.0). if ! wget -q "https://dl.google.com/android/repository/repository2-3.xml" -O /tmp/android-repo.xml; then echo "Failed to download SDK repository manifest" echo "updated=false" >> $GITHUB_OUTPUT exit 0 fi - LATEST_PLATFORM=$(perl -0777 -ne 'while(/(.*?)<\/remotePackage>/sg){my($v,$b)=($1,$2); next if $b=~//; print "$v\n"}' /tmp/android-repo.xml | sort -V | tail -1) + LATEST_PLATFORM=$(python3 - /tmp/android-repo.xml <<'PY' + import re, sys, xml.etree.ElementTree as ET + + def local(tag): # strip XML namespace, if any + return tag.rsplit('}', 1)[-1] + + root = ET.parse(sys.argv[1]).getroot() + best, best_key = '', None + for pkg in root.iter(): + if local(pkg.tag) != 'remotePackage' or pkg.get('obsolete') == 'true': + continue + m = re.fullmatch(r'platforms;android-(\d+(?:\.\d+)?)', pkg.get('path', '')) + if not m: + continue + # Skip previews: any descendant element marks a preview. + if any(local(e.tag) == 'codename' for e in pkg.iter()): + continue + ver = m.group(1) + key = tuple(int(x) for x in ver.split('.')) + if best_key is None or key > best_key: + best, best_key = ver, key + print(best) + PY + ) LATEST_BUILD_TOOLS=$(echo "$PACKAGES" | grep 'build-tools;' | grep -oP 'build-tools;\K[0-9.]+' | sort -V | tail -1) LATEST_NDK=$(echo "$PACKAGES" | grep -P '^\s+ndk;' | grep -oP 'ndk;\K[0-9.]+' | sort -V | tail -1)