From 55fb4f9a6904a6938131d8eabc0c6b0542c88dd4 Mon Sep 17 00:00:00 2001 From: Hal Eisen Date: Tue, 28 Jul 2026 15:55:41 -0700 Subject: [PATCH 1/5] ADFA-4907 | Standardize plugin toolchain: compileSdk/targetSdk 36, AGP 8.11.0, Kotlin 2.3.0, Gradle 8.14.3 Aligns all 25 example plugins with Code On The Go's on-device build toolchain (verified on device: CoGo ships only android-36, AGP 8.11.0, Gradle 8.14.3; does not pin Kotlin). Relevant because plugins are being built with CoGo itself (ADFA-4693). - compileSdk & targetSdk -> 36 (22 plugins; 3 template installers already 36) - AGP -> 8.11.0 (ai-assistant, ai-core from 8.13.2; client-time-tracker, compose-preview, layout-editor from 8.8.2 -- downgrades intentional, match CoGo) - Kotlin -> 2.3.0 (flutter-template, pebble, template-manager from 2.1.0) - Gradle wrapper -> 8.14.3 (ai-assistant, ai-core from 8.14.4; client-time-tracker, compose-preview, layout-editor from 8.10.2) - template-manager: migrate deprecated kotlinOptions.jvmTarget string DSL to compilerOptions { jvmTarget.set(JvmTarget.JVM_17) } (required by Kotlin 2.3.0) Java/jvmTarget already uniform at 17. 20/25 plugins build clean. 5 (ai-assistant, ai-core, code-suggestions-plugin, speech-to-text-plugin, vector-search-plugin) fail with pre-existing unresolved-reference errors (stale libs/plugin-api.jar, missing newer API symbols) -- verified failing at baseline before this change, out of scope here. --- Beepy/build.gradle.kts | 4 ++-- ai-assistant/build.gradle.kts | 4 ++-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- ai-assistant/settings.gradle.kts | 2 +- ai-core/build.gradle.kts | 4 ++-- ai-core/gradle/wrapper/gradle-wrapper.properties | 2 +- ai-core/settings.gradle.kts | 2 +- ai-literacy-course/build.gradle.kts | 4 ++-- apk-viewer/build.gradle.kts | 4 ++-- bookshelf/build.gradle.kts | 4 ++-- client-time-tracker/build.gradle.kts | 4 ++-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- client-time-tracker/settings.gradle.kts | 2 +- code-suggestions-plugin/build.gradle.kts | 4 ++-- compose-preview/build.gradle.kts | 4 ++-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- compose-preview/settings.gradle.kts | 2 +- cotg-ndk/build.gradle.kts | 4 ++-- flutter-template/settings.gradle.kts | 2 +- icons-repository/build.gradle.kts | 4 ++-- keystore-generator/build.gradle.kts | 4 ++-- layout-editor/build.gradle.kts | 4 ++-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- layout-editor/settings.gradle.kts | 2 +- markdown-preview/build.gradle.kts | 4 ++-- ndk-installer-plugin/build.gradle.kts | 4 ++-- .../settings.gradle.kts | 2 +- python-tools/build.gradle.kts | 4 ++-- rainbow-on-the-go/build.gradle.kts | 4 ++-- random-xkcd/build.gradle.kts | 4 ++-- sketch-to-ui-plugin/build.gradle.kts | 4 ++-- snippets/build.gradle.kts | 4 ++-- speech-to-text-plugin/build.gradle.kts | 4 ++-- template-manager/build.gradle.kts | 16 ++++++++-------- template-manager/settings.gradle.kts | 2 +- vector-search-plugin/build.gradle.kts | 4 ++-- 36 files changed, 65 insertions(+), 65 deletions(-) diff --git a/Beepy/build.gradle.kts b/Beepy/build.gradle.kts index 8460e150..81315a26 100644 --- a/Beepy/build.gradle.kts +++ b/Beepy/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "com.example.beepy" - compileSdk = 33 + compileSdk = 36 defaultConfig { applicationId = "com.example.beepy" minSdk = 28 - targetSdk = 33 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/ai-assistant/build.gradle.kts b/ai-assistant/build.gradle.kts index b376da7c..4b6b5c73 100644 --- a/ai-assistant/build.gradle.kts +++ b/ai-assistant/build.gradle.kts @@ -10,12 +10,12 @@ pluginBuilder { android { namespace = "com.itsaky.androidide.plugins.aiassistant" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.itsaky.androidide.plugins.aiassistant" minSdk = 33 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/ai-assistant/gradle/wrapper/gradle-wrapper.properties b/ai-assistant/gradle/wrapper/gradle-wrapper.properties index 692c2dc2..7c504ab6 100644 --- a/ai-assistant/gradle/wrapper/gradle-wrapper.properties +++ b/ai-assistant/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/ai-assistant/settings.gradle.kts b/ai-assistant/settings.gradle.kts index de2975f0..a529bf5f 100644 --- a/ai-assistant/settings.gradle.kts +++ b/ai-assistant/settings.gradle.kts @@ -18,7 +18,7 @@ buildscript { dependencies { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) - classpath("com.android.tools.build:gradle:8.13.2") + classpath("com.android.tools.build:gradle:8.11.0") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/ai-core/build.gradle.kts b/ai-core/build.gradle.kts index ff3a4772..663594a2 100644 --- a/ai-core/build.gradle.kts +++ b/ai-core/build.gradle.kts @@ -10,12 +10,12 @@ pluginBuilder { android { namespace = "com.itsaky.androidide.plugins.aicore" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.itsaky.androidide.plugins.aicore" minSdk = 33 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/ai-core/gradle/wrapper/gradle-wrapper.properties b/ai-core/gradle/wrapper/gradle-wrapper.properties index 692c2dc2..7c504ab6 100644 --- a/ai-core/gradle/wrapper/gradle-wrapper.properties +++ b/ai-core/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/ai-core/settings.gradle.kts b/ai-core/settings.gradle.kts index 814b83f3..e6de23ea 100644 --- a/ai-core/settings.gradle.kts +++ b/ai-core/settings.gradle.kts @@ -18,7 +18,7 @@ buildscript { dependencies { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) - classpath("com.android.tools.build:gradle:8.13.2") + classpath("com.android.tools.build:gradle:8.11.0") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/ai-literacy-course/build.gradle.kts b/ai-literacy-course/build.gradle.kts index 78a2fa9c..06342e17 100644 --- a/ai-literacy-course/build.gradle.kts +++ b/ai-literacy-course/build.gradle.kts @@ -19,12 +19,12 @@ pluginBuilder { android { namespace = "org.appdevforall.ailiteracycourse" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.ailiteracycourse" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/apk-viewer/build.gradle.kts b/apk-viewer/build.gradle.kts index 765f3bd1..460265e0 100644 --- a/apk-viewer/build.gradle.kts +++ b/apk-viewer/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "com.example.sampleplugin" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.example.sampleplugin" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/bookshelf/build.gradle.kts b/bookshelf/build.gradle.kts index 339ac3cf..c0d11528 100644 --- a/bookshelf/build.gradle.kts +++ b/bookshelf/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "org.appdevforall.bookshelfplugin" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.bookshelfplugin" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/client-time-tracker/build.gradle.kts b/client-time-tracker/build.gradle.kts index bb8c2950..341278f4 100644 --- a/client-time-tracker/build.gradle.kts +++ b/client-time-tracker/build.gradle.kts @@ -14,12 +14,12 @@ pluginBuilder { android { namespace = "com.appdevforall.contractor.plugin" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.appdevforall.contractor.plugin" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/client-time-tracker/gradle/wrapper/gradle-wrapper.properties b/client-time-tracker/gradle/wrapper/gradle-wrapper.properties index df97d72b..d4081da4 100644 --- a/client-time-tracker/gradle/wrapper/gradle-wrapper.properties +++ b/client-time-tracker/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/client-time-tracker/settings.gradle.kts b/client-time-tracker/settings.gradle.kts index 9862b68e..a5210d81 100644 --- a/client-time-tracker/settings.gradle.kts +++ b/client-time-tracker/settings.gradle.kts @@ -15,7 +15,7 @@ buildscript { dependencies { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) - classpath("com.android.tools.build:gradle:8.8.2") + classpath("com.android.tools.build:gradle:8.11.0") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/code-suggestions-plugin/build.gradle.kts b/code-suggestions-plugin/build.gradle.kts index af56914f..5ffe0761 100644 --- a/code-suggestions-plugin/build.gradle.kts +++ b/code-suggestions-plugin/build.gradle.kts @@ -10,12 +10,12 @@ pluginBuilder { android { namespace = "com.itsaky.androidide.plugins.codesuggestions" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.itsaky.androidide.plugins.codesuggestions" minSdk = 33 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/compose-preview/build.gradle.kts b/compose-preview/build.gradle.kts index 12086457..6a7fb69e 100644 --- a/compose-preview/build.gradle.kts +++ b/compose-preview/build.gradle.kts @@ -11,12 +11,12 @@ pluginBuilder { android { namespace = "org.appdevforall.composepreview" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.composepreview" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" diff --git a/compose-preview/gradle/wrapper/gradle-wrapper.properties b/compose-preview/gradle/wrapper/gradle-wrapper.properties index df97d72b..d4081da4 100644 --- a/compose-preview/gradle/wrapper/gradle-wrapper.properties +++ b/compose-preview/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/compose-preview/settings.gradle.kts b/compose-preview/settings.gradle.kts index 490288c7..1d1a6d2e 100644 --- a/compose-preview/settings.gradle.kts +++ b/compose-preview/settings.gradle.kts @@ -15,7 +15,7 @@ buildscript { dependencies { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) - classpath("com.android.tools.build:gradle:8.8.2") + classpath("com.android.tools.build:gradle:8.11.0") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") classpath("org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.3.0") } diff --git a/cotg-ndk/build.gradle.kts b/cotg-ndk/build.gradle.kts index 5b0ad299..4a9134ad 100644 --- a/cotg-ndk/build.gradle.kts +++ b/cotg-ndk/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "com.cotg.cotgndk" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.cotg.cotgndk" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 6 versionName = "6.0.0" } diff --git a/flutter-template/settings.gradle.kts b/flutter-template/settings.gradle.kts index 0342a1b2..5de2bb66 100644 --- a/flutter-template/settings.gradle.kts +++ b/flutter-template/settings.gradle.kts @@ -15,7 +15,7 @@ buildscript { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) classpath("com.android.tools.build:gradle:8.11.0") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/icons-repository/build.gradle.kts b/icons-repository/build.gradle.kts index 82840a5b..1f594550 100644 --- a/icons-repository/build.gradle.kts +++ b/icons-repository/build.gradle.kts @@ -12,11 +12,11 @@ pluginBuilder { android { namespace = "dev.omar.plugin.iconsrepo" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "dev.omar.plugin.iconsrepo" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/keystore-generator/build.gradle.kts b/keystore-generator/build.gradle.kts index cd5c4349..45d07e86 100644 --- a/keystore-generator/build.gradle.kts +++ b/keystore-generator/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "com.appdevforall.keygen.plugin" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.appdevforall.keygen.plugin" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/layout-editor/build.gradle.kts b/layout-editor/build.gradle.kts index 98afaba1..7eb67da7 100644 --- a/layout-editor/build.gradle.kts +++ b/layout-editor/build.gradle.kts @@ -10,12 +10,12 @@ pluginBuilder { android { namespace = "org.appdevforall.codeonthego.layouteditor" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.codeonthego.layouteditor" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/layout-editor/gradle/wrapper/gradle-wrapper.properties b/layout-editor/gradle/wrapper/gradle-wrapper.properties index df97d72b..d4081da4 100644 --- a/layout-editor/gradle/wrapper/gradle-wrapper.properties +++ b/layout-editor/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/layout-editor/settings.gradle.kts b/layout-editor/settings.gradle.kts index 8b717726..087f3668 100644 --- a/layout-editor/settings.gradle.kts +++ b/layout-editor/settings.gradle.kts @@ -15,7 +15,7 @@ buildscript { dependencies { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) - classpath("com.android.tools.build:gradle:8.8.2") + classpath("com.android.tools.build:gradle:8.11.0") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/markdown-preview/build.gradle.kts b/markdown-preview/build.gradle.kts index 5be08435..4e77ce0e 100644 --- a/markdown-preview/build.gradle.kts +++ b/markdown-preview/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "com.codeonthego.markdownpreviewer" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.codeonthego.markdownpreviewer" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/ndk-installer-plugin/build.gradle.kts b/ndk-installer-plugin/build.gradle.kts index 6d392a53..4715448f 100644 --- a/ndk-installer-plugin/build.gradle.kts +++ b/ndk-installer-plugin/build.gradle.kts @@ -17,12 +17,12 @@ pluginBuilder { android { namespace = "org.appdevforall.ndkinstaller" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.ndkinstaller" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/pebble-custom-function-template-installer/settings.gradle.kts b/pebble-custom-function-template-installer/settings.gradle.kts index 07f43eaa..380415e1 100644 --- a/pebble-custom-function-template-installer/settings.gradle.kts +++ b/pebble-custom-function-template-installer/settings.gradle.kts @@ -15,7 +15,7 @@ buildscript { classpath(files("libs/plugin-api.jar")) classpath(files("libs/gradle-plugin.jar")) classpath("com.android.tools.build:gradle:8.11.0") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/python-tools/build.gradle.kts b/python-tools/build.gradle.kts index e5b21ba9..6948f123 100644 --- a/python-tools/build.gradle.kts +++ b/python-tools/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "com.appdevforall.python.plugin" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.appdevforall.python.plugin" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/rainbow-on-the-go/build.gradle.kts b/rainbow-on-the-go/build.gradle.kts index 905b9d62..4f24246b 100644 --- a/rainbow-on-the-go/build.gradle.kts +++ b/rainbow-on-the-go/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "org.appdevforall.rainbowonthego" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.rainbowonthego" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/random-xkcd/build.gradle.kts b/random-xkcd/build.gradle.kts index 12077797..e1447d9a 100644 --- a/random-xkcd/build.gradle.kts +++ b/random-xkcd/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "org.appdevforall.randomxkcd" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.randomxkcd" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/sketch-to-ui-plugin/build.gradle.kts b/sketch-to-ui-plugin/build.gradle.kts index d1e999a1..5ba26240 100644 --- a/sketch-to-ui-plugin/build.gradle.kts +++ b/sketch-to-ui-plugin/build.gradle.kts @@ -12,7 +12,7 @@ pluginBuilder { android { namespace = "com.appdevforall.sketchtoui.plugin" - compileSdk = 35 + compileSdk = 36 sourceSets { getByName("main") { @@ -34,7 +34,7 @@ android { defaultConfig { applicationId = "com.appdevforall.sketchtoui.plugin" minSdk = 28 - targetSdk = 35 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/snippets/build.gradle.kts b/snippets/build.gradle.kts index 31834263..804269fa 100644 --- a/snippets/build.gradle.kts +++ b/snippets/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "com.codeonthego.snippets" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.codeonthego.snippets" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/speech-to-text-plugin/build.gradle.kts b/speech-to-text-plugin/build.gradle.kts index 6f56f5f0..5f58595a 100644 --- a/speech-to-text-plugin/build.gradle.kts +++ b/speech-to-text-plugin/build.gradle.kts @@ -10,12 +10,12 @@ pluginBuilder { android { namespace = "com.itsaky.androidide.plugins.stt" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.itsaky.androidide.plugins.stt" minSdk = 33 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/template-manager/build.gradle.kts b/template-manager/build.gradle.kts index 4b0b2905..8e06a10d 100644 --- a/template-manager/build.gradle.kts +++ b/template-manager/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { id("com.android.application") id("org.jetbrains.kotlin.android") @@ -33,10 +35,6 @@ android { targetCompatibility = JavaVersion.VERSION_17 } - kotlinOptions { - jvmTarget = "17" - } - buildFeatures { viewBinding = true } @@ -55,6 +53,12 @@ android { } } +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } +} + dependencies { compileOnly(files("../libs/plugin-api.jar")) @@ -88,7 +92,3 @@ tasks.matching { }.configureEach { enabled = false } - -tasks.withType().configureEach { - kotlinOptions.jvmTarget = "17" -} diff --git a/template-manager/settings.gradle.kts b/template-manager/settings.gradle.kts index 201a950e..365d7cd1 100644 --- a/template-manager/settings.gradle.kts +++ b/template-manager/settings.gradle.kts @@ -15,7 +15,7 @@ buildscript { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) classpath("com.android.tools.build:gradle:8.11.0") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/vector-search-plugin/build.gradle.kts b/vector-search-plugin/build.gradle.kts index 492c58b4..6a093b1b 100644 --- a/vector-search-plugin/build.gradle.kts +++ b/vector-search-plugin/build.gradle.kts @@ -10,12 +10,12 @@ pluginBuilder { android { namespace = "com.itsaky.androidide.plugins.vectorsearch" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "com.itsaky.androidide.plugins.vectorsearch" minSdk = 33 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } From ce0bd8d3cf98ca318b934c3411ab7b365e6f00ae Mon Sep 17 00:00:00 2001 From: Hal Eisen Date: Wed, 5 Aug 2026 23:41:31 -0700 Subject: [PATCH 2/5] ADFA-4907 | Extend toolchain standardization to 3 missed plugins Two plugins landed on main after this branch was cut, so they were never standardized: - project-to-template (#56): compileSdk/targetSdk 34 -> 36 - get-ai-models (#55): Kotlin 2.1.0 -> 2.3.0 Both get-ai-models and template-manager pin Kotlin twice: the kotlin-gradle-plugin classpath in settings.gradle.kts, and `kotlin` in gradle/libs.versions.toml, which drives libs.kotlin.stdlib. The catalog comment states the two must match, so both were bumped. That surfaced a defect in this branch: it had already bumped template-manager's classpath to 2.3.0 but left its catalog at 2.1.0, so the compiler and stdlib disagreed. Fixed here. Verified: all 27 plugins now report compileSdk/targetSdk 36, AGP 8.11.0, Kotlin 2.3.0, with no catalog left at an older pin. All four affected plugins build assemblePlugin successfully; kotlin-stdlib resolves to 2.3.0 in get-ai-models and template-manager, and the packaged manifests of project-to-template and get-ai-models report targetSdkVersion=36. --- get-ai-models/gradle/libs.versions.toml | 2 +- get-ai-models/settings.gradle.kts | 2 +- project-to-template/build.gradle.kts | 4 ++-- template-manager/gradle/libs.versions.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/get-ai-models/gradle/libs.versions.toml b/get-ai-models/gradle/libs.versions.toml index 03f0ddab..8d7ad94e 100644 --- a/get-ai-models/gradle/libs.versions.toml +++ b/get-ai-models/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Must match the kotlin-gradle-plugin classpath pinned in settings.gradle.kts. -kotlin = "2.1.0" +kotlin = "2.3.0" coreKtx = "1.13.1" appcompat = "1.6.1" material = "1.12.0" diff --git a/get-ai-models/settings.gradle.kts b/get-ai-models/settings.gradle.kts index 4a534b5d..f4066634 100644 --- a/get-ai-models/settings.gradle.kts +++ b/get-ai-models/settings.gradle.kts @@ -15,7 +15,7 @@ buildscript { classpath(files("../libs/plugin-api.jar")) classpath(files("../libs/gradle-plugin.jar")) classpath("com.android.tools.build:gradle:8.11.0") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0") } } diff --git a/project-to-template/build.gradle.kts b/project-to-template/build.gradle.kts index 5a950ec4..11e7d739 100644 --- a/project-to-template/build.gradle.kts +++ b/project-to-template/build.gradle.kts @@ -12,12 +12,12 @@ pluginBuilder { android { namespace = "org.appdevforall.projecttotemplate" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "org.appdevforall.projecttotemplate" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 1 versionName = "1.0.0" } diff --git a/template-manager/gradle/libs.versions.toml b/template-manager/gradle/libs.versions.toml index 57361eee..7256ccea 100644 --- a/template-manager/gradle/libs.versions.toml +++ b/template-manager/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Must match the kotlin-gradle-plugin classpath pinned in settings.gradle.kts. -kotlin = "2.1.0" +kotlin = "2.3.0" coreKtx = "1.13.1" appcompat = "1.6.1" material = "1.12.0" From e4da077d1aa26866f057293b7133fb4bc2484930 Mon Sep 17 00:00:00 2001 From: Hal Eisen Date: Fri, 7 Aug 2026 13:24:28 -0700 Subject: [PATCH 3/5] ADFA-4907 | Enforce the standard toolchain in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds scripts/check-toolchain.sh and a pull_request-triggered workflow that fails the build when any Gradle module drifts off the ADFA-4907 standard (compileSdk/targetSdk 36, AGP 8.11.0, Kotlin 2.3.0, Gradle 8.14.3-bin, Java 17). Until now nothing enforced this. Both existing workflows are workflow_dispatch-only, so a PR could move any of these values with zero CI signal — which is how origin/main still carries compileSdk 33/34/35, AGP 8.8.2/8.13.2 and Gradle 8.10.2. The check is pure text inspection (no JDK, no Gradle, no network), so it runs in seconds and is cheap to require. It walks every build.gradle.kts, including subprojects. The earlier sweep enumerated only top-level plugin folders, which is why ai-core/llama-impl kept compileSdk = 34 through a dedicated standardization pass. Files under src/main/assets/ are excluded: those are project templates that Code On The Go stamps out for the user's own app, not our builds. minSdk is deliberately not checked — it legitimately varies (21 template installers, 26 most, 28 Beepy/sketch-to-ui, 33 the AI plugins). Also fixes the nine violations the check found, so it lands green: * kotlin-stdlib pinned behind the Kotlin plugin -> 2.3.0 (flutter-template, bookshelf, ndk-installer-plugin, cotg-ndk, pebble) * ai-core/llama-impl compileSdk 34 -> 36 * ai-assistant + ai-core wrapper -all.zip -> -bin.zip * ai-core catalog agp "8.13.2" -> "8.11.0" (contradicted settings.gradle.kts) --- .github/workflows/check-toolchain.yml | 46 ++++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- ai-core/gradle/libs.versions.toml | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- ai-core/llama-impl/build.gradle.kts | 2 +- bookshelf/build.gradle.kts | 2 +- cotg-ndk/build.gradle.kts | 2 +- flutter-template/build.gradle.kts | 2 +- ndk-installer-plugin/build.gradle.kts | 2 +- .../build.gradle.kts | 2 +- scripts/check-toolchain.sh | 236 ++++++++++++++++++ 11 files changed, 291 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/check-toolchain.yml create mode 100755 scripts/check-toolchain.sh diff --git a/.github/workflows/check-toolchain.yml b/.github/workflows/check-toolchain.yml new file mode 100644 index 00000000..86c1fbc7 --- /dev/null +++ b/.github/workflows/check-toolchain.yml @@ -0,0 +1,46 @@ +name: Check toolchain + +# Fails a pull request that drifts off the standard plugin toolchain +# (compileSdk/targetSdk 36, AGP 8.11.0, Kotlin 2.3.0, Gradle 8.14.3-bin, +# Java 17) — see ADFA-4907. +# +# This is the only workflow here that runs automatically on pull requests. +# "Build plugin artifacts" and "Update libs from CodeOnTheGo" are both +# workflow_dispatch-only, which is why toolchain drift previously reached +# main with no CI signal at all. +# +# It is pure text inspection — no JDK, no Gradle, no network — so it costs a +# few seconds and is safe to make a required check. + +on: + pull_request: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +jobs: + check-toolchain: + name: Toolchain versions + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Check toolchain versions + run: ./scripts/check-toolchain.sh + + - name: Report declared versions + # Runs even when the check above fails, so the run summary shows what + # every module actually declares next to the failure list. + if: always() + run: | + { + echo '### Declared toolchain versions' + echo + echo '```' + ./scripts/check-toolchain.sh --list + echo '```' + } >> "$GITHUB_STEP_SUMMARY" diff --git a/ai-assistant/gradle/wrapper/gradle-wrapper.properties b/ai-assistant/gradle/wrapper/gradle-wrapper.properties index 7c504ab6..42f0071e 100644 --- a/ai-assistant/gradle/wrapper/gradle-wrapper.properties +++ b/ai-assistant/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/ai-core/gradle/libs.versions.toml b/ai-core/gradle/libs.versions.toml index 802507a0..d72a2611 100644 --- a/ai-core/gradle/libs.versions.toml +++ b/ai-core/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] activityKtx = "1.8.2" -agp = "8.13.2" +agp = "8.11.0" agp-tooling = "8.11.0" androidx-sqlite = "2.6.2" appcompatVersion = "1.7.1" diff --git a/ai-core/gradle/wrapper/gradle-wrapper.properties b/ai-core/gradle/wrapper/gradle-wrapper.properties index 7c504ab6..42f0071e 100644 --- a/ai-core/gradle/wrapper/gradle-wrapper.properties +++ b/ai-core/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/ai-core/llama-impl/build.gradle.kts b/ai-core/llama-impl/build.gradle.kts index b940f4ff..66cb03b0 100644 --- a/ai-core/llama-impl/build.gradle.kts +++ b/ai-core/llama-impl/build.gradle.kts @@ -11,7 +11,7 @@ kotlin { android { namespace = "android.llama.cpp" - compileSdk = 34 + compileSdk = 36 defaultConfig { minSdk = 33 diff --git a/bookshelf/build.gradle.kts b/bookshelf/build.gradle.kts index c0d11528..cdb607ae 100644 --- a/bookshelf/build.gradle.kts +++ b/bookshelf/build.gradle.kts @@ -46,7 +46,7 @@ dependencies { compileOnly(files("../libs/gradle-plugin.jar")) compileOnly(files("../libs/plugin-api.jar")) - implementation("org.jetbrains.kotlin:kotlin-stdlib:2.1.21") + implementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.0") } tasks.matching { diff --git a/cotg-ndk/build.gradle.kts b/cotg-ndk/build.gradle.kts index 4a9134ad..6a6577ad 100644 --- a/cotg-ndk/build.gradle.kts +++ b/cotg-ndk/build.gradle.kts @@ -63,7 +63,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.10.0") implementation("androidx.fragment:fragment-ktx:1.8.8") - implementation("org.jetbrains.kotlin:kotlin-stdlib:2.1.21") + implementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0") } diff --git a/flutter-template/build.gradle.kts b/flutter-template/build.gradle.kts index a2a2692a..dd017486 100644 --- a/flutter-template/build.gradle.kts +++ b/flutter-template/build.gradle.kts @@ -50,7 +50,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.10.0") - implementation("org.jetbrains.kotlin:kotlin-stdlib:2.1.0") + implementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.0") } tasks.withType().configureEach { diff --git a/ndk-installer-plugin/build.gradle.kts b/ndk-installer-plugin/build.gradle.kts index 4715448f..7926eb1e 100644 --- a/ndk-installer-plugin/build.gradle.kts +++ b/ndk-installer-plugin/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { compileOnly(files("../libs/plugin-api.jar")) - implementation("org.jetbrains.kotlin:kotlin-stdlib:2.1.21") + implementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") } diff --git a/pebble-custom-function-template-installer/build.gradle.kts b/pebble-custom-function-template-installer/build.gradle.kts index d9d767b4..52ed2402 100644 --- a/pebble-custom-function-template-installer/build.gradle.kts +++ b/pebble-custom-function-template-installer/build.gradle.kts @@ -52,7 +52,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.10.0") implementation("androidx.fragment:fragment-ktx:1.8.8") - implementation("org.jetbrains.kotlin:kotlin-stdlib:2.1.0") + implementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.0") } tasks.withType().configureEach { diff --git a/scripts/check-toolchain.sh b/scripts/check-toolchain.sh new file mode 100755 index 00000000..4717d60d --- /dev/null +++ b/scripts/check-toolchain.sh @@ -0,0 +1,236 @@ +#!/usr/bin/env bash +# +# check-toolchain.sh (ADFA-4907) +# +# Assert that every Gradle module in this repo declares the one standard +# toolchain. Pure text inspection -- no Gradle run, no JDK, no network, so it +# is fast enough to gate every pull request. +# +# WHY THESE NUMBERS: they are not "latest". They track the toolchain that Code +# On The Go itself ships on-device, because these plugins are meant to be built +# *with* Code On The Go (ADFA-4693). Verified against CoGo build C-d-0727-1613: +# +# * android-36 is the ONLY installed platform in CoGo's bundled SDK +# * AGP 8.11.0 is the ONLY AGP in CoGo's Gradle caches +# * Gradle 8.14.3 is CoGo's Gradle +# * CoGo pins no Kotlin version (it fetches per project); 2.3.0 is our standard +# * Java 17 was already uniform across every plugin +# +# Bumping any value below therefore means re-verifying against a real CoGo +# build first -- not just picking something newer. +# +# Usage: +# scripts/check-toolchain.sh # check; exit 1 and print a report on drift +# scripts/check-toolchain.sh --list # print what every module declares, exit 0 +# +set -euo pipefail + +# --------------------------------------------------------------------------- +# The standard +# --------------------------------------------------------------------------- +EXPECTED_COMPILE_SDK="36" +EXPECTED_TARGET_SDK="36" +EXPECTED_AGP="8.11.0" +EXPECTED_KOTLIN="2.3.0" +EXPECTED_GRADLE="8.14.3" +EXPECTED_GRADLE_DIST="bin" # gradle--bin.zip, not -all.zip +EXPECTED_JAVA="VERSION_17" +EXPECTED_JVM_TARGET="JVM_17" + +# minSdk is deliberately NOT checked. It legitimately varies by what a plugin +# needs (21 for the template installers, 26 for most, 28 for Beepy and +# sketch-to-ui, 33 for the AI plugins which rely on API-33 runtime behavior). +# Do not "standardize" it here. + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$REPO_ROOT" + +LIST_ONLY=0 +[ "${1:-}" = "--list" ] && LIST_ONLY=1 + +failures=() +fail() { failures+=("$1"); } + +# Files under src/main/assets/ are shipped project *templates* -- skeletons that +# Code On The Go stamps out for the user's own app. They are not our builds and +# must not be held to our toolchain. +find_gradle() { + find . -name "$1" \ + -not -path './.git/*' \ + -not -path '*/build/*' \ + -not -path '*/src/main/assets/*' \ + -print0 +} + +# first_value +# Prints ":" for the first matching line, or nothing. +# +# Uses bash's own =~ rather than grep|sed: interpolating these regexes into a +# sed expression breaks on BSD/macOS sed (the escaped "\:" in distributionUrl) +# and on greedy ".*" before the capture group. BASH_REMATCH has neither problem. +# +# Always succeeds: "key absent" is a normal answer, not an error, and under +# `set -e` a bare failing grep here would abort the whole script silently. +first_value() { + local file="$1" re="$2" ln=0 line + while IFS= read -r line || [ -n "$line" ]; do + ln=$((ln + 1)) + if [[ $line =~ $re ]]; then + printf '%s:%s\n' "$ln" "${BASH_REMATCH[1]}" + return 0 + fi + done < "$file" + return 0 +} + +# --------------------------------------------------------------------------- +# build.gradle.kts -- SDK levels, Java level, Kotlin jvmTarget, stdlib pin +# --------------------------------------------------------------------------- +while IFS= read -r -d '' f; do + mod="${f#./}"; mod="${mod%/build.gradle.kts}" + + # --- compileSdk (every Android module has one) --- + hit="$(first_value "$f" '^[[:space:]]*compileSdk[[:space:]]*=[[:space:]]*([0-9]+)')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$LIST_ONLY" = 1 ] && echo "$mod compileSdk=$val" + [ "$val" != "$EXPECTED_COMPILE_SDK" ] && \ + fail "$f:$ln compileSdk = $val (expected $EXPECTED_COMPILE_SDK)" + fi + + # --- targetSdk (application modules only; library modules have none) --- + hit="$(first_value "$f" '^[[:space:]]*targetSdk[[:space:]]*=[[:space:]]*([0-9]+)')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$LIST_ONLY" = 1 ] && echo "$mod targetSdk=$val" + [ "$val" != "$EXPECTED_TARGET_SDK" ] && \ + fail "$f:$ln targetSdk = $val (expected $EXPECTED_TARGET_SDK)" + elif grep -q 'com\.android\.application' "$f"; then + fail "$f declares com.android.application but no targetSdk" + fi + + # --- Java source/target compatibility --- + while IFS= read -r bad; do + fail "$f:${bad%%:*} ${bad#*:} (expected JavaVersion.$EXPECTED_JAVA)" + done < <(grep -nE '^[[:space:]]*(source|target)Compatibility[[:space:]]*=' "$f" \ + | grep -v "JavaVersion\.$EXPECTED_JAVA" | sed 's/[[:space:]]*$//') + + # --- Kotlin jvmTarget --- + # Kotlin 2.3.0 made the old string DSL (kotlinOptions.jvmTarget = "17") a hard + # error. That exact pattern broke template-manager during the ADFA-4907 bump, + # so reject it outright rather than waiting for a build to fail. + while IFS= read -r bad; do + fail "$f:${bad%%:*} deprecated string DSL '${bad#*:}' -- Kotlin ${EXPECTED_KOTLIN} rejects it; use kotlin { compilerOptions { jvmTarget.set(JvmTarget.$EXPECTED_JVM_TARGET) } }" + done < <(grep -nE 'jvmTarget[[:space:]]*=[[:space:]]*"' "$f" | sed 's/[[:space:]]*$//') + + if grep -qE 'org\.jetbrains\.kotlin|kotlin\("' "$f"; then + if ! grep -q "JvmTarget\.$EXPECTED_JVM_TARGET" "$f"; then + fail "$f applies a Kotlin plugin but never sets jvmTarget to JvmTarget.$EXPECTED_JVM_TARGET" + fi + fi + + # --- explicit kotlin-stdlib pin must match the Kotlin plugin --- + # An explicit pin older than the Kotlin Gradle plugin is the "version skew" + # the plugin-review rubric flags. Most modules correctly omit the line and + # inherit the stdlib from the plugin; if you do pin it, pin it to the standard. + while IFS= read -r bad; do + fail "$f:${bad%%:*} kotlin-stdlib pinned to ${bad#*:} (expected $EXPECTED_KOTLIN, or drop the line and inherit it)" + done < <(grep -nE 'kotlin-stdlib:[0-9]' "$f" \ + | sed -E "s/^([0-9]+):.*kotlin-stdlib:([0-9][^\"']*).*/\1:\2/" \ + | grep -v ":$EXPECTED_KOTLIN\$") +done < <(find_gradle build.gradle.kts) + +# --------------------------------------------------------------------------- +# settings.gradle.kts -- AGP and Kotlin Gradle plugin on the buildscript classpath +# --------------------------------------------------------------------------- +while IFS= read -r -d '' f; do + mod="${f#./}"; mod="${mod%/settings.gradle.kts}" + + hit="$(first_value "$f" 'com\.android\.tools\.build:gradle:([0-9][^"]*)')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$LIST_ONLY" = 1 ] && echo "$mod agp=$val" + [ "$val" != "$EXPECTED_AGP" ] && \ + fail "$f:$ln AGP $val (expected $EXPECTED_AGP -- the only AGP in CoGo's caches)" + fi + + hit="$(first_value "$f" 'kotlin-gradle-plugin:([0-9][^"]*)')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$LIST_ONLY" = 1 ] && echo "$mod kotlin=$val" + [ "$val" != "$EXPECTED_KOTLIN" ] && \ + fail "$f:$ln Kotlin $val (expected $EXPECTED_KOTLIN)" + fi + + hit="$(first_value "$f" 'compose-compiler-gradle-plugin:([0-9][^"]*)')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$val" != "$EXPECTED_KOTLIN" ] && \ + fail "$f:$ln Compose compiler plugin $val (must match Kotlin $EXPECTED_KOTLIN)" + fi +done < <(find_gradle settings.gradle.kts) + +# --------------------------------------------------------------------------- +# gradle-wrapper.properties -- Gradle version AND distribution flavor +# --------------------------------------------------------------------------- +while IFS= read -r -d '' f; do + hit="$(first_value "$f" 'distributions/gradle-([0-9][^-]*)-')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$LIST_ONLY" = 1 ] && echo "${f#./} gradle=$val" + [ "$val" != "$EXPECTED_GRADLE" ] && \ + fail "$f:$ln Gradle $val (expected $EXPECTED_GRADLE -- CoGo's Gradle)" + fi + hit="$(first_value "$f" 'gradle-[0-9][^-]*-(bin|all)\.zip')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$val" != "$EXPECTED_GRADLE_DIST" ] && \ + fail "$f:$ln gradle-...-$val.zip (expected -$EXPECTED_GRADLE_DIST.zip, matching the root wrapper)" + fi +done < <(find_gradle gradle-wrapper.properties) + +# --------------------------------------------------------------------------- +# libs.versions.toml -- catalogs must agree with the classpath they document +# --------------------------------------------------------------------------- +# Only three modules use a catalog, and two of them carry a hand-written +# "Must match the kotlin-gradle-plugin classpath pinned in settings.gradle.kts" +# comment. This automates that comment. A stale entry here is not inert: it is +# the number the next person greps for. +while IFS= read -r -d '' f; do + hit="$(first_value "$f" '^agp[[:space:]]*=[[:space:]]*"([^"]+)"')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$val" != "$EXPECTED_AGP" ] && \ + fail "$f:$ln catalog agp = \"$val\" (expected $EXPECTED_AGP; disagrees with settings.gradle.kts)" + fi + hit="$(first_value "$f" '^kotlin[[:space:]]*=[[:space:]]*"([^"]+)"')" + if [ -n "$hit" ]; then + ln="${hit%%:*}"; val="${hit#*:}" + [ "$val" != "$EXPECTED_KOTLIN" ] && \ + fail "$f:$ln catalog kotlin = \"$val\" (expected $EXPECTED_KOTLIN; disagrees with settings.gradle.kts)" + fi +done < <(find_gradle libs.versions.toml) + +# --------------------------------------------------------------------------- +# Report +# --------------------------------------------------------------------------- +[ "$LIST_ONLY" = 1 ] && exit 0 + +if [ ${#failures[@]} -eq 0 ]; then + echo "toolchain OK - compileSdk/targetSdk $EXPECTED_COMPILE_SDK, AGP $EXPECTED_AGP, Kotlin $EXPECTED_KOTLIN, Gradle $EXPECTED_GRADLE-$EXPECTED_GRADLE_DIST, Java 17" + exit 0 +fi + +{ + echo + echo "Toolchain drift: ${#failures[@]} problem(s)." + echo + printf ' %s\n' "${failures[@]}" + echo + echo "The standard is defined at the top of scripts/check-toolchain.sh and tracks" + echo "Code On The Go's own on-device toolchain (ADFA-4907). Fix the files above, or" + echo "-- if Code On The Go itself has moved -- update the script's constants and say" + echo "which CoGo build you verified against." + echo +} >&2 +exit 1 From 306840bf773e714e7e95886fd9d8777fe7666999 Mon Sep 17 00:00:00 2001 From: Hal Eisen Date: Fri, 7 Aug 2026 13:36:45 -0700 Subject: [PATCH 4/5] ADFA-4907 | Simplify check-toolchain.sh Collapses the nine copy-pasted "extract, compare, report" blocks into two helpers (check_value for first-match keys, check_every for all-match keys), plus small file_matches/reject/module_of helpers. That duplication had already caused a real defect: four of the nine copies omitted the --list echo, so --list silently under-reported the compose-compiler pin, the wrapper bin/all flavor, and both catalog entries. Recording the value is now part of the helper, so it cannot be forgotten. --list goes from 5 fact types / 134 lines to 9 / 164, sorted by module instead of grouped by internal scan order. Also: * One matching idiom. The header claimed grep|sed was avoided for BSD sed portability, then the kotlin-stdlib check used exactly that. Everything is bash =~ now, so the claim is true and no subprocesses are spawned. * One find traversal with a case dispatch instead of four full walks of the 12.8k-entry tree. Runtime 1.02s -> 0.38s. * Documents why discovery is deliberately broader than plugin_dirs() in .githooks/pre-push, so a future "DRY win" does not silently drop ai-core/llama-api and llama-impl from coverage. * Narrows the --list usage text, which overstated what it prints. * Workflow header no longer restates the version numbers (third copy). Deliberately NOT changed: no declarative rules table (four of the checks have genuinely different shapes and a table would gut the failure-message hints), and the standard stays a set of literal constants rather than being derived from the root wrapper -- deriving it would make a wrong root wrapper undetectable. --- .github/workflows/check-toolchain.yml | 4 +- scripts/check-toolchain.sh | 306 ++++++++++++++------------ 2 files changed, 164 insertions(+), 146 deletions(-) diff --git a/.github/workflows/check-toolchain.yml b/.github/workflows/check-toolchain.yml index 86c1fbc7..c8d4b396 100644 --- a/.github/workflows/check-toolchain.yml +++ b/.github/workflows/check-toolchain.yml @@ -1,8 +1,8 @@ name: Check toolchain # Fails a pull request that drifts off the standard plugin toolchain -# (compileSdk/targetSdk 36, AGP 8.11.0, Kotlin 2.3.0, Gradle 8.14.3-bin, -# Java 17) — see ADFA-4907. +# (ADFA-4907). The standard itself lives in scripts/check-toolchain.sh — it is +# deliberately not restated here, so there is only one copy of the numbers. # # This is the only workflow here that runs automatically on pull requests. # "Build plugin artifacts" and "Update libs from CodeOnTheGo" are both diff --git a/scripts/check-toolchain.sh b/scripts/check-toolchain.sh index 4717d60d..fe9b61fa 100755 --- a/scripts/check-toolchain.sh +++ b/scripts/check-toolchain.sh @@ -19,9 +19,18 @@ # Bumping any value below therefore means re-verifying against a real CoGo # build first -- not just picking something newer. # +# SCOPE: this walks *every* build.gradle.kts, deliberately broader than the +# "top-level dir applying com.itsaky.androidide.plugins.build" definition of a +# plugin used by .githooks/pre-push (plugin_dirs()), scripts/update-libs.sh and +# CLAUDE.md. Subprojects such as ai-core/llama-api and ai-core/llama-impl +# compile into a plugin and must agree on the toolchain, but are invisible to +# that definition -- which is exactly how ai-core/llama-impl kept compileSdk 34 +# through a dedicated standardization pass. Do not "unify" discovery onto +# plugin_dirs(): it would silently drop those modules from coverage. +# # Usage: # scripts/check-toolchain.sh # check; exit 1 and print a report on drift -# scripts/check-toolchain.sh --list # print what every module declares, exit 0 +# scripts/check-toolchain.sh --list # print the versions it checks, exit 0 # set -euo pipefail @@ -34,7 +43,7 @@ EXPECTED_AGP="8.11.0" EXPECTED_KOTLIN="2.3.0" EXPECTED_GRADLE="8.14.3" EXPECTED_GRADLE_DIST="bin" # gradle--bin.zip, not -all.zip -EXPECTED_JAVA="VERSION_17" +EXPECTED_JAVA="JavaVersion.VERSION_17" EXPECTED_JVM_TARGET="JVM_17" # minSdk is deliberately NOT checked. It legitimately varies by what a plugin @@ -45,176 +54,185 @@ EXPECTED_JVM_TARGET="JVM_17" REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$REPO_ROOT" -LIST_ONLY=0 -[ "${1:-}" = "--list" ] && LIST_ONLY=1 +failures=() # drift reports, printed on exit 1 +declared=() # "