diff --git a/.ci.yaml b/.ci.yaml index 8b928433ca3..294b81ef48b 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -2521,6 +2521,15 @@ targets: - bin/** - .ci.yaml + - name: Mac hello_world_macos__compile + bringup: true # New target https://github.com/flutter/flutter/issues/109633 + recipe: devicelab/devicelab_drone + timeout: 60 + properties: + tags: > + ["devicelab", "hostonly"] + task_name: hello_world_macos__compile + - name: Mac module_custom_host_app_name_test recipe: devicelab/devicelab_drone timeout: 60 diff --git a/TESTOWNERS b/TESTOWNERS index 95ee36fe569..3d7d0fd55b2 100644 --- a/TESTOWNERS +++ b/TESTOWNERS @@ -226,6 +226,7 @@ /dev/devicelab/bin/tasks/complex_layout_win_desktop__start_up.dart @schectman @flutter/desktop /dev/devicelab/bin/tasks/flutter_view_win_desktop__start_up.dart @schectman @flutter/desktop /dev/devicelab/bin/tasks/platform_view_win_desktop__start_up.dart @schectman @flutter/desktop +/dev/devicelab/bin/tasks/hello_world_macos__compile.dart @a-wallen @flutter/desktop ## Host only framework tests # Linux analyze diff --git a/dev/devicelab/bin/tasks/hello_world_macos__compile.dart b/dev/devicelab/bin/tasks/hello_world_macos__compile.dart new file mode 100644 index 00000000000..ce741eca5cb --- /dev/null +++ b/dev/devicelab/bin/tasks/hello_world_macos__compile.dart @@ -0,0 +1,12 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_devicelab/framework/devices.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/tasks/perf_tests.dart'; + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.macos; + await task(createHelloWorldCompileTest()); +} diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart index 86ae8ea6be5..d100317516b 100644 --- a/dev/devicelab/lib/tasks/perf_tests.dart +++ b/dev/devicelab/lib/tasks/perf_tests.dart @@ -671,7 +671,7 @@ class StartupTest { '--profile', '--target=$target', ]); - applicationBinaryPath = _findIosAppInBuildDirectory('$testDirectory/build/ios/iphoneos'); + applicationBinaryPath = _findDarwinAppInBuildDirectory('$testDirectory/build/ios/iphoneos'); break; case DeviceOperatingSystem.fake: case DeviceOperatingSystem.fuchsia: @@ -805,7 +805,7 @@ class DevtoolsStartupTest { '-v', '--profile', ]); - applicationBinaryPath = _findIosAppInBuildDirectory('$testDirectory/build/ios/iphoneos'); + applicationBinaryPath = _findDarwinAppInBuildDirectory('$testDirectory/build/ios/iphoneos'); break; case DeviceOperatingSystem.fake: case DeviceOperatingSystem.fuchsia: @@ -1376,28 +1376,41 @@ class CompileTest { switch (deviceOperatingSystem) { case DeviceOperatingSystem.ios: - options.insert(0, 'ios'); + case DeviceOperatingSystem.macos: + unawaited(stderr.flush()); + late final String deviceId; + if (deviceOperatingSystem == DeviceOperatingSystem.ios) { + deviceId = 'ios'; + } else if (deviceOperatingSystem == DeviceOperatingSystem.macos) { + deviceId = 'macos'; + } else { + throw Exception('Attempted to run darwin compile workflow with $deviceOperatingSystem'); + } + + options.insert(0, deviceId); options.add('--tree-shake-icons'); options.add('--split-debug-info=infos/'); watch.start(); await flutter('build', options: options); watch.stop(); - final Directory appBuildDirectory = dir(path.join(cwd, 'build/ios/Release-iphoneos')); - final Directory? appBundle = appBuildDirectory - .listSync() - .whereType() - .singleWhere((Directory? directory) => - directory != null && path.extension(directory.path) == '.app', - orElse: () => null); - if (appBundle == null) { - throw 'Failed to find app bundle in ${appBuildDirectory.path}'; + final Directory buildDirectory = dir(path.join( + cwd, + 'build', + )); + final String? appBundlePath = + _findDarwinAppInBuildDirectory(buildDirectory.path); + if (appBundlePath == null) { + throw 'Failed to find app bundle in ${buildDirectory.path}'; } - final String appPath = appBundle.path; // IPAs are created manually, https://flutter.dev/ios-release/ - await exec('tar', ['-zcf', 'build/app.ipa', appPath]); + await exec('tar', ['-zcf', 'build/app.ipa', appBundlePath]); releaseSizeInBytes = await file('$cwd/build/app.ipa').length(); if (reportPackageContentSizes) { - metrics.addAll(await getSizesFromIosApp(appPath)); + final Map sizeMetrics = await getSizesFromDarwinApp( + appPath: appBundlePath, + operatingSystem: deviceOperatingSystem, + ); + metrics.addAll(sizeMetrics); } break; case DeviceOperatingSystem.android: @@ -1435,8 +1448,6 @@ class CompileTest { throw Exception('Unsupported option for fake devices'); case DeviceOperatingSystem.fuchsia: throw Exception('Unsupported option for Fuchsia devices'); - case DeviceOperatingSystem.macos: - throw Exception('Unsupported option for macOS devices'); case DeviceOperatingSystem.windows: unawaited(stderr.flush()); options.insert(0, 'windows'); @@ -1496,7 +1507,9 @@ class CompileTest { case DeviceOperatingSystem.fuchsia: throw Exception('Unsupported option for Fuchsia devices'); case DeviceOperatingSystem.macos: - throw Exception('Unsupported option for Fuchsia devices'); + unawaited(stderr.flush()); + options.insert(0, 'macos'); + break; case DeviceOperatingSystem.windows: unawaited(stderr.flush()); options.insert(0, 'windows'); @@ -1511,19 +1524,52 @@ class CompileTest { }; } - static Future> getSizesFromIosApp(String appPath) async { - // Thin the binary to only contain one architecture. - final String xcodeBackend = path.join(flutterDirectory.path, 'packages', 'flutter_tools', 'bin', 'xcode_backend.sh'); - await exec(xcodeBackend, ['thin'], environment: { - 'ARCHS': 'arm64', - 'WRAPPER_NAME': path.basename(appPath), - 'TARGET_BUILD_DIR': path.dirname(appPath), - }); + static Future> getSizesFromDarwinApp({ + required String appPath, + required DeviceOperatingSystem operatingSystem, + }) async { + late final File flutterFramework; + late final String frameworkDirectory; + switch (deviceOperatingSystem) { + case DeviceOperatingSystem.ios: + frameworkDirectory = path.join( + appPath, + 'Frameworks', + ); + flutterFramework = File(path.join( + frameworkDirectory, + 'Flutter.framework', + 'Flutter', + )); + break; + case DeviceOperatingSystem.macos: + frameworkDirectory = path.join( + appPath, + 'Contents', + 'Frameworks', + ); + flutterFramework = File(path.join( + frameworkDirectory, + 'FlutterMacOS.framework', + 'FlutterMacOS', + )); // https://github.com/flutter/flutter/issues/70413 + break; + case DeviceOperatingSystem.android: + case DeviceOperatingSystem.androidArm: + case DeviceOperatingSystem.androidArm64: + case DeviceOperatingSystem.fake: + case DeviceOperatingSystem.fuchsia: + case DeviceOperatingSystem.windows: + throw Exception('Called ${CompileTest.getSizesFromDarwinApp} with $operatingSystem.'); + } - final File appFramework = File(path.join(appPath, 'Frameworks', 'App.framework', 'App')); - final File flutterFramework = File(path.join(appPath, 'Frameworks', 'Flutter.framework', 'Flutter')); + final File appFramework = File(path.join( + frameworkDirectory, + 'App.framework', + 'App', + )); - return { + return { 'app_framework_uncompressed_bytes': await appFramework.length(), 'flutter_framework_uncompressed_bytes': await flutterFramework.length(), }; @@ -1884,8 +1930,9 @@ Future waitForFile(String path) async { throw StateError('Did not find vmservice out file after 1 hour'); } -String? _findIosAppInBuildDirectory(String searchDirectory) { - for (final FileSystemEntity entity in Directory(searchDirectory).listSync()) { +String? _findDarwinAppInBuildDirectory(String searchDirectory) { + for (final FileSystemEntity entity in Directory(searchDirectory) + .listSync(recursive: true)) { if (entity.path.endsWith('.app')) { return entity.path; }