From a5fea8c795734dcfce181ce097af7cbea8aee106 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Mon, 8 Apr 2024 09:56:06 -0700 Subject: [PATCH] Increase the recommended Xcode version to Xcode 15 (#146367) Xcode 15 will be required for iOS App Store submission > Please note that as of April 2024 all iOS and iPadOS apps submitted to the App Store must be built with a minimum of Xcode 15 and the iOS 17 SDK. https://developer.apple.com/ios/submit/ And will also be required for Swift Package Manager support https://github.com/flutter/flutter/pull/146256. We could swap to "required" but macOS developers don't technically need to upgrade. We can let the Store itself enforce its policies. And we can swap to Xcode 15 "required" when SPM adoption is further along. Part of https://github.com/flutter/flutter/issues/144582 --- .../flutter_tools/lib/src/macos/xcode.dart | 2 +- .../test/general.shard/macos/xcode_test.dart | 29 ++++++++++++++++--- .../macos/xcode_validator_test.dart | 6 ++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/flutter_tools/lib/src/macos/xcode.dart b/packages/flutter_tools/lib/src/macos/xcode.dart index 540f08d5f3b..ea2a161e870 100644 --- a/packages/flutter_tools/lib/src/macos/xcode.dart +++ b/packages/flutter_tools/lib/src/macos/xcode.dart @@ -24,7 +24,7 @@ Version get xcodeRequiredVersion => Version(14, null, null); /// Diverging this number from the minimum required version will provide a doctor /// warning, not error, that users should upgrade Xcode. -Version get xcodeRecommendedVersion => xcodeRequiredVersion; +Version get xcodeRecommendedVersion => Version(15, null, null); /// SDK name passed to `xcrun --sdk`. Corresponds to undocumented Xcode /// SUPPORTED_PLATFORMS values. diff --git a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart index b250f15cba2..aaaa81f72be 100644 --- a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart @@ -312,12 +312,12 @@ void main() { expect(xcode.isRecommendedVersionSatisfactory, isFalse); }); - testWithoutContext('version checks pass when version meets minimum', () { + testWithoutContext('version checks pass when version meets minimum but not recommended', () { xcodeProjectInterpreter.isInstalled = true; xcodeProjectInterpreter.version = Version(14, null, null); expect(xcode.isRequiredVersionSatisfactory, isTrue); - expect(xcode.isRecommendedVersionSatisfactory, isTrue); + expect(xcode.isRecommendedVersionSatisfactory, isFalse); }); testWithoutContext('version checks pass when major version exceeds minimum', () { @@ -325,7 +325,6 @@ void main() { xcodeProjectInterpreter.version = Version(15, 0, 0); expect(xcode.isRequiredVersionSatisfactory, isTrue); - expect(xcode.isRecommendedVersionSatisfactory, isTrue); }); testWithoutContext('version checks pass when minor version exceeds minimum', () { @@ -333,13 +332,35 @@ void main() { xcodeProjectInterpreter.version = Version(14, 3, 0); expect(xcode.isRequiredVersionSatisfactory, isTrue); - expect(xcode.isRecommendedVersionSatisfactory, isTrue); }); testWithoutContext('version checks pass when patch version exceeds minimum', () { xcodeProjectInterpreter.isInstalled = true; xcodeProjectInterpreter.version = Version(14, 0, 2); + expect(xcode.isRequiredVersionSatisfactory, isTrue); + }); + + testWithoutContext('version checks pass when major version exceeds recommendation', () { + xcodeProjectInterpreter.isInstalled = true; + xcodeProjectInterpreter.version = Version(16, 0, 0); + + expect(xcode.isRequiredVersionSatisfactory, isTrue); + expect(xcode.isRecommendedVersionSatisfactory, isTrue); + }); + + testWithoutContext('version checks pass when minor version exceeds recommendation', () { + xcodeProjectInterpreter.isInstalled = true; + xcodeProjectInterpreter.version = Version(15, 3, 0); + + expect(xcode.isRequiredVersionSatisfactory, isTrue); + expect(xcode.isRecommendedVersionSatisfactory, isTrue); + }); + + testWithoutContext('version checks pass when patch version exceeds recommendation', () { + xcodeProjectInterpreter.isInstalled = true; + xcodeProjectInterpreter.version = Version(15, 0, 2); + expect(xcode.isRequiredVersionSatisfactory, isTrue); expect(xcode.isRecommendedVersionSatisfactory, isTrue); }); diff --git a/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart b/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart index 70a454a57d3..b8d2f1988e8 100644 --- a/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart @@ -77,7 +77,7 @@ void main() { final ProcessManager processManager = FakeProcessManager.any(); final Xcode xcode = Xcode.test( processManager: processManager, - xcodeProjectInterpreter: XcodeProjectInterpreter.test(processManager: processManager, version: Version(12, 4, null)), + xcodeProjectInterpreter: XcodeProjectInterpreter.test(processManager: processManager, version: Version(14, 4, null)), ); final XcodeValidator validator = XcodeValidator( xcode: xcode, @@ -87,8 +87,8 @@ void main() { final ValidationResult result = await validator.validate(); expect(result.type, ValidationType.partial); expect(result.messages.last.type, ValidationMessageType.hint); - expect(result.messages.last.message, contains('Flutter recommends a minimum Xcode version of 13')); - }, skip: true); // [intended] Unskip and update when minimum and required check versions diverge. + expect(result.messages.last.message, contains('Flutter recommends a minimum Xcode version of 15')); + }, skip: false); // [intended] Skip this test when minimum and required check versions converge. testWithoutContext('Emits partial status when Xcode EULA not signed', () async { final ProcessManager processManager = FakeProcessManager.list([