diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3a1ff8029..1a4df5d9a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,38 +45,6 @@ jobs: draft: false prerelease: false - build-mac: - needs: - - release - runs-on: macos-latest - env: - desktop-directory: ./desktop - - steps: - - uses: actions/checkout@v3.5.3 - with: - ref: ${{ needs.release.outputs.tag }} - - uses: actions/setup-node@v3.6.0 - with: - node-version: '18.x' - - name: Install - uses: nick-fields/retry@v2.8.3 - with: - timeout_minutes: 10 - max_attempts: 3 - command: cd ${{env.desktop-directory}} && yarn - - name: Build - uses: nick-fields/retry@v2.8.3 - with: - timeout_minutes: 30 - max_attempts: 3 - command: cd ${{env.desktop-directory}} && yarn build --mac --mac-dmg - - name: Upload - uses: actions/upload-artifact@v3.1.2 - with: - name: 'Flipper-mac.dmg' - path: 'dist/Flipper-mac.dmg' - build-server-mac: needs: - release @@ -112,72 +80,6 @@ jobs: name: 'Flipper-server-mac-aarch64.dmg' path: 'dist/Flipper-server-mac-aarch64.dmg' - build-linux: - needs: - - release - runs-on: ubuntu-latest - env: - desktop-directory: ./desktop - - steps: - - uses: actions/checkout@v3.5.3 - with: - ref: ${{ needs.release.outputs.tag }} - - uses: actions/setup-node@v3.6.0 - with: - node-version: '18.x' - - name: Install - uses: nick-fields/retry@v2.8.3 - with: - timeout_minutes: 10 - max_attempts: 3 - command: cd ${{env.desktop-directory}} && yarn - - name: Build - uses: nick-fields/retry@v2.8.3 - with: - timeout_minutes: 30 - max_attempts: 3 - command: cd ${{env.desktop-directory}} && yarn build --linux - - name: Upload Linux - uses: actions/upload-artifact@v3.1.2 - with: - name: 'Flipper-linux.zip' - path: 'dist/Flipper-linux.zip' - - build-win: - needs: - - release - runs-on: windows-latest - env: - desktop-directory: ./desktop - - steps: - - uses: actions/checkout@v3.5.3 - with: - ref: ${{ needs.release.outputs.tag }} - - uses: actions/setup-node@v3.6.0 - with: - node-version: '18.x' - - name: Install - uses: nick-fields/retry@v2.8.3 - with: - timeout_minutes: 10 - max_attempts: 3 - shell: pwsh - command: cd ${{env.desktop-directory}}; yarn - - name: Build - uses: nick-fields/retry@v2.8.3 - with: - timeout_minutes: 30 - max_attempts: 3 - shell: pwsh - command: cd ${{env.desktop-directory}}; yarn build --win - - name: Upload Windows - uses: actions/upload-artifact@v3.1.2 - with: - name: 'Flipper-win.zip' - path: 'dist/Flipper-win.zip' - build-flipper-server: needs: - release @@ -210,9 +112,6 @@ jobs: publish: needs: - - build-win - - build-linux - - build-mac - build-server-mac - build-flipper-server - release @@ -222,12 +121,6 @@ jobs: - uses: actions/checkout@v3.5.3 with: ref: ${{ needs.release.outputs.tag }} - - name: Download Mac - if: ${{ needs.release.outputs.tag != '' }} - uses: actions/download-artifact@v1 - with: - name: 'Flipper-mac.dmg' - path: 'Flipper-mac.dmg' - name: Download Flipper Server x86-64 if: ${{ needs.release.outputs.tag != '' }} uses: actions/download-artifact@v1 @@ -240,18 +133,6 @@ jobs: with: name: 'Flipper-server-mac-aarch64.dmg' path: 'Flipper-server-mac-aarch64.dmg' - - name: Download Linux - if: ${{ needs.release.outputs.tag != '' }} - uses: actions/download-artifact@v1 - with: - name: 'Flipper-linux.zip' - path: 'Flipper-linux.zip' - - name: Download Windows - if: ${{ needs.release.outputs.tag != '' }} - uses: actions/download-artifact@v1 - with: - name: 'Flipper-win.zip' - path: 'Flipper-win.zip' - name: Download Flipper Server if: ${{ needs.release.outputs.tag != '' }} uses: actions/download-artifact@v1 @@ -265,7 +146,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: created_tag: ${{ needs.release.outputs.tag }} - args: Flipper-mac.dmg/Flipper-mac.dmg Flipper-linux.zip/Flipper-linux.zip Flipper-win.zip/Flipper-win.zip flipper-server.tgz/flipper-server.tgz Flipper-server-mac-x64.dmg/Flipper-server-mac-x64.dmg Flipper-server-mac-aarch64.dmg/Flipper-server-mac-aarch64.dmg + args: flipper-server.tgz/flipper-server.tgz Flipper-server-mac-x64.dmg/Flipper-server-mac-x64.dmg Flipper-server-mac-aarch64.dmg/Flipper-server-mac-aarch64.dmg - name: Set up npm token run: echo "//registry.yarnpkg.com/:_authToken=${{ secrets.FLIPPER_NPM_TOKEN }}" >> ~/.npmrc - name: Publish flipper-server on NPM diff --git a/.gitignore b/.gitignore index 9a301999a..d614cbca7 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ xplat/build # Mac OS X *.DS_Store +facebook/flipper-server/Resources/ # Automatically generated docs/extending/ui-components.mdx diff --git a/README.md b/README.md index 727eed423..e6eb68ffd 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,24 @@
+--- +## Important Accouncement + +Flipper is moving away from its Electron distribution to an in-Browser experience. + +**How does this affect me?** + +Functionality hasn't changed. The UI remains unchanged. Flipper will run in your default browser instead of a standalone application. +If you build from source, Flipper will open in the browser instead of a standalone app. We also provide a MacOS app for the Flipper runtime which can be run and will also open Flipper in the browser. + +The last Electron release is [v0.239.0](https://github.com/facebook/flipper/releases/tag/v0.239.0). As such, future releases will not include Electron artifacts. + +### React Native support + +If you are debugging React Native applications, v0.239.0 will be the last release with support for it due to technical limitations for React Dev Tools and Hermes Debugger plugins. As such, please refer to that release when debugging React Native applications. + +--- +Flipper (formerly Sonar) is a platform for debugging mobile apps on iOS and Android and JS apps in your browser or in Node.js. Visualize, inspect, and control your apps from a simple desktop interface. Use Flipper as is or extend it using the plugin API.
diff --git a/build.gradle b/build.gradle index 48fc54c05..a30924ed0 100644 --- a/build.gradle +++ b/build.gradle @@ -109,7 +109,7 @@ ext.deps = [ okhttp3 : 'com.squareup.okhttp3:okhttp:4.11.0', leakcanary : 'com.squareup.leakcanary:leakcanary-android:1.6.3', leakcanary2 : 'com.squareup.leakcanary:leakcanary-android:2.8.1', - protobuf : 'com.google.protobuf:protobuf-java:3.23.4', + protobuf : 'com.google.protobuf:protobuf-java:3.25.1', testCore : 'androidx.test:core:1.4.0', testRules : 'androidx.test:rules:1.5.0', // Plugin dependencies diff --git a/desktop/app/src/init.tsx b/desktop/app/src/init.tsx index 697d66c49..756a678ed 100644 --- a/desktop/app/src/init.tsx +++ b/desktop/app/src/init.tsx @@ -143,7 +143,7 @@ async function getFlipperServer( const {readyForIncomingConnections} = await startServer( { staticPath, - entry: 'index.web.dev.html', + entry: 'index.web.html', port, }, environmentInfo, diff --git a/desktop/doctor/src/fb-stubs/idbInstallationInstructions.tsx b/desktop/doctor/src/fb-stubs/idbInstallationInstructions.tsx deleted file mode 100644 index cb326a3a8..000000000 --- a/desktop/doctor/src/fb-stubs/idbInstallationInstructions.tsx +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -export const getIdbInstallationInstructions = (idbPath: string) => - `IDB is required to use Flipper with iOS devices. It can be installed from https://github.com/facebook/idb and configured in Flipper settings. You can also disable physical iOS device support in settings. Current setting: ${idbPath} isn't a valid IDB installation.`; diff --git a/desktop/doctor/src/fb-stubs/messages.tsx b/desktop/doctor/src/fb-stubs/messages.tsx new file mode 100644 index 000000000..77008f47d --- /dev/null +++ b/desktop/doctor/src/fb-stubs/messages.tsx @@ -0,0 +1,26 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +export const getIdbInstallationInstructions = ( + idbPath: string, +): {message: string; commands: {title: string; command: string}[]} => ({ + message: `IDB is required to use Flipper with iOS devices. It can be installed from https://github.com/facebook/idb and configured in Flipper settings. You can also disable physical iOS device support in settings. Current setting: ${idbPath} isn't a valid IDB installation.`, + commands: [], +}); + +export const installXcode = + 'Install Xcode from the App Store or download it from https://developer.apple.com'; + +export const installSDK = + 'You can install it using Xcode (https://developer.apple.com/xcode/). Once installed, restart flipper.'; + +export const installAndroidStudio = [ + 'Android Studio is not installed.', + 'Install Android Studio from https://developer.android.com/studio', +].join('\n'); diff --git a/desktop/doctor/src/index.tsx b/desktop/doctor/src/index.tsx index 22fb87da6..f6b7b6376 100644 --- a/desktop/doctor/src/index.tsx +++ b/desktop/doctor/src/index.tsx @@ -17,7 +17,12 @@ import * as fs from 'fs'; import * as path from 'path'; import type {FlipperDoctor} from 'flipper-common'; import * as fs_extra from 'fs-extra'; -import {getIdbInstallationInstructions} from './fb-stubs/idbInstallationInstructions'; +import { + getIdbInstallationInstructions, + installXcode, + installSDK, + installAndroidStudio, +} from './fb-stubs/messages'; import {validateSelectedXcodeVersion} from './fb-stubs/validateSelectedXcodeVersion'; export function getHealthchecks(): FlipperDoctor.Healthchecks { @@ -62,6 +67,29 @@ export function getHealthchecks(): FlipperDoctor.Healthchecks { isRequired: false, isSkipped: false, healthchecks: [ + ...(process.platform === 'darwin' + ? [ + { + key: 'android.android-studio', + label: 'Android Studio Installed', + isRequired: false, + run: async (_: FlipperDoctor.EnvironmentInfo) => { + const hasProblem = !fs.existsSync( + '/Applications/Android Studio.app', + ); + + const message = hasProblem + ? installAndroidStudio + : `Android Studio is installed.`; + + return { + hasProblem, + message, + }; + }, + }, + ] + : []), { key: 'android.sdk', label: 'SDK Installed', @@ -74,12 +102,12 @@ export function getHealthchecks(): FlipperDoctor.Healthchecks { if (!androidHome) { androidHomeResult = { hasProblem: true, - message: `ANDROID_HOME is not defined. You can use Flipper Settings (File > Preferences) to point to its location.`, + message: `ANDROID_HOME is not defined. You can use Flipper Settings (More > Settings) to point to its location.`, }; } else if (!fs.existsSync(androidHome)) { androidHomeResult = { hasProblem: true, - message: `ANDROID_HOME point to a folder which does not exist: ${androidHome}. You can use Flipper Settings (File > Preferences) to point to a different location.`, + message: `ANDROID_HOME point to a folder which does not exist: ${androidHome}. You can use Flipper Settings (More > Settings) to point to a different location.`, }; } else { const platformToolsDir = path.join(androidHome, 'platform-tools'); @@ -102,12 +130,12 @@ export function getHealthchecks(): FlipperDoctor.Healthchecks { if (!androidSdkRoot) { androidSdkRootResult = { hasProblem: true, - message: `ANDROID_SDK_ROOT is not defined. You can use Flipper Settings (File > Preferences) to point to its location.`, + message: `ANDROID_SDK_ROOT is not defined. You can use Flipper Settings (More > Settings) to point to its location.`, }; } else if (!fs.existsSync(androidSdkRoot)) { androidSdkRootResult = { hasProblem: true, - message: `ANDROID_SDK_ROOT point to a folder which does not exist: ${androidSdkRoot}. You can use Flipper Settings (File > Preferences) to point to a different location.`, + message: `ANDROID_SDK_ROOT point to a folder which does not exist: ${androidSdkRoot}. You can use Flipper Settings (More > Settings) to point to a different location.`, }; } else { const platformToolsDir = path.join( @@ -137,26 +165,6 @@ export function getHealthchecks(): FlipperDoctor.Healthchecks { isRequired: false, isSkipped: false, healthchecks: [ - { - key: 'ios.sdk', - label: 'SDK Installed', - isRequired: true, - run: async (e: FlipperDoctor.EnvironmentInfo) => { - const hasProblem = - !e.SDKs['iOS SDK'] || - !e.SDKs['iOS SDK'].Platforms || - !e.SDKs['iOS SDK'].Platforms.length; - const message = hasProblem - ? 'iOS SDK is not installed. You can install it using Xcode (https://developer.apple.com/xcode/).' - : `iOS SDK is installed for the following platforms: ${JSON.stringify( - e.SDKs['iOS SDK'].Platforms, - )}.`; - return { - hasProblem, - message, - }; - }, - }, { key: 'ios.xcode', label: 'XCode Installed', @@ -164,7 +172,7 @@ export function getHealthchecks(): FlipperDoctor.Healthchecks { run: async (e: FlipperDoctor.EnvironmentInfo) => { const hasProblem = e.IDEs == null || e.IDEs.Xcode == null; const message = hasProblem - ? 'Xcode (https://developer.apple.com/xcode/) is not installed.' + ? `Xcode is not installed.\n${installXcode}.` : `Xcode version ${e.IDEs.Xcode.version} is installed at "${e.IDEs.Xcode.path}".`; return { hasProblem, @@ -217,6 +225,26 @@ export function getHealthchecks(): FlipperDoctor.Healthchecks { }; }, }, + { + key: 'ios.sdk', + label: 'SDK Installed', + isRequired: true, + run: async (e: FlipperDoctor.EnvironmentInfo) => { + const hasProblem = + !e.SDKs['iOS SDK'] || + !e.SDKs['iOS SDK'].Platforms || + !e.SDKs['iOS SDK'].Platforms.length; + const message = hasProblem + ? `iOS SDK is not installed. ${installSDK}` + : `iOS SDK is installed for the following platforms: ${JSON.stringify( + e.SDKs['iOS SDK'].Platforms, + )}.`; + return { + hasProblem, + message, + }; + }, + }, { key: 'ios.xctrace', label: 'xctrace exists', @@ -260,13 +288,17 @@ export function getHealthchecks(): FlipperDoctor.Healthchecks { const result = await tryExecuteCommand( `${settings?.idbPath} --help`, ); - const hasProblem = result.hasProblem; - const message = hasProblem - ? getIdbInstallationInstructions(settings.idbPath) - : 'Flipper is configured to use your IDB installation.'; + if (result.hasProblem) { + return { + hasProblem: true, + ...getIdbInstallationInstructions(settings.idbPath), + }; + } + return { - hasProblem, - message, + hasProblem: false, + message: + 'Flipper is configured to use your IDB installation.', }; }, }, diff --git a/desktop/flipper-common/src/PluginDetails.tsx b/desktop/flipper-common/src/PluginDetails.tsx index c7a400e9c..ed8d88624 100644 --- a/desktop/flipper-common/src/PluginDetails.tsx +++ b/desktop/flipper-common/src/PluginDetails.tsx @@ -82,6 +82,7 @@ export type ActivatablePluginDetails = InstalledPluginDetails; // Describes plugin available for downloading. Until downloaded to the disk it is not available for activation in Flipper. export interface DownloadablePluginDetails extends ConcretePluginDetails { isActivatable: false; + buildId: string; downloadUrl: string; lastUpdated: Date; // Indicates whether plugin should be enabled by default for new users diff --git a/desktop/flipper-common/src/index.tsx b/desktop/flipper-common/src/index.tsx index 7925006b6..b89847fee 100644 --- a/desktop/flipper-common/src/index.tsx +++ b/desktop/flipper-common/src/index.tsx @@ -54,6 +54,7 @@ export { isConnectivityOrAuthError, isError, isAuthError, + FlipperServerDisconnectedError, getStringFromErrorLike, getErrorFromErrorLike, deserializeRemoteError, diff --git a/desktop/flipper-common/src/server-types.tsx b/desktop/flipper-common/src/server-types.tsx index cb285b123..64c04e6ef 100644 --- a/desktop/flipper-common/src/server-types.tsx +++ b/desktop/flipper-common/src/server-types.tsx @@ -168,6 +168,7 @@ export type FlipperServerEvents = { 'plugins-server-add-on-message': ExecuteMessage; 'download-file-update': DownloadFileUpdate; 'server-log': LoggerInfo; + 'browser-connection-created': {}; }; export type OS = @@ -287,6 +288,7 @@ export type FlipperServerCommands = { serial: string, appBundlePath: string, ) => Promise