feat(app): add Android device/emulator support to macOS menu bar app#9547
Draft
feat(app): add Android device/emulator support to macOS menu bar app#9547
Conversation
Users can now share Android APK builds through Tuist Previews, the same way they share iOS .ipa files today. Running `tuist share app.apk` extracts metadata via aapt2 and uploads the APK for distribution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Android SDK's build-tools directory is never added to PATH by standard installation methods (mise, Homebrew). Instead of requiring users to manually add it, look for aapt2 in ANDROID_HOME, ANDROID_SDK_ROOT, and well-known installation paths before falling back to PATH. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Android APK builds use a SHA256 hash as binary_id, and there's no strict requirement to prevent re-uploading the same APK. Replace the unconditional unique index with a partial one that only applies to non-APK build types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… tuist run Extract share and run commands into cross-platform TuistShareCommand and TuistRunCommand modules (following the TuistBuildCommand pattern). Create TuistAndroid module with ADB device discovery, APK install, and app launch. - TuistAndroid: AdbController with device discovery, app install/launch using am start instead of monkey for reliable activity resolution - TuistShareCommand: moved from TuistKit, APK sharing always compiled, Apple builds behind #if os(macOS) - TuistRunCommand: moved from TuistKit, Android device selection and APK install/launch cross-platform, Apple simulator/device behind #if os(macOS) - Restructured PreviewsUploadService for cross-platform APK upload - Added GetPreviewInfoService, ServerPreviewInfo, PreviewUploadResult - Better error messages from adb commands (extracts stderr from CommandError) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts: # server/lib/tuist_web/components/previews/platform_icon.ex # server/priv/gettext/dashboard.pot
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove hardcoded fallback paths (mise, Android Studio, Homebrew) — rely on the standard ANDROID_HOME / ANDROID_SDK_ROOT environment variables and bare PATH lookup instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…solution Removes the `servicePlatform` computed property from `Target+PlatformResolution.swift` and inlines the platform resolution logic at each call site in BuildService, TestService, and RunCommandService. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ommandService Replaces platform-specific FileHandler/AbsolutePath.current branching with the cross-platform Environment.pathRelativeToWorkingDirectory helper. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Linux only preview URLs are supported, so --generate, --clean, --configuration, --os, --rosetta, and passthrough arguments are now only available on macOS. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show platform-appropriate help for the runnable argument and reorder to list the most common options first. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…hods The cross-platform method only accepts path, runnable, and device. The macOS-only method adds generate, clean, configuration, osVersion, rosetta, and arguments parameters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…types Replace the macOS-only booted simulator shortcut with a cross-platform isReady check. Android devices and physical devices are always ready, simulators only when booted. If exactly one ready device exists, it is selected automatically without prompting. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inline the platform checks directly at the call sites. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove custom ServerPreviewInfo and PreviewUploadResult wrapper types, using Components.Schemas.Preview from the generated OpenAPI client instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eview Rename the server operationId from downloadPreview to getPreview and consolidate into a single cross-platform GetPreviewService returning Components.Schemas.Preview. Remove the duplicate macOS-only service and update the app to convert at call sites. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Eliminate the separate APKPreviewUploadService by making PreviewsUploadService cross-platform. APK upload methods are always compiled while IPA/appBundle methods remain behind #if canImport(TuistCore). Git info is now passed as parameters instead of resolved internally, removing the TuistGit dependency from TuistServer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the failable `init?` with a throwing `init` that reports exactly which URL or date failed to parse via ServerPreviewError, instead of silently returning nil. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move configuration, platforms, and derivedDataPath options behind the platform guard since they only apply to Apple builds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…share Move TuistGit from macOS-only to cross-platform targets since all its dependencies are already cross-platform. Use GitController.gitInfo() in ShareCommandService instead of manual CommandRunner git calls, gaining CI environment variable fallbacks for branch/ref detection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…module cross-platform Move APK metadata parsing (aapt2 resolution, badging output parsing) from ShareCommandService into a dedicated APKMetadataService in the TuistAndroid module. Make TuistAndroid cross-platform (macOS + iOS) with Command-using implementations behind #if canImport(Command). Replace custom path() helper with Environment.current.pathRelativeToWorkingDirectory(). Add TuistAndroid as a dependency of TuistServer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parse application-icon-* lines from aapt2 output to find the highest density icon path, then unzip the APK and upload the icon via UploadPreviewIconService. This brings Android previews to parity with Apple previews which already extract and upload app icons. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Command Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend the macOS menu bar app to display Android devices and emulators alongside Apple devices and simulators, and support launching Android APK previews via ADB. - Add TuistAndroid dependency to TuistMenuBar target - Add androidDevice case to Device/SelectedDevice enums - Add AdbController integration to DeviceService for device discovery and APK install/launch - Show Android physical devices in "Connected" section with iOS devices - Show Android emulators in pinned/unpinned sections with simulators - Add AndroidDeviceRow view component with pinning support for emulators - Add well-known paths (mise, Homebrew, Android Studio) to ADB resolution - Add Codable/Hashable conformance to AndroidDevice for AppStorage - Gracefully handle missing ADB (no Android devices shown) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ANDROID_HOME/ANDROID_SDK_ROOTenv varsTest plan
xcsiftbuild build -workspace Tuist.xcworkspace -scheme TuistApppassesxcsiftbuild test -workspace Tuist.xcworkspace -scheme TuistApp -only-testing TuistMenuBarTestspasses (17/17)🤖 Generated with Claude Code