From 306ced2573873995df4e8674d9781528d58e7d66 Mon Sep 17 00:00:00 2001 From: Tymofiy Bortnyk Date: Mon, 17 Aug 2026 22:41:10 +0300 Subject: [PATCH 1/2] Relax intl constraint to `any` (SDK-pinned via flutter_localizations) flutter_localizations pins intl to an exact version per Flutter release (0.20.2 on 3.44.x), so any concrete constraint here is redundant at best and unsolvable at worst: dependabot's intl ^0.20.3 bump (PR branch dependabot/pub/minor-and-patch-293bb9c172) can never resolve and re-fails CI after every merge rebases it. `any` is the documented form for SDK-pinned packages (https://dart.dev/go/sdk-version-pinning) and leaves nothing for dependabot to bump. Resolution is unchanged (lockfile identical: intl 0.20.2). Co-Authored-By: Claude Fable 5 --- pubspec.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 3c25294..1c73abc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,8 +41,11 @@ dependencies: # org.bortnik.meteogram/svg method channel (LocationBridge / NativeSvgService.reverseGeocode). # This keeps the app free of any Kotlin-Gradle-Plugin plugin, required by AGP-9 built-in Kotlin. - # Internationalization - intl: ^0.20.2 + # Internationalization — `any` because the Flutter SDK pins intl exactly via + # flutter_localizations (https://dart.dev/go/sdk-version-pinning); a concrete + # constraint here can never out-resolve the pin and only generates unsolvable + # dependabot bumps. + intl: any dev_dependencies: flutter_test: From e03ef4dc7b630f3bf5855d8bce66d90ff1f07f85 Mon Sep 17 00:00:00 2001 From: Tymofiy Bortnyk Date: Mon, 17 Aug 2026 22:53:28 +0300 Subject: [PATCH 2/2] Bump Flutter 3.44.4 -> 3.47.0; declared KGP 2.2.21 -> 2.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flutter 3.47 supports AGP built-in Kotlin first-class: the kotlin-android force-apply is now gated on isBuiltInKotlinEnabled() (AGP >= 9 with android.builtInKotlin=true skips it entirely; flutter/flutter#184837 closed), so the benign "KGP was not found on the classpath" warning from 3.44.x is gone. flutter_localizations now constrains intl with a caret (^0.20.3 instead of the exact 0.20.2 pin), so intl resolves to 0.20.3 under the app's `any` constraint. - CI: flutter-version 3.44.4 -> 3.47.0 in test/e2e/codeql/release workflows - settings.gradle.kts: declared (apply false) KGP 2.2.21 -> 2.4.0, the 3.47 template version — clears 3.47's "Kotlin version will soon be dropped, upgrade to at least 2.3.20" build warning; KGP is still never applied (built-in Kotlin compiles) - analysis_options.yaml: analyzer excludes for build/ and platform dirs, auto-migrated by the 3.47 tool on pub get - pubspec.lock: intl 0.20.3, matcher 0.12.20, meta 1.19.0, test_api 0.7.12, vector_math 2.4.2 (all SDK-pinned) - CLAUDE.md / gradle.properties comments updated; android.newDsl=false still required and still works on 3.47 Verified on 3.47.0: analyze clean (+ --suggestions compatible java/gradle/agp/kgp), 124 Dart tests, Kotlin :app:test, debug (x64) and release (arm64, R8, 19.0MB) APKs build with no KGP warnings. Co-Authored-By: Claude Fable 5 --- .github/workflows/codeql-default.yml | 2 +- .github/workflows/e2e.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- CLAUDE.md | 23 ++++++++++++----------- analysis_options.yaml | 8 ++++++++ android/gradle.properties | 3 ++- android/settings.gradle.kts | 2 +- pubspec.lock | 22 +++++++++++----------- 9 files changed, 38 insertions(+), 28 deletions(-) diff --git a/.github/workflows/codeql-default.yml b/.github/workflows/codeql-default.yml index fac4dc9..3e72fbf 100644 --- a/.github/workflows/codeql-default.yml +++ b/.github/workflows/codeql-default.yml @@ -39,7 +39,7 @@ jobs: uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: '3.44.4' + flutter-version: '3.47.0' cache: true - name: Cache Gradle dependencies diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 0047754..efd4d0a 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -37,7 +37,7 @@ jobs: uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: '3.44.4' + flutter-version: '3.47.0' cache: true - name: Install Flutter dependencies run: flutter pub get diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0774c0e..cf31001 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: '3.44.4' + flutter-version: '3.47.0' cache: true - name: Install dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 71e5788..7127007 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,7 +47,7 @@ jobs: uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: '3.44.4' + flutter-version: '3.47.0' cache: true - name: Cache Gradle dependencies diff --git a/CLAUDE.md b/CLAUDE.md index 74440b5..65e2e53 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,7 +17,7 @@ This file provides context for AI assistants working on this project. | Aspect | Value | |--------|-------| -| Framework | Flutter 3.44.4 (pinned — see "Before Coding") | +| Framework | Flutter 3.47.0 (pinned — see "Before Coding") | | Android SDK | minSdk 30 (Android 11), target 36 — do NOT lower minSdk, see Gotcha #9 | | Weather API | Open-Meteo (free, no key) | | Charting | Native SVG (SvgChartGenerator.kt + AndroidSVG) | @@ -146,17 +146,18 @@ build. The project therefore has **zero Flutter plugins with native code** (`GeneratedPluginRegistrant` is empty): `home_widget` and `geolocator` were both removed in favour of native implementations (`WidgetStore`/`LocationProvider` over the method channel). -**With no KGP plugin present, Flutter 3.44.4 builds clean** (unpinned from 3.41.7 to 3.44.0 -2026-05; bumped to the 3.44.1 then 3.44.4 patch 2026-06). Flutter 3.44.4 still *tries* to force-apply -`kotlin-android` to `:app` and logs a -benign warning — `Applying the Kotlin Android Plugin (KGP) was unsuccessful. KGP was not found -on the classpath.` — but the apply is caught (`FlutterPluginUtils.kt:633`) and the build -succeeds. That one warning line is expected; ignore it (Flutter plans to drop the force-apply, -flutter/flutter#184837). +**With no KGP plugin present, Flutter 3.47.0 builds clean** (unpinned from 3.41.7 to 3.44.0 +2026-05; 3.44.1 → 3.44.4 patches 2026-06; bumped to 3.47.0 2026-08). Flutter 3.47 supports +built-in Kotlin first-class: the old force-apply of `kotlin-android` is now gated on +`isBuiltInKotlinEnabled()` (AGP ≥ 9 + `android.builtInKotlin=true` skips it entirely, +flutter/flutter#184837 closed), so the benign "KGP was not found on the classpath" warning +that 3.44.x logged is gone. Note: 3.47's `flutter_localizations` pins `intl` via a caret +(`^0.20.3`) instead of an exact version, and the app's `intl` constraint is `any` (SDK-pinned; +dart.dev/go/sdk-version-pinning) so dependabot has nothing to bump. -- **Before coding, check the toolchain & deps.** Confirm `flutter --version` is **3.44.4** (the +- **Before coding, check the toolchain & deps.** Confirm `flutter --version` is **3.47.0** (the pinned version — don't unintentionally build on another); run `flutter pub outdated` to review - dependency updates and note any Flutter release past 3.44.4. Treat **any** Flutter or dependency + dependency updates and note any Flutter release past 3.47.0. Treat **any** Flutter or dependency bump as a *deliberate, verified* change — it can re-break the built-in-Kotlin setup (see history below) — not a casual upgrade. - **CRITICAL:** do **not** add any Flutter plugin that applies KGP (most native plugins do) — it @@ -164,7 +165,7 @@ flutter/flutter#184837). channel, or a plugin version that supports built-in Kotlin. If a KGP plugin is unavoidable, you must switch to the legacy path: `android.builtInKotlin=false` + re-add `id("kotlin-android")` to `app/build.gradle.kts` (KGP is already declared `apply false` in `settings.gradle.kts`). -- **CI:** `flutter-version: '3.44.4'` in `.github/workflows/`. +- **CI:** `flutter-version: '3.47.0'` in `.github/workflows/`. - **Verify after any toolchain/plugin change:** `make analyze` + `make test` + a debug build. After switching the local Flutter SDK version, run `flutter clean` first (stale kernel caches from a different Dart version cause spurious `dot-shorthands` framework-compile errors). diff --git a/analysis_options.yaml b/analysis_options.yaml index 4649fa8..5bd7801 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -5,6 +5,14 @@ analyzer: errors: missing_return: error missing_required_param: error + exclude: + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** language: strict-casts: true strict-inference: true diff --git a/android/gradle.properties b/android/gradle.properties index af16bb8..7a47485 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -3,7 +3,8 @@ android.useAndroidX=true # AGP 9 built-in Kotlin: no module applies the Kotlin Gradle Plugin (kotlin-android), # so AGP compiles Kotlin directly. The project keeps zero KGP-using plugins (home_widget + -# geolocator went native) so this works under Flutter 3.44.0. builtInKotlin defaults to true +# geolocator went native). Flutter 3.47+ supports built-in Kotlin first-class (it skips the +# old kotlin-android force-apply when AGP >= 9 has builtInKotlin on). builtInKotlin defaults to true # on AGP 9; set explicitly to document intent. Do NOT add a plugin that applies KGP — see CLAUDE.md. # # newDsl is kept false because the Flutter Gradle plugin path we use does not support the new diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index 97dbbf9..cc65fae 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -22,7 +22,7 @@ plugins { id("com.android.application") version "9.0.1" apply false // Declared (never applied) so Flutter's tooling can read a KGP version; Kotlin // compilation is handled by AGP built-in Kotlin, not this plugin. - id("org.jetbrains.kotlin.android") version "2.2.21" apply false + id("org.jetbrains.kotlin.android") version "2.4.0" apply false } include(":app") diff --git a/pubspec.lock b/pubspec.lock index 4f1b0b3..17a2a3c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -92,10 +92,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: "1ca20c894b1717686a2319b8548763d812bc0aabdac580420a44c5178c57a867" url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.20.3" leak_tracker: dependency: transitive description: @@ -132,10 +132,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.20" material_color_utilities: dependency: transitive description: @@ -148,10 +148,10 @@ packages: dependency: transitive description: name: meta - sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" mocktail: dependency: "direct dev" description: @@ -217,10 +217,10 @@ packages: dependency: transitive description: name: test_api - sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.12" typed_data: dependency: transitive description: @@ -233,10 +233,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: f36f9f3be64c6198714492bb455c11056e33e2f85d9a0b676a48301e44fdcf47 url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.2" vm_service: dependency: transitive description: @@ -254,5 +254,5 @@ packages: source: hosted version: "1.1.1" sdks: - dart: ">=3.10.4 <4.0.0" + dart: ">=3.11.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54"