From 0937a1c5ad3af5cf53f826b4763da5537b8e8c49 Mon Sep 17 00:00:00 2001 From: Tommy Chow Date: Sat, 15 Aug 2026 14:51:05 -0700 Subject: [PATCH] build(deps): bump Flutter to 3.47.0 and Android Gradle stack (#590) * build(deps): bump Flutter pin to 3.47.0 and Android Gradle stack Pin Flutter 3.47.0 (Dart 3.13) as the CI source of truth and move the Android toolchain to the 3.47 template versions: Gradle 9.3.1, AGP 9.1.0, Kotlin 2.4.0. App Gradle script matches the 3.47 template (drop kotlin-android / kotlinOptions, use compilerOptions). Keep android.builtInKotlin=false and android.newDsl=false so plugins that still apply KGP keep building. AGP 9 requires libraries to compile against their dependencies' compileSdk; force plugin modules to 36 via finalizeDsl. Ignore android/build/, which AGP 9 now writes a problems report into. analyze, test, and a release APK all passed. 16 KB zip alignment verified. iOS UIScene is not in this commit: AppDelegate is customized (CookieExtractorPlugin), so Flutter will not auto-migrate. * ci: drop unused Claude Code GitHub Actions Remove the PR review workflow and the @claude mention bot. Neither is used anymore; the review job just failed this PR on an expired OAuth token. * feat(ios): adopt UIScene lifecycle for Flutter 3.47 Adopt UIApplicationSceneManifest and FlutterImplicitEngineDelegate in AppDelegate to support the UIScene lifecycle requirement on iOS. Co-authored-by: Cursor --------- Co-authored-by: Cursor --- .github/workflows/claude-code-review.yml | 43 ---------------- .github/workflows/claude.yml | 49 ------------------- .gitignore | 2 + analysis_options.yaml | 3 ++ android/app/build.gradle.kts | 11 +++-- android/build.gradle.kts | 13 +++++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/settings.gradle.kts | 4 +- ios/Flutter/AppFrameworkInfo.plist | 2 - ios/Podfile.lock | 2 +- ios/Runner/AppDelegate.swift | 14 ++++-- ios/Runner/Info.plist | 21 ++++++++ pubspec.lock | 18 +++---- pubspec.yaml | 2 +- 14 files changed, 68 insertions(+), 118 deletions(-) delete mode 100644 .github/workflows/claude-code-review.yml delete mode 100644 .github/workflows/claude.yml diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml deleted file mode 100644 index 66e16681..00000000 --- a/.github/workflows/claude-code-review.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Claude Code Review - -on: - pull_request: - types: [opened, synchronize, ready_for_review, reopened] - # Optional: Only run on specific file changes - # paths: - # - "src/**/*.ts" - # - "src/**/*.tsx" - # - "src/**/*.js" - # - "src/**/*.jsx" - -jobs: - claude-review: - # Optional: Filter by PR author - # if: | - # github.event.pull_request.user.login == 'external-contributor' || - # github.event.pull_request.user.login == 'new-developer' || - # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' - - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - issues: read - id-token: write - - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 1 - - - name: Run Claude Code Review - id: claude-review - uses: anthropics/claude-code-action@v1 - with: - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' - plugins: 'code-review@claude-code-plugins' - prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://code.claude.com/docs/en/cli-reference for available options diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml deleted file mode 100644 index 50f44994..00000000 --- a/.github/workflows/claude.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Claude Code - -on: - issue_comment: - types: [created] - pull_request_review_comment: - types: [created] - issues: - types: [opened, assigned] - pull_request_review: - types: [submitted] - -jobs: - claude: - if: | - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - issues: read - id-token: write - actions: read # Required for Claude to read CI results on PRs - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 1 - - - name: Run Claude Code - id: claude - uses: anthropics/claude-code-action@v1 - with: - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - - # This is an optional setting that allows Claude to read CI results on PRs - additional_permissions: | - actions: read - - # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. - # prompt: 'Update the pull request description to include a summary of changes.' - - # Optional: Add claude_args to customize behavior and configuration - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://code.claude.com/docs/en/cli-reference for available options - # claude_args: '--allowed-tools Bash(gh pr:*)' diff --git a/.gitignore b/.gitignore index 1cbf0d64..dfee3eb8 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,8 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release +# AGP 9 writes a problems report here even when the Gradle build dir is redirected +/android/build/ # Folder containing random testing files random/ diff --git a/analysis_options.yaml b/analysis_options.yaml index de45531d..3b60af70 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -16,6 +16,9 @@ analyzer: - ios/** - android/** - web/** + - windows/** + - macos/** + - linux/** linter: # The lint rules applied to this project can be customized in the diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 596b2812..998334f3 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -6,7 +6,6 @@ plugins { id("com.google.gms.google-services") id("com.google.firebase.firebase-perf") id("com.google.firebase.crashlytics") - id("kotlin-android") // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id("dev.flutter.flutter-gradle-plugin") } @@ -27,10 +26,6 @@ android { targetCompatibility = JavaVersion.VERSION_17 } - kotlinOptions { - jvmTarget = JavaVersion.VERSION_17.toString() - } - defaultConfig { applicationId = "com.tommychow.frosty" minSdk = flutter.minSdkVersion @@ -64,6 +59,12 @@ android { } } +kotlin { + compilerOptions { + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } +} + flutter { source = "../.." } diff --git a/android/build.gradle.kts b/android/build.gradle.kts index dbee657b..b477a6e8 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -1,3 +1,5 @@ +import com.android.build.api.variant.LibraryAndroidComponentsExtension + allprojects { repositories { google() @@ -19,6 +21,17 @@ subprojects { project.evaluationDependsOn(":app") } +// AGP 9 requires each library to compile against at least the compileSdk of +// its dependencies. Several Flutter plugins still pin compileSdk 33/34. +// finalizeDsl runs after the plugin's android {} block. Does not change minSdk. +subprojects { + pluginManager.withPlugin("com.android.library") { + extensions.configure("androidComponents") { + finalizeDsl { it.compileSdk = 36 } + } + } +} + tasks.register("clean") { delete(rootProject.layout.buildDirectory) } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index db3f4531..bcef617e 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index f4978443..f68c56f0 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.11.1" apply false - id("org.jetbrains.kotlin.android") version "2.2.20" apply false + id("com.android.application") version "9.1.0" apply false + id("org.jetbrains.kotlin.android") version "2.4.0" apply false id("com.google.gms.google-services") version "4.4.4" apply false id("com.google.firebase.firebase-perf") version "2.0.2" apply false id("com.google.firebase.crashlytics") version "3.0.6" apply false diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 0d140800..391a902b 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -20,7 +20,5 @@ ???? CFBundleVersion 1.0 - MinimumOSVersion - 15.0 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2cf6d774..560b1f09 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -20,7 +20,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: advanced_in_app_review: daebe4c801525b756fe589de60fd327cb12f965c - Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + Flutter: 71a624a5bc0c04062bf19101d501e466baf2fb47 flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13 PODFILE CHECKSUM: 57c8aed26fba39d3ec9424816221f294a07c58eb diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index a66ef771..a51f2738 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,19 +2,23 @@ import Flutter import UIKit @main -@objc class AppDelegate: FlutterAppDelegate { +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - guard let cookieExtractorRegistrar = self.registrar( + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + guard let cookieExtractorRegistrar = engineBridge.pluginRegistry.registrar( forPlugin: "CookieExtractorPlugin" ) else { assertionFailure("Failed to create CookieExtractorPlugin registrar") - return false + return } CookieExtractorPlugin.register(with: cookieExtractorRegistrar) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 6052fdf9..1f85dcd5 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -52,6 +52,27 @@ UIApplicationSupportsIndirectInputEvents + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneDelegateClassName + FlutterSceneDelegate + UISceneConfigurationName + flutter + UISceneStoryboardFile + Main + + + + UIStatusBarHidden UIBackgroundModes diff --git a/pubspec.lock b/pubspec.lock index 128e2ed0..ea969bdb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -814,10 +814,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: @@ -830,10 +830,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" mime: dependency: transitive description: @@ -1284,10 +1284,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: @@ -1404,10 +1404,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: @@ -1538,4 +1538,4 @@ packages: version: "3.1.3" sdks: dart: ">=3.12.0 <4.0.0" - flutter: "3.44.9" + flutter: "3.47.0" diff --git a/pubspec.yaml b/pubspec.yaml index a2ec9777..b24b3fa0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,7 +23,7 @@ environment: sdk: ^3.9.0 # Exact Flutter pin, enforced by `flutter pub get` locally and read by CI via # `flutter-version-file: pubspec.yaml`. Single source of truth: bump here. - flutter: 3.44.9 + flutter: 3.47.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions