From b98d48549c8752c649ace52ef200e7d51d6d20b1 Mon Sep 17 00:00:00 2001 From: Gray Mackall <34871572+gmackall@users.noreply.github.com> Date: Tue, 18 Jun 2024 13:24:09 -0700 Subject: [PATCH] Make flutter tool enforce >= kotlin 1.7.0, Gradle 7.0.2, and AGP 7.0.0, and Fix test failures blocking androidx upgrade (#149204) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR to pave the way for https://github.com/flutter/engine/pull/53001 to re-land Summary: - Enforces use of Kotlin >= `1.7.0` (please see below note) - Fixes ci failures that prevented the above PR from landing. Details: Because it landed initially, we are able to fake the roll in this PR to fix all the tests ([see my comment](https://github.com/flutter/flutter/pull/149204#discussion_r1617924772)). Fixes all the tests that failed: 1. `module_test` failing on multiple platforms (3/9 of the failures). Failure is ``` > Android resource linking failed ERROR:/b/s/w/ir/x/t/flutter_module_test.KECMXW/hello/.android/plugins_build_output/device_info/intermediates/merged_res/release/values/values.xml:194: AAPT: error: resource android:attr/lStar not found. ``` This is a rather unhelpful error message but some [folks online suggest](https://stackoverflow.com/a/69050529) that upgrading your `compileSdk` version fixes this. These resolve when I remove the dependency on the long discontinued [package_info](https://pub.dev/packages/package_info) and [device_info](https://pub.dev/packages/device_info) packages, perhaps because they are transitively pulling in low `compileSdk` versions? This is unclear to me. 2. `module_custom_host_app_name_test` was failing for the same reason (another 3/9, or cumulative 6/9). 3. `tool_integration_tests_3_4` was a flake 🙂 (7/9) 4. `framework_tests_slow` needed a newer version of the Kotlin Gradle plugin (the flutter tool tells us this, so I just upgraded as suggested) and it resolved (8/9) 5.`android_preview_tool_integration_tests` needed newer AGP and KGP versions. I also refactored the tests, and bumped our error versions, fixing https://github.com/flutter/flutter/issues/142653. **Note that the bump to KGP is not in line with our policy** - we didn't warn for `1.5.0-1.6.x` for a release (or at all) before dropping support. But I think it might still be justified: - The bump to our androidx libraries unblocks ongoing Scribe work, and also includes a fix for a [memory leak](https://github.com/flutter/flutter/issues/129307#issuecomment-1601636959) and a [crash on folding phones](https://github.com/flutter/flutter/issues/114868#issuecomment-2133226962), among many other bug fixes. - Gradle [doesn't test on half of that range](https://docs.gradle.org/current/userguide/compatibility.html#kotlin), and so we implicitly can't claim to support it either. More generally, our Java and Kotlin support ranges should probably strictly fall within what Gradle tests. --- .../module_custom_host_app_name_test.dart | 2 +- dev/devicelab/bin/tasks/module_test.dart | 2 +- dev/tracing_tests/android/settings.gradle | 2 +- .../dependency_version_checker.gradle.kts | 19 ++- .../module/android/gradle/build.gradle.tmpl | 1 + ...roid_dependency_version_checking_test.dart | 115 +++++------------- 6 files changed, 41 insertions(+), 100 deletions(-) diff --git a/dev/devicelab/bin/tasks/module_custom_host_app_name_test.dart b/dev/devicelab/bin/tasks/module_custom_host_app_name_test.dart index 7471bdcd0d1b..fd12a871c733 100644 --- a/dev/devicelab/bin/tasks/module_custom_host_app_name_test.dart +++ b/dev/devicelab/bin/tasks/module_custom_host_app_name_test.dart @@ -73,7 +73,7 @@ Future main() async { content = await pubspec.readAsString(); content = content.replaceFirst( '${platformLineSep}dependencies:$platformLineSep', - '${platformLineSep}dependencies:$platformLineSep device_info: 2.0.3$platformLineSep package_info: 2.0.2$platformLineSep', + '${platformLineSep}dependencies:$platformLineSep', ); await pubspec.writeAsString(content, flush: true); await inDirectory(projectDir, () async { diff --git a/dev/devicelab/bin/tasks/module_test.dart b/dev/devicelab/bin/tasks/module_test.dart index 9d5f8f8137b0..4b31487e4b68 100644 --- a/dev/devicelab/bin/tasks/module_test.dart +++ b/dev/devicelab/bin/tasks/module_test.dart @@ -121,7 +121,7 @@ class ModuleTest { content = content.replaceFirst( '${platformLineSep}dependencies:$platformLineSep', - '${platformLineSep}dependencies:$platformLineSep device_info: 2.0.3$platformLineSep package_info: 2.0.2$platformLineSep', + '${platformLineSep}dependencies:$platformLineSep', ); await pubspec.writeAsString(content, flush: true); await inDirectory(projectDir, () async { diff --git a/dev/tracing_tests/android/settings.gradle b/dev/tracing_tests/android/settings.gradle index a6c9bea71ffe..315de6a53f4b 100644 --- a/dev/tracing_tests/android/settings.gradle +++ b/dev/tracing_tests/android/settings.gradle @@ -28,7 +28,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "7.3.0" apply false - id "org.jetbrains.kotlin.android" version "1.6.0" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" apply false } include ":app" diff --git a/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts b/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts index 720c63460bab..eb5694afe095 100644 --- a/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts +++ b/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts @@ -65,7 +65,7 @@ class DependencyVersionChecker { private fun getPotentialAGPFix(projectDirectory: String): String { return "Your project's AGP version is typically " + - "defined the plugins block of the `settings.gradle` file " + + "defined in the plugins block of the `settings.gradle` file " + "($projectDirectory/settings.gradle), by a plugin with the id of " + "com.android.application. \nIf you don't see a plugins block, your project " + "was likely created with an older template version. In this case it is most " + @@ -76,7 +76,7 @@ class DependencyVersionChecker { private fun getPotentialKGPFix(projectDirectory: String): String { return "Your project's KGP version is typically " + - "defined the plugins block of the `settings.gradle` file " + + "defined in the plugins block of the `settings.gradle` file " + "($projectDirectory/settings.gradle), by a plugin with the id of " + "org.jetbrains.kotlin.android. \nIf you don't see a plugins block, your project " + "was likely created with an older template version, in which case it is most " + @@ -85,23 +85,20 @@ class DependencyVersionChecker { } // The following versions define our support policy for Gradle, Java, AGP, and KGP. - // All "error" versions are currently set to 0 as this policy is new. They will be increased - // to match the current values of the "warn" versions in the next release. // Before updating any "error" version, ensure that you have updated the corresponding // "warn" version for a full release to provide advanced warning. See // flutter.dev/go/android-dependency-versions for more. - // TODO(gmackall): https://github.com/flutter/flutter/issues/142653. - val warnGradleVersion: Version = Version(7, 0, 2) - val errorGradleVersion: Version = Version(0, 0, 0) + val warnGradleVersion: Version = Version(7, 1, 0) + val errorGradleVersion: Version = Version(7, 0, 2) val warnJavaVersion: JavaVersion = JavaVersion.VERSION_11 val errorJavaVersion: JavaVersion = JavaVersion.VERSION_1_1 - val warnAGPVersion: Version = Version(7, 0, 0) - val errorAGPVersion: Version = Version(0, 0, 0) + val warnAGPVersion: Version = Version(7, 0, 1) + val errorAGPVersion: Version = Version(7, 0, 0) - val warnKGPVersion: Version = Version(1, 5, 0) - val errorKGPVersion: Version = Version(0, 0, 0) + val warnKGPVersion: Version = Version(1, 7, 10) + val errorKGPVersion: Version = Version(1, 7, 0) /** * Checks if the project's Android build time dependencies are each within the respective diff --git a/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl b/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl index 0134936423f0..a0d7f621d698 100644 --- a/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl +++ b/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl @@ -32,6 +32,7 @@ android { compileSdk = {{compileSdkVersion}} defaultConfig { minSdk = {{minSdkVersion}} + targetSdk = {{targetSdkVersion}} } } diff --git a/packages/flutter_tools/test/android_preview_integration.shard/android_dependency_version_checking_test.dart b/packages/flutter_tools/test/android_preview_integration.shard/android_dependency_version_checking_test.dart index 1906753b04c1..96e3f6353d35 100644 --- a/packages/flutter_tools/test/android_preview_integration.shard/android_dependency_version_checking_test.dart +++ b/packages/flutter_tools/test/android_preview_integration.shard/android_dependency_version_checking_test.dart @@ -67,8 +67,10 @@ void main() { tryToDelete(tempDir as FileSystemEntity); }); - testUsingContext( - 'AGP version out of "warn" support band prints warning but still builds', () async { + Future buildFlutterApkWithSpecifiedDependencyVersions({ + required String gradleVersion, + required String agpVersion, + required String kgpVersion}) async { // Create a new flutter project. final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); ProcessResult result = await processManager.run([ @@ -78,9 +80,6 @@ void main() { '--platforms=android', ], workingDirectory: tempDir.path); expect(result, const ProcessResultMatcher()); - const String gradleVersion = '7.5'; - const String agpVersion = '4.2.0'; - const String kgpVersion = '1.7.10'; final Directory app = Directory(fileSystem.path.join(tempDir.path, 'dependency_checker_app')); @@ -108,101 +107,45 @@ void main() { 'apk', '--debug', ], workingDirectory: app.path); - expect(result, const ProcessResultMatcher()); - expect(result.stderr, contains('Please upgrade your Android Gradle ' - 'Plugin version')); - }); + return result; + } testUsingContext( - 'Gradle version out of "warn" support band prints warning but still builds', () async { - // Create a new flutter project. - final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); - ProcessResult result = await processManager.run([ - flutterBin, - 'create', - 'dependency_checker_app', - '--platforms=android', - ], workingDirectory: tempDir.path); - expect(result, const ProcessResultMatcher()); - const String gradleVersion = '7.0'; - const String agpVersion = '4.2.0'; - const String kgpVersion = '1.7.10'; + 'AGP version out of "warn" support band but in "error" band builds ' + 'successfully and prints warning', () async { - final Directory app = Directory(fileSystem.path.join(tempDir.path, 'dependency_checker_app')); - - // Modify gradle version to passed in version. - final File gradleWrapperProperties = File(fileSystem.path.join( - app.path, 'android', 'gradle', 'wrapper', 'gradle-wrapper.properties')); - final String propertyContent = gradleWrapperPropertiesFileContent.replaceFirst( - gradleReplacementString, - gradleVersion, + final ProcessResult result = await buildFlutterApkWithSpecifiedDependencyVersions( + gradleVersion: '7.5', + agpVersion: '7.0.0', + kgpVersion: '1.7.10' ); - await gradleWrapperProperties.writeAsString(propertyContent, flush: true); - - final File gradleSettings = File(fileSystem.path.join( - app.path, 'android', 'settings.gradle')); - final String settingsContent = gradleSettingsFileContent - .replaceFirst(agpReplacementString, agpVersion) - .replaceFirst(kgpReplacementString, kgpVersion); - await gradleSettings.writeAsString(settingsContent, flush: true); - - - // Ensure that gradle files exists from templates. - result = await processManager.run([ - flutterBin, - 'build', - 'apk', - '--debug', - ], workingDirectory: app.path); expect(result, const ProcessResultMatcher()); - expect(result.stderr, contains('Please upgrade your Gradle version')); + expect(result.stderr, contains('Please upgrade your Android Gradle Plugin version')); }); testUsingContext( - 'Kotlin version out of "warn" support band prints warning but still builds', () async { + 'Gradle version out of "warn" support band but in "error" band builds ' + 'successfully and prints warning', () async { // Create a new flutter project. - final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); - ProcessResult result = await processManager.run([ - flutterBin, - 'create', - 'dependency_checker_app', - '--platforms=android', - ], workingDirectory: tempDir.path); + final ProcessResult result = await buildFlutterApkWithSpecifiedDependencyVersions( + gradleVersion: '7.0.2', + agpVersion: '7.0.0', + kgpVersion: '1.7.10' + ); expect(result, const ProcessResultMatcher()); - const String gradleVersion = '7.5'; - const String agpVersion = '7.4.0'; - const String kgpVersion = '1.4.10'; - - final Directory app = Directory(fileSystem.path.join(tempDir.path, 'dependency_checker_app')); + expect(result.stderr, contains('Please upgrade your Gradle version')); + }); - // Modify gradle version to passed in version. - final File gradleWrapperProperties = File(fileSystem.path.join( - app.path, 'android', 'gradle', 'wrapper', 'gradle-wrapper.properties')); - final String propertyContent = gradleWrapperPropertiesFileContent.replaceFirst( - gradleReplacementString, - gradleVersion, + testUsingContext( + 'Kotlin version out of "warn" support band but in "error" band builds ' + 'successfully and prints warning', () async { + final ProcessResult result = await buildFlutterApkWithSpecifiedDependencyVersions( + gradleVersion: '7.5', + agpVersion: '7.4.0', + kgpVersion: '1.7.0' ); - await gradleWrapperProperties.writeAsString(propertyContent, flush: true); - - final File gradleSettings = File(fileSystem.path.join( - app.path, 'android', 'settings.gradle')); - final String settingsContent = gradleSettingsFileContent - .replaceFirst(agpReplacementString, agpVersion) - .replaceFirst(kgpReplacementString, kgpVersion); - await gradleSettings.writeAsString(settingsContent, flush: true); - - // Ensure that gradle files exists from templates. - result = await processManager.run([ - flutterBin, - 'build', - 'apk', - '--debug', - ], workingDirectory: app.path); expect(result, const ProcessResultMatcher()); expect(result.stderr, contains('Please upgrade your Kotlin version')); }); - - // TODO(gmackall): Add tests for build blocking when the - // corresponding error versions are enabled. }