From 4d7ddd445c5bbe443517d91e045b02d6bfb7213d Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 17 Nov 2022 14:18:09 -0800 Subject: [PATCH 01/58] build: allow packager override for PROJECT_ROOT (#35354) Summary: This allows folks with a monorepo setup for React Native to set a simple configuration on the "Bundle React Native code and images" phase. This is because the bundler was configured to look for node_modules in a specific place, but in a monorepo your node_modules may be at the root one layer lower than a default configuration. This same pattern of overriding this variable exists in the [react-native-xcode](https://github.com/facebook/react-native/blob/main/scripts/react-native-xcode.sh#L63) file. Fixes: https://github.com/facebook/react-native/issues/33636 - "Unable to resolve module index" ``` Error: Unable to resolve module ./index from /Volumes/Nexus/Projects/xxx/.: None of these files exist: * index(.native|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx) * index/index(.native|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx) ``` ## Changelog [General] [Added] - Add support for overriding `PROJECT_ROOT` during bundle steps for monorepos. Pull Request resolved: https://github.com/facebook/react-native/pull/35354 Test Plan: Working CI build via CircleCI. Reviewed By: cipolleschi Differential Revision: D41319439 Pulled By: ryancat fbshipit-source-id: 8516e54436b0a9d4b9df1efeee8e62c95d4d35b2 --- scripts/packager.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/packager.sh b/scripts/packager.sh index acb1581257863f..c149c751a55fee 100755 --- a/scripts/packager.sh +++ b/scripts/packager.sh @@ -8,14 +8,14 @@ THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd) REACT_NATIVE_ROOT="$THIS_DIR/.." # Application root directory - General use case: react-native is a dependency -PROJECT_ROOT="$THIS_DIR/../../.." +PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../.."} # check and assign NODE_BINARY env # shellcheck disable=SC1090 source "${THIS_DIR}/node-binary.sh" # When running react-native tests, react-native doesn't live in node_modules but in the PROJECT_ROOT -if [ ! -d "$PROJECT_ROOT/node_modules/react-native" ]; +if [ ! -d "$THIS_DIR/../../../node_modules/react-native" ]; then PROJECT_ROOT="$THIS_DIR/.." fi From 15656342a8401eb599090da7962928dd48d7d890 Mon Sep 17 00:00:00 2001 From: Alpha Date: Fri, 18 Nov 2022 04:06:32 -0800 Subject: [PATCH 02/58] Resolve android crash on display modal (#35380) Summary: From exception logging, found crashes due to `Attempt to invoke virtual method 'int android.view.ViewGroup.getChildCount()' on a null object reference`. Tracing through the stack, it appears the constructor for `ViewGroup` conditionally calls `initializeScrollbarsInternal()`, which in turn calls `getChildCount()`. However `ReactModalHostView` overrides `getChildCount()`, so `getChildCount()` is called before `ReactModalHostView` constructor completes, resulting in null reference when accessing `mHostView` from `getChildCount()`. ## Changelog [Android] [Fixed] - Fix crash on initialize modal Pull Request resolved: https://github.com/facebook/react-native/pull/35380 Test Plan: In the rn-tester project, display a modal. Reviewed By: javache, cipolleschi Differential Revision: D41392235 Pulled By: ryancat fbshipit-source-id: ce78e4d458ad41769e78139ea0a8a038384e830d --- .../com/facebook/react/views/modal/ReactModalHostView.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java index 82be75a4377fc9..b8046f5da76c21 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java @@ -120,7 +120,9 @@ public void addView(View child, int index) { @Override public int getChildCount() { - return mHostView.getChildCount(); + // This method may be called by the parent constructor + // before mHostView is initialized. + return mHostView == null ? 0 : mHostView.getChildCount(); } @Override From 55b1670aa6c34f31491ffeba05997f131aae31e7 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 18 Nov 2022 04:46:16 -0800 Subject: [PATCH 03/58] Void the Maven coordinates for react-native and hermes-engine (#35379) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35379 This diff moves the publishing coordinates from: ``` com.facebook.react:react-native com.facebook.react:hermes-engine ``` to ``` com.facebook.react:react-android com.facebook.react:hermes-android ``` I've picked those they are the most layout friendly when building from source, but we can discuss if we want others. I've updated the Gradle plugin to have a dependencySubstitution rule + update the template with those changes. It should now be possible to still use `implementation("com.facebook.react:react-native:+")` inside libraries on 0.71+ and RNGP will resolve dependencies correctly. Changelog: [Android] [Changed] - Void the Maven coordinates for react-native and hermes-engine Reviewed By: cipolleschi Differential Revision: D41380525 fbshipit-source-id: 91e059fa261acb89bee7ca0c79c30c3d856a2c80 --- ReactAndroid/build.gradle | 6 ++++-- ReactAndroid/hermes-engine/build.gradle | 13 +++++++++++++ .../facebook/react/utils/DependencyUtils.kt | 18 ++++++++++++++++-- .../react/utils/DependencyUtilsTest.kt | 4 ++-- scripts/release-utils.js | 6 +++--- scripts/test-manual-e2e.sh | 1 - template/android/app/build.gradle | 4 ++-- 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index b9be2a80de9252..d43535934995e3 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -616,11 +616,13 @@ apply plugin: "org.jetbrains.kotlin.android" apply from: "./publish.gradle" // We need to override the artifact ID as this project is called `ReactAndroid` but -// the maven coordinates are on `react-native`. +// the maven coordinates are on `react-android`. +// Please note that the original coordinates, `react-native`, have been voided +// as they caused https://github.com/facebook/react-native/issues/35210 publishing { publications { getByName("release") { - artifactId 'react-native' + artifactId 'react-android' } } } diff --git a/ReactAndroid/hermes-engine/build.gradle b/ReactAndroid/hermes-engine/build.gradle index 9ab86d50d1f601..760aaef0d57336 100644 --- a/ReactAndroid/hermes-engine/build.gradle +++ b/ReactAndroid/hermes-engine/build.gradle @@ -234,4 +234,17 @@ afterEvaluate { prepareHeadersForPrefab.dependsOn(buildHermes) } +/* Publishing Configuration */ apply from: "../publish.gradle" + +// We need to override the artifact ID as this project is called `hermes-engine` but +// the maven coordinates are on `hermes-android`. +// Please note that the original coordinates, `hermes-engine`, have been voided +// as they caused https://github.com/facebook/react-native/issues/35210 +publishing { + publications { + getByName("release") { + artifactId 'hermes-android' + } + } +} diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt index c96213eb2aa98e..d11199ed2cdcf4 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt @@ -35,9 +35,23 @@ internal object DependencyUtils { fun configureDependencies(project: Project, versionString: String) { if (versionString.isBlank()) return project.configurations.all { configuration -> + // Here we set a dependencySubstitution for both react-native and hermes-engine as those + // coordinates are voided due to https://github.com/facebook/react-native/issues/35210 + // This allows users to import libraries that are still using + // implementation("com.facebook.react:react-native:+") and resolve the right dependency. + configuration.resolutionStrategy.dependencySubstitution { + it.substitute(it.module("com.facebook.react:react-native")) + .using(it.module("com.facebook.react:react-android:${versionString}")) + .because( + "The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.") + it.substitute(it.module("com.facebook.react:hermes-engine")) + .using(it.module("com.facebook.react:hermes-android:${versionString}")) + .because( + "The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.") + } configuration.resolutionStrategy.force( - "com.facebook.react:react-native:${versionString}", - "com.facebook.react:hermes-engine:${versionString}", + "com.facebook.react:react-android:${versionString}", + "com.facebook.react:hermes-android:${versionString}", ) } } diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt index e73eeb7937fa51..4386e33233d36e 100644 --- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt @@ -177,8 +177,8 @@ class DependencyUtilsTest { configureDependencies(project, "1.2.3") val forcedModules = project.configurations.first().resolutionStrategy.forcedModules - assertTrue(forcedModules.any { it.toString() == "com.facebook.react:react-native:1.2.3" }) - assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-engine:1.2.3" }) + assertTrue(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" }) + assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" }) } @Test diff --git a/scripts/release-utils.js b/scripts/release-utils.js index 4f10f1551217ba..870ec0187edd47 100644 --- a/scripts/release-utils.js +++ b/scripts/release-utils.js @@ -30,19 +30,19 @@ function generateAndroidArtifacts(releaseVersion, tmpPublishingFolder) { '-debug-sources.jar', '-release-sources.jar', ].map(suffix => { - return `react-native-${releaseVersion}${suffix}`; + return `react-android-${releaseVersion}${suffix}`; }); artifacts.forEach(name => { if ( !test( '-e', - `/tmp/maven-local/com/facebook/react/react-native/${releaseVersion}/${name}`, + `/tmp/maven-local/com/facebook/react/react-android/${releaseVersion}/${name}`, ) ) { echo( `Failing as expected file: \n\ - /tmp/maven-local/com/facebook/react/react-native/${releaseVersion}/${name}\n\ + /tmp/maven-local/com/facebook/react/react-android/${releaseVersion}/${name}\n\ was not correctly generated.`, ); exit(1); diff --git a/scripts/test-manual-e2e.sh b/scripts/test-manual-e2e.sh index 22cd23221aea0c..7e08c8050f4445 100755 --- a/scripts/test-manual-e2e.sh +++ b/scripts/test-manual-e2e.sh @@ -141,7 +141,6 @@ init_template_app(){ info "Double checking the versions in package.json are correct:" grep "\"react-native\": \".*react-native-$PACKAGE_VERSION-$TIMESTAMP.tgz\"" "/tmp/${project_name}/package.json" || error "Incorrect version number in /tmp/${project_name}/package.json" - grep -E "com.facebook.react:react-native:\\+" "${project_name}/android/app/build.gradle" || error "Dependency in /tmp/${project_name}/android/app/build.gradle must be com.facebook.react:react-native:+" success "New sample project generated at /tmp/${project_name}" popd >/dev/null || exit diff --git a/template/android/app/build.gradle b/template/android/app/build.gradle index db242847621b2c..71195c76234a76 100644 --- a/template/android/app/build.gradle +++ b/template/android/app/build.gradle @@ -150,7 +150,7 @@ android { dependencies { // The version of react-native is set by the React Native Gradle Plugin - implementation("com.facebook.react:react-native") + implementation("com.facebook.react:react-android") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0") @@ -161,7 +161,7 @@ dependencies { debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") if (hermesEnabled.toBoolean()) { - implementation("com.facebook.react:hermes-engine") + implementation("com.facebook.react:hermes-android") } else { implementation jscFlavor } From 95c5e181adeec7b1399fdd807986cda1c81564cf Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 18 Nov 2022 04:46:16 -0800 Subject: [PATCH 04/58] Bump RNGP to 0.72.1 (#35389) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35389 As the title says, just bumping RNGP Changelog: [Internal] [Changed] - Bump RNGP to 0.72.1 Reviewed By: cipolleschi Differential Revision: D41398920 fbshipit-source-id: 39baadc54c604ababe7f558cc1c1291c08aae983 --- package.json | 2 +- packages/react-native-gradle-plugin/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 07ae77c2304211..efc43ed0877e67 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "pretty-format": "^26.5.2", "promise": "^8.3.0", "react-devtools-core": "^4.26.1", - "react-native-gradle-plugin": "^0.72.0", + "react-native-gradle-plugin": "^0.72.1", "react-refresh": "^0.4.0", "react-shallow-renderer": "^16.15.0", "regenerator-runtime": "^0.13.2", diff --git a/packages/react-native-gradle-plugin/package.json b/packages/react-native-gradle-plugin/package.json index aeff3bfcc02822..366753a6a394c8 100644 --- a/packages/react-native-gradle-plugin/package.json +++ b/packages/react-native-gradle-plugin/package.json @@ -1,6 +1,6 @@ { "name": "react-native-gradle-plugin", - "version": "0.72.0", + "version": "0.72.1", "description": "⚛️ Gradle Plugin for React Native", "homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin", "repository": { From 0ba1127c15182564ac25b41b55433ed8f9512a9c Mon Sep 17 00:00:00 2001 From: Pranav Yadav Date: Fri, 18 Nov 2022 05:58:04 -0800 Subject: [PATCH 05/58] untrack test reports generated by test libraries (reporters) (#35187) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: - Untrack Test Reports generated by test libraries (reporters E.g. `jest-junit`) - E.g. `/reports/junit/js-test-results.xml` report is generated; when we exec `yarn test-ci`, which is **_shouldn't_ be tracked** ### NOTE: Used `[skip ci]` to avoid wastage of compute resources �🌏 - Feel free to init tests manually if you find it necessary ## Changelog [GENERAL] [CHANGED] - Untrack Test Reports generated by test libraries (reporters E.g. `jest-junit`) Pull Request resolved: https://github.com/facebook/react-native/pull/35187 Test Plan: `yarn test-ci` ![image](https://user-images.githubusercontent.com/55224033/199709131-240d844c-a98a-419b-a370-cafe8e927de4.png) Reviewed By: cipolleschi Differential Revision: D40993282 Pulled By: sshic fbshipit-source-id: 3fe150d3e8bd45cec56b50f2dc071002412e475e --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index fadf52a7f1c187..fa41a5729c3b34 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,9 @@ package-lock.json /coverage /third-party +# Test Reports +/reports + # Root dir shouldn't have Xcode project /*.xcodeproj From c06323f46334ee720cc46d48405ce584de16163d Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Fri, 18 Nov 2022 07:22:01 -0800 Subject: [PATCH 06/58] fix: Patch AnimatedStyle to avoid discarding the initial style info (#35198) Summary: This PR patches `AnimatedStyle` to avoid discarding the initial style information which destroys the output of web-style compilers and breaks rendering, as requested on https://github.com/facebook/react-native/issues/34425. This uses a slightly modified version of a patch used by react-native-web https://github.com/necolas/react-native-web/commit/4c678d2912bddf30ad3d1f2c9a71f453d29427f0. ## Changelog [General] [Fixed] - Patch AnimatedStyle to avoid discarding the initial style info Pull Request resolved: https://github.com/facebook/react-native/pull/35198 Test Plan: Run `yarn jest Animated` and ensure CI is green ![image](https://user-images.githubusercontent.com/11707729/199869612-4f2302da-5791-492f-83a7-683305757c23.png) Reviewed By: necolas Differential Revision: D41379826 Pulled By: javache fbshipit-source-id: 7e16726828b98def14847ec3499ff93777a9cbfb --- .../Animated/__tests__/Animated-web-test.js | 198 ++++++++++++++++++ Libraries/Animated/nodes/AnimatedStyle.js | 48 ++++- 2 files changed, 238 insertions(+), 8 deletions(-) create mode 100644 Libraries/Animated/__tests__/Animated-web-test.js diff --git a/Libraries/Animated/__tests__/Animated-web-test.js b/Libraries/Animated/__tests__/Animated-web-test.js new file mode 100644 index 00000000000000..2fccade525c107 --- /dev/null +++ b/Libraries/Animated/__tests__/Animated-web-test.js @@ -0,0 +1,198 @@ +/** + * 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 + * @oncall react_native + */ + +const StyleSheet = require('../../StyleSheet/StyleSheet'); +let Animated = require('../Animated').default; +let AnimatedProps = require('../nodes/AnimatedProps').default; + +jest.mock('../../Utilities/Platform', () => { + return {OS: 'web'}; +}); + +describe('Animated tests', () => { + beforeEach(() => { + jest.resetModules(); + }); + + describe('Animated', () => { + it('works end to end', () => { + const anim = new Animated.Value(0); + const translateAnim = anim.interpolate({ + inputRange: [0, 1], + outputRange: [100, 200], + }); + + const callback = jest.fn(); + + const node = new AnimatedProps( + { + style: { + backgroundColor: 'red', + opacity: anim, + transform: [ + { + translate: [translateAnim, translateAnim], + }, + { + translateX: translateAnim, + }, + {scale: anim}, + ], + shadowOffset: { + width: anim, + height: anim, + }, + }, + }, + callback, + ); + + expect(node.__getValue()).toEqual({ + style: [ + { + backgroundColor: 'red', + opacity: anim, + shadowOffset: { + width: anim, + height: anim, + }, + transform: [ + {translate: [translateAnim, translateAnim]}, + {translateX: translateAnim}, + {scale: anim}, + ], + }, + { + opacity: 0, + transform: [{translate: [100, 100]}, {translateX: 100}, {scale: 0}], + shadowOffset: { + width: 0, + height: 0, + }, + }, + ], + }); + + expect(anim.__getChildren().length).toBe(0); + + node.__attach(); + + expect(anim.__getChildren().length).toBe(3); + + anim.setValue(0.5); + + expect(callback).toBeCalled(); + + expect(node.__getValue()).toEqual({ + style: [ + { + backgroundColor: 'red', + opacity: anim, + shadowOffset: { + width: anim, + height: anim, + }, + transform: [ + {translate: [translateAnim, translateAnim]}, + {translateX: translateAnim}, + {scale: anim}, + ], + }, + { + opacity: 0.5, + transform: [ + {translate: [150, 150]}, + {translateX: 150}, + {scale: 0.5}, + ], + shadowOffset: { + width: 0.5, + height: 0.5, + }, + }, + ], + }); + + node.__detach(); + expect(anim.__getChildren().length).toBe(0); + + anim.setValue(1); + expect(callback.mock.calls.length).toBe(1); + }); + + /** + * The behavior matters when the input style is a mix of values + * from StyleSheet.create and an inline style with an animation + */ + it('does not discard initial style', () => { + const value1 = new Animated.Value(1); + const scale = value1.interpolate({ + inputRange: [0, 1], + outputRange: [1, 2], + }); + const callback = jest.fn(); + const node = new AnimatedProps( + { + style: [ + styles.red, + { + transform: [ + { + scale, + }, + ], + }, + ], + }, + callback, + ); + + expect(node.__getValue()).toEqual({ + style: [ + [ + styles.red, + { + transform: [{scale}], + }, + ], + { + transform: [{scale: 2}], + }, + ], + }); + + node.__attach(); + expect(callback.mock.calls.length).toBe(0); + value1.setValue(0.5); + expect(callback.mock.calls.length).toBe(1); + expect(node.__getValue()).toEqual({ + style: [ + [ + styles.red, + { + transform: [{scale}], + }, + ], + { + transform: [{scale: 1.5}], + }, + ], + }); + + node.__detach(); + }); + }); +}); + +const styles = StyleSheet.create({ + red: { + backgroundColor: 'red', + }, +}); diff --git a/Libraries/Animated/nodes/AnimatedStyle.js b/Libraries/Animated/nodes/AnimatedStyle.js index 7cb11bb1b55679..31291968f16e15 100644 --- a/Libraries/Animated/nodes/AnimatedStyle.js +++ b/Libraries/Animated/nodes/AnimatedStyle.js @@ -13,24 +13,52 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; import flattenStyle from '../../StyleSheet/flattenStyle'; +import Platform from '../../Utilities/Platform'; import NativeAnimatedHelper from '../NativeAnimatedHelper'; import AnimatedNode from './AnimatedNode'; import AnimatedTransform from './AnimatedTransform'; import AnimatedWithChildren from './AnimatedWithChildren'; +function createAnimatedStyle(inputStyle: any): Object { + const style = flattenStyle(inputStyle); + const animatedStyles: any = {}; + for (const key in style) { + const value = style[key]; + if (key === 'transform') { + animatedStyles[key] = new AnimatedTransform(value); + } else if (value instanceof AnimatedNode) { + animatedStyles[key] = value; + } else if (value && !Array.isArray(value) && typeof value === 'object') { + animatedStyles[key] = createAnimatedStyle(value); + } + } + return animatedStyles; +} + +function createStyleWithAnimatedTransform(inputStyle: any): Object { + let style = flattenStyle(inputStyle) || ({}: {[string]: any}); + + if (style.transform) { + style = { + ...style, + transform: new AnimatedTransform(style.transform), + }; + } + return style; +} + export default class AnimatedStyle extends AnimatedWithChildren { + _inputStyle: any; _style: Object; constructor(style: any) { super(); - style = flattenStyle(style) || ({}: {[string]: any}); - if (style.transform) { - style = { - ...style, - transform: new AnimatedTransform(style.transform), - }; + if (Platform.OS === 'web') { + this._inputStyle = style; + this._style = createAnimatedStyle(style); + } else { + this._style = createStyleWithAnimatedTransform(style); } - this._style = style; } // Recursively get values for nested styles (like iOS's shadowOffset) @@ -50,7 +78,11 @@ export default class AnimatedStyle extends AnimatedWithChildren { return updatedStyle; } - __getValue(): Object { + __getValue(): Object | Array { + if (Platform.OS === 'web') { + return [this._inputStyle, this._walkStyleAndGetValues(this._style)]; + } + return this._walkStyleAndGetValues(this._style); } From 88d1825c734e83c092b60380ecfd284c43e7b3fe Mon Sep 17 00:00:00 2001 From: Richard Howell Date: Fri, 18 Nov 2022 08:23:55 -0800 Subject: [PATCH 07/58] remove -weak_framework (#89233) Summary: X-link: https://github.com/pytorch/pytorch/pull/89233 The `-weak_framework` flag is no longer necessary, Buck will weakly link frameworks depending on the `target_sdk_version` of the binary being linked. Reviewed By: ebgraham, malfet Differential Revision: D41348639 fbshipit-source-id: 47992282ba030294b2304c550d49df13e24e9c79 --- BUCK | 7 +------ React/CoreModules/BUCK | 8 ++------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/BUCK b/BUCK index e998e2d09e5a88..f900a2be0e0e42 100644 --- a/BUCK +++ b/BUCK @@ -406,12 +406,6 @@ rn_apple_xplat_cxx_library( "-Wno-global-constructors", ], contacts = ["oncall+react_native@xmail.facebook.com"], - exported_linker_flags = [ - "-weak_framework", - "UserNotifications", - "-weak_framework", - "WebKit", - ], exported_preprocessor_flags = rn_extra_build_flags(), fbobjc_enable_exceptions = True, frameworks = [ @@ -426,6 +420,7 @@ rn_apple_xplat_cxx_library( "$SDKROOT/System/Library/Frameworks/SystemConfiguration.framework", "$SDKROOT/System/Library/Frameworks/UIKit.framework", "$SDKROOT/System/Library/Frameworks/UserNotifications.framework", + "$SDKROOT/System/Library/Frameworks/WebKit.framework", ], labels = [ "depslint_never_add", diff --git a/React/CoreModules/BUCK b/React/CoreModules/BUCK index 9820c22ed4b943..dec99e70172ec9 100644 --- a/React/CoreModules/BUCK +++ b/React/CoreModules/BUCK @@ -22,17 +22,13 @@ rn_apple_library( ], contacts = ["oncall+react_native@xmail.facebook.com"], enable_exceptions = True, - exported_linker_flags = [ - "-weak_framework", - "UserNotifications", - "-weak_framework", - "WebKit", - ], exported_preprocessor_flags = rn_extra_build_flags(), extension_api_only = True, frameworks = [ "Foundation", "UIKit", + "UserNotifications", + "WebKit", ], header_path_prefix = "React", labels = [ From 56e724fd88560242f4c9a75c91d62add653dbb2f Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 18 Nov 2022 10:24:15 -0800 Subject: [PATCH 08/58] Fix `react-native-oss-ios-xxx` Summary: Regenerating pods to fix the outage allow-large-files ## Changelog [internal] - Regenerating pods to fix the outage Reviewed By: blakef Differential Revision: D41402573 fbshipit-source-id: 6a378705e48db99ef04405c50098b239e1a73045 --- packages/rn-tester/Podfile.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index d6bfa85c149f95..8f2ba52f782abf 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -124,18 +124,18 @@ PODS: - React-RCTVibration (= 1000.0.0) - React-callinvoker (1000.0.0) - React-Codegen (1000.0.0): - - FBReactNativeSpec (= 1000.0.0) - - hermes-engine (= 1000.0.0) - - RCT-Folly (= 2021.07.22.00) - - RCTRequired (= 1000.0.0) - - RCTTypeSafety (= 1000.0.0) - - React-Core (= 1000.0.0) - - React-graphics (= 1000.0.0) - - React-jsi (= 1000.0.0) - - React-jsiexecutor (= 1000.0.0) - - React-rncore (= 1000.0.0) - - ReactCommon/turbomodule/bridging (= 1000.0.0) - - ReactCommon/turbomodule/core (= 1000.0.0) + - FBReactNativeSpec + - hermes-engine + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - React-graphics + - React-jsi + - React-jsiexecutor + - React-rncore + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core - React-Core (1000.0.0): - glog - RCT-Folly (= 2021.07.22.00) @@ -942,7 +942,7 @@ SPEC CHECKSUMS: CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: d68947eddece25638eb0f642d1b957c90388afd1 - FBReactNativeSpec: 9a029e7dec747a8836d785b3b7a433db5960504b + FBReactNativeSpec: 28f74ec52cc9615a6addb362d6ff0ff7d978a0b4 Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 @@ -954,7 +954,7 @@ SPEC CHECKSUMS: FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - hermes-engine: d344c89c3f4657f7031e5280e1b3dd531b425bfd + hermes-engine: eef898075e6242f0e6b71c6dae00630dd7a35b21 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 @@ -962,7 +962,7 @@ SPEC CHECKSUMS: RCTTypeSafety: a41e253b4ed644708899857d912b2f50c7b6214d React: 2fc6c4c656cccd6753016528ad41199c16fd558e React-callinvoker: a7d5e883a83bb9bd3985b08be832c5e76451d18f - React-Codegen: 4a022870a58b95e17da8f32641ba3d72b551f268 + React-Codegen: 4f1e911c128928e425e11698ad7859dfd0f92e20 React-Core: 719bec4b41c93b1affb1e2c3a43956ec482ecb9f React-CoreModules: feaa45c54c58e1420981f6dd544c8b3d01200caa React-cxxreact: c5f93e7a35f3545489d8e1f89beb9d2d56acfde5 @@ -996,6 +996,6 @@ SPEC CHECKSUMS: Yoga: 1b1a12ff3d86a10565ea7cbe057d42f5e5fb2a07 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 20298ecd3f30aa788ad491637e593ed0d8c100ca +PODFILE CHECKSUM: 5d1fc1e8809808c4384337ae55c5be2de48ffe4c COCOAPODS: 1.11.3 From ad0c8551c2b08acfc8f9983c31fc26513823ed3e Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Fri, 18 Nov 2022 11:51:39 -0800 Subject: [PATCH 09/58] remove all unnecessary imports to Geometry.h Summary: Changelog: [Internal] Reviewed By: stephinphection Differential Revision: D41366189 fbshipit-source-id: ea4ed1f0c759b5a05012425684bfb835dbe90904 --- .../ComponentViews/ScrollView/RCTScrollViewComponentView.mm | 1 - .../Mounting/ComponentViews/Text/RCTParagraphComponentView.mm | 1 - .../ComponentViews/TextInput/RCTTextInputComponentView.mm | 1 - React/Fabric/RCTConversions.h | 1 - .../react/renderer/attributedstring/ParagraphAttributes.h | 2 +- ReactCommon/react/renderer/attributedstring/conversions.h | 1 - .../renderer/components/inputaccessory/InputAccessoryState.h | 1 - .../react/renderer/components/modal/ModalHostViewState.h | 1 - .../renderer/components/scrollview/ScrollViewEventEmitter.h | 1 - ReactCommon/react/renderer/components/text/BaseTextProps.h | 1 - .../components/androidtextinput/AndroidTextInputProps.h | 1 - ReactCommon/react/renderer/components/view/ViewProps.h | 1 - .../react/renderer/components/view/YogaLayoutableShadowNode.h | 1 - ReactCommon/react/renderer/components/view/conversions.h | 1 - ReactCommon/react/renderer/core/LayoutContext.h | 1 - ReactCommon/react/renderer/core/LayoutableShadowNode.h | 1 - ReactCommon/react/renderer/core/propsConversions.h | 1 - .../textlayoutmanager/platform/ios/RCTTextLayoutManager.h | 1 - ReactCommon/react/renderer/uimanager/UIManager.cpp | 1 - 19 files changed, 1 insertion(+), 19 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 2ebbb0e82ac91e..8c95cdbc0b9e18 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -18,7 +18,6 @@ #import #import #import -#import #import "RCTConversions.h" #import "RCTEnhancedScrollView.h" diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm index 048d1b3dd9a25b..5903f966375d3a 100644 --- a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm @@ -14,7 +14,6 @@ #import #import #import -#import #import #import #import diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index c7c0f1d1a7937b..5aa7024c9743e2 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -8,7 +8,6 @@ #import "RCTTextInputComponentView.h" #import -#import #import #import diff --git a/React/Fabric/RCTConversions.h b/React/Fabric/RCTConversions.h index 58cbfeb466b64e..ca5cd623f46f44 100644 --- a/React/Fabric/RCTConversions.h +++ b/React/Fabric/RCTConversions.h @@ -11,7 +11,6 @@ #import #import #import -#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h b/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h index c71909b89ad15f..f5f87c6cf52050 100644 --- a/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h +++ b/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include namespace facebook { namespace react { diff --git a/ReactCommon/react/renderer/attributedstring/conversions.h b/ReactCommon/react/renderer/attributedstring/conversions.h index f768de8cd82d2f..b2b5ef848ea493 100644 --- a/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/ReactCommon/react/renderer/attributedstring/conversions.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/ReactCommon/react/renderer/components/inputaccessory/InputAccessoryState.h b/ReactCommon/react/renderer/components/inputaccessory/InputAccessoryState.h index b5817524093944..15843aa341e52d 100644 --- a/ReactCommon/react/renderer/components/inputaccessory/InputAccessoryState.h +++ b/ReactCommon/react/renderer/components/inputaccessory/InputAccessoryState.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include namespace facebook { diff --git a/ReactCommon/react/renderer/components/modal/ModalHostViewState.h b/ReactCommon/react/renderer/components/modal/ModalHostViewState.h index 2afe22358d135b..f25d1a5e88d476 100644 --- a/ReactCommon/react/renderer/components/modal/ModalHostViewState.h +++ b/ReactCommon/react/renderer/components/modal/ModalHostViewState.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #ifdef ANDROID diff --git a/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h b/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h index 39274ad2daaa6a..868441d5f97c1e 100644 --- a/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h +++ b/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h @@ -12,7 +12,6 @@ #include #include #include -#include namespace facebook { namespace react { diff --git a/ReactCommon/react/renderer/components/text/BaseTextProps.h b/ReactCommon/react/renderer/components/text/BaseTextProps.h index b2d4e0789f8bf9..82369e28069f27 100644 --- a/ReactCommon/react/renderer/components/text/BaseTextProps.h +++ b/ReactCommon/react/renderer/components/text/BaseTextProps.h @@ -11,7 +11,6 @@ #include #include #include -#include namespace facebook { namespace react { diff --git a/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.h b/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.h index 33b34adff99198..7652984ce15e86 100644 --- a/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.h +++ b/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.h @@ -12,7 +12,6 @@ // #include #include #include -#include #include #include diff --git a/ReactCommon/react/renderer/components/view/ViewProps.h b/ReactCommon/react/renderer/components/view/ViewProps.h index ea08ea8defb82f..dbdc48934b97fb 100644 --- a/ReactCommon/react/renderer/components/view/ViewProps.h +++ b/ReactCommon/react/renderer/components/view/ViewProps.h @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h b/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h index 84e985e3853ca9..f836f1504e36ed 100644 --- a/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h +++ b/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h @@ -18,7 +18,6 @@ #include #include #include -#include namespace facebook { namespace react { diff --git a/ReactCommon/react/renderer/components/view/conversions.h b/ReactCommon/react/renderer/components/view/conversions.h index 8a8a30295e51e2..1fa108b5fb5775 100644 --- a/ReactCommon/react/renderer/components/view/conversions.h +++ b/ReactCommon/react/renderer/components/view/conversions.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/ReactCommon/react/renderer/core/LayoutContext.h b/ReactCommon/react/renderer/core/LayoutContext.h index f2a4ae55e7e7d4..04d6b298028744 100644 --- a/ReactCommon/react/renderer/core/LayoutContext.h +++ b/ReactCommon/react/renderer/core/LayoutContext.h @@ -10,7 +10,6 @@ #include #include -#include namespace facebook { namespace react { diff --git a/ReactCommon/react/renderer/core/LayoutableShadowNode.h b/ReactCommon/react/renderer/core/LayoutableShadowNode.h index 35dd55e7514543..e5b0fff4747484 100644 --- a/ReactCommon/react/renderer/core/LayoutableShadowNode.h +++ b/ReactCommon/react/renderer/core/LayoutableShadowNode.h @@ -18,7 +18,6 @@ #include #include #include -#include #include namespace facebook { diff --git a/ReactCommon/react/renderer/core/propsConversions.h b/ReactCommon/react/renderer/core/propsConversions.h index c4221f977567f9..269c64a4ad021f 100644 --- a/ReactCommon/react/renderer/core/propsConversions.h +++ b/ReactCommon/react/renderer/core/propsConversions.h @@ -14,7 +14,6 @@ #include #include #include -#include #include namespace facebook { diff --git a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextLayoutManager.h b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextLayoutManager.h index 15e4c755abc732..0c2dc67921eb95 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextLayoutManager.h +++ b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextLayoutManager.h @@ -10,7 +10,6 @@ #import #import #import -#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ReactCommon/react/renderer/uimanager/UIManager.cpp b/ReactCommon/react/renderer/uimanager/UIManager.cpp index 44692eeab2615d..32907b56a02217 100644 --- a/ReactCommon/react/renderer/uimanager/UIManager.cpp +++ b/ReactCommon/react/renderer/uimanager/UIManager.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include From 8b1f6e09c1b11e07096156d8d01aaff649745fbc Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Fri, 18 Nov 2022 12:46:10 -0800 Subject: [PATCH 10/58] Fix TouchableOpacity componentDidUpdate causing an excessive number of pending callbacks (#35387) Summary: The commit https://github.com/facebook/react-native/commit/3eddc9abb70eb54209c68aab7dbd69e363cc7b29 included on v0.69 introduced a wrong `if` statement inside the `componentDidUpdate` function of the `TouchableOpacity` component. As this `if` statement always evaluates to `true` (`(true || false) !== undefined`) we end up making unnecessary calls to the `_opacityInactive` method every time the component props changes, e.g. every time a `` inside the TouchableOpacity changes we call this function over and over, and this has been causing some performance issues on big lists. This PR fixes this problem by adjusting the `componentDidUpdate` function to only call `_opacityInactive` when necessary. Closes https://github.com/facebook/react-native/issues/34442 Closes https://github.com/facebook/react-native/issues/32476 ## Changelog [General] [Fixed] - Fix TouchableOpacity componentDidUpdate causing an excessive number of pending callbacks Pull Request resolved: https://github.com/facebook/react-native/pull/35387 Test Plan: 1. Open the RNTester app and navigate to the `Touchable* and onPress` page 2. Test the `TouchableOpacity` component through the many sections Reviewed By: cipolleschi Differential Revision: D41397396 Pulled By: ryancat fbshipit-source-id: 24863b5cbbdd2f3dd1f654b43d7031560937b888 --- Libraries/Components/Touchable/TouchableOpacity.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 2aef4e824f10a5..cc18e8ecd0db23 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -301,9 +301,8 @@ class TouchableOpacity extends React.Component { this.state.pressability.configure(this._createPressabilityConfig()); if ( this.props.disabled !== prevProps.disabled || - (flattenStyle(prevProps.style)?.opacity !== - flattenStyle(this.props.style)?.opacity) !== - undefined + flattenStyle(prevProps.style)?.opacity !== + flattenStyle(this.props.style)?.opacity ) { this._opacityInactive(250); } From 81e441ae8a7daed79d8804c72e1991b29f670411 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Fri, 18 Nov 2022 15:56:58 -0800 Subject: [PATCH 11/58] fix(template): reference App.tsx vs App.js in template text (#35377) Summary: The template has moved to typescript now, the self-reference needed an update ## Changelog [GENERAL] [FIXED] - reference App.tsx vs App.js in text of new typescript template Pull Request resolved: https://github.com/facebook/react-native/pull/35377 Test Plan: It is just a text change - it either makes sense or it doesn't. I think it makes sense? Reviewed By: cipolleschi Differential Revision: D41386912 Pulled By: NickGerleman fbshipit-source-id: 6e62c11567e8fbff70b123446a827b18af43e864 --- template/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/App.tsx b/template/App.tsx index 71991406fe1fe9..bf24c33164b8e9 100644 --- a/template/App.tsx +++ b/template/App.tsx @@ -77,7 +77,7 @@ function App(): JSX.Element { backgroundColor: isDarkMode ? Colors.black : Colors.white, }}>
- Edit App.js to change this + Edit App.tsx to change this screen and then come back to see your edits.
From 27e7295ca76111c00bcf83327b0a151f21c23743 Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Mon, 21 Nov 2022 03:06:15 -0800 Subject: [PATCH 12/58] Abort pod install if bad HERMES_ENGINE_TARBALL_PATH is set Summary: Changelog: [iOS][Changed] - Abort pod install if bad HERMES_ENGINE_TARBALL_PATH is set. Reviewed By: cipolleschi Differential Revision: D41341471 fbshipit-source-id: 34a3ac154b0a3f795d07dcd10f92361cb9bb4ad6 --- sdks/hermes-engine/hermes-engine.podspec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sdks/hermes-engine/hermes-engine.podspec b/sdks/hermes-engine/hermes-engine.podspec index 8ce5017049f906..47973a6f7f4943 100644 --- a/sdks/hermes-engine/hermes-engine.podspec +++ b/sdks/hermes-engine/hermes-engine.podspec @@ -26,7 +26,13 @@ isInMain = version.include?('1000.0.0') isNightly = version.start_with?('0.0.0-') if ENV.has_key?('HERMES_ENGINE_TARBALL_PATH') - Pod::UI.puts '[Hermes] Using pre-built Hermes binaries from local path.' if Object.const_defined?("Pod::UI") + if !File.exist?(ENV['HERMES_ENGINE_TARBALL_PATH']) + abort "[Hermes] HERMES_ENGINE_TARBALL_PATH is set, but points to a non-existing file: \"#{ENV['HERMES_ENGINE_TARBALL_PATH']}\"\nIf you don't want to use tarball, run `unset HERMES_ENGINE_TARBALL_PATH`" + end +end + +if ENV.has_key?('HERMES_ENGINE_TARBALL_PATH') + Pod::UI.puts "[Hermes] Using pre-built Hermes binaries from local path: #{ENV['HERMES_ENGINE_TARBALL_PATH']}".yellow if Object.const_defined?("Pod::UI") source[:http] = "file://#{ENV['HERMES_ENGINE_TARBALL_PATH']}" elsif isInMain Pod::UI.puts '[Hermes] Installing hermes-engine may take slightly longer, building Hermes compiler from source...'.yellow if Object.const_defined?("Pod::UI") From 25132c8490ca2d4a9e64ce26413a9a854187adca Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 21 Nov 2022 03:55:21 -0800 Subject: [PATCH 13/58] Fix: Avoid path in the template import (#35394) Summary: Investigating [this comment](https://github.com/reactwg/react-native-releases/discussions/41#discussioncomment-4170008), I made some tests. It seems like we can simply use `#import ` instead of the `#import ` in both setups: - default setup - `use_frameworks! :linkage => :static` ## Changelog [iOS] [Fixed] - Support `use_framework! :linkage => :static` in template Pull Request resolved: https://github.com/facebook/react-native/pull/35394 Test Plan: 1. Manually tested with a new app 2. CircleCI 3. Sandcastle Reviewed By: cortinico Differential Revision: D41402060 Pulled By: cipolleschi fbshipit-source-id: e1ed8196ed860b3663a88f5283f2745e39b0e944 --- template/ios/HelloWorld/AppDelegate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/ios/HelloWorld/AppDelegate.h b/template/ios/HelloWorld/AppDelegate.h index d04640c7a38180..5d2808256ca079 100644 --- a/template/ios/HelloWorld/AppDelegate.h +++ b/template/ios/HelloWorld/AppDelegate.h @@ -1,4 +1,4 @@ -#import +#import #import @interface AppDelegate : RCTAppDelegate From 8b319fd4887c41345dce999854f6b92e331c3b14 Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Mon, 21 Nov 2022 04:44:31 -0800 Subject: [PATCH 14/58] Do not run prepare_pods with js1 oss update-pods Summary: The order of following calls is irrelevant. ``` __update_pods_and_offline_mirrors "$JS_ENGINE_JSC" __update_pods_and_offline_mirrors "$JS_ENGINE_HERMES" ``` If execute `__update_pods_and_offline_mirrors "$JS_ENGINE_HERMES"` last, then `prepare_pods "$JS_ENGINE_HERMES"` is redundant. allow-large-files Changelog: [Internal][Changed] - Cleanup offline pod mirrors updating behaviour. Reviewed By: cipolleschi Differential Revision: D41346899 fbshipit-source-id: 694713330fb94561d872883a18f97869cd30cd26 --- packages/rn-tester/Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 8f2ba52f782abf..cf594d49707e18 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -954,7 +954,7 @@ SPEC CHECKSUMS: FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - hermes-engine: eef898075e6242f0e6b71c6dae00630dd7a35b21 + hermes-engine: d18f5a58d912c767ed56b58821bddd685d766712 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 From 138af74e3f2aa429eedc8881c8feb6d4a7b5c253 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 21 Nov 2022 05:21:39 -0800 Subject: [PATCH 15/58] Remove `HERMES_BUILD_FROM_SOURCE` flag (#35397) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35397 This Diff removes the `HERMES_BUILD_FROM_SOURCE` that was not always propagated to the original script. This lead to some cases where hermesC was built during `pod install` and then removed by the `react_native_post_install`'s `else` branch. Basically, when the Pods are installed the first time, everything run smoothly. Subsequent invocations of `pod install`, to install other dependencies, for example, will incur in this problem because: 1. Cocoapods will see that hermes-engine is already installed 2. the podspec is not executed, given that the pod has been fetched from the cache 3. The env var is not set (given that the podspec is not executed) 4. the main script sees the env var as not set, `ENV['HERMES_BUILD_FROM_SOURCE'] == "1"` return false 5. The `else` branch is executed, and it removes the `hermesc_build_dir` and the `copy Hermes framework` script phase. ## Changelog: [iOS][Changed] - Remove `HERMES_BUILD_FROM_SOURCE` flag Reviewed By: cortinico, dmytrorykun Differential Revision: D41373439 fbshipit-source-id: ea4aafd187c0ca3ff5c0d79f8aeaaa46ad50f499 --- scripts/cocoapods/__tests__/jsengine-test.rb | 18 ++++++++++++++++++ scripts/cocoapods/jsengine.rb | 12 ++++++++++++ scripts/react_native_pods.rb | 5 ++++- sdks/hermes-engine/hermes-engine.podspec | 3 +-- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/scripts/cocoapods/__tests__/jsengine-test.rb b/scripts/cocoapods/__tests__/jsengine-test.rb index 13ad540d5f25bf..303e99949dc9e0 100644 --- a/scripts/cocoapods/__tests__/jsengine-test.rb +++ b/scripts/cocoapods/__tests__/jsengine-test.rb @@ -19,6 +19,7 @@ def setup end def teardown + ENV['HERMES_ENGINE_TARBALL_PATH'] = nil Open3.reset() Pod::Config.reset() Pod::UI.reset() @@ -119,4 +120,21 @@ def test_setupHermes_installsPods_installsFabricSubspecWhenFabricEnabled assert_equal($podInvocation["React-hermes"][:path], "../../ReactCommon/hermes") assert_equal($podInvocation["libevent"][:version], "~> 2.1.12") end + + # ================================= # + # TEST - isBuildingHermesFromSource # + # ================================= # + def test_isBuildingHermesFromSource_whenTarballIsNilAndVersionIsNotNightly_returnTrue + assert_true(is_building_hermes_from_source("1000.0.0")) + end + + def test_isBuildingHermesFromSource_whenTarballIsNotNil_returnFalse + ENV['HERMES_ENGINE_TARBALL_PATH'] = "~/Downloads/hermes-ios-debug.tar.gz" + assert_false(is_building_hermes_from_source("1000.0.0")) + end + + def test_isBuildingHermesFromSource_whenIsNigthly_returnsFalse + assert_false(is_building_hermes_from_source("0.0.0-")) + end + end diff --git a/scripts/cocoapods/jsengine.rb b/scripts/cocoapods/jsengine.rb index 345972449d8802..73030a8062a75e 100644 --- a/scripts/cocoapods/jsengine.rb +++ b/scripts/cocoapods/jsengine.rb @@ -63,3 +63,15 @@ def remove_copy_hermes_framework_script_phase(installer, react_native_path) def remove_hermesc_build_dir(react_native_path) %x(rm -rf #{react_native_path}/sdks/hermes-engine/build_host_hermesc) end + +def is_building_hermes_from_source(react_native_version) + is_nightly = react_native_version.start_with?('0.0.0-') + has_tarball = ENV['HERMES_ENGINE_TARBALL_PATH'] != nil + + # this is the same logic in the hermes-engine.podspec + if has_tarball || is_nightly + return false + end + + return true +end diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index 074965bfbd63a6..910213464d0cce 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -202,7 +202,10 @@ def react_native_post_install(installer, react_native_path = "../node_modules/re flipper_post_install(installer) end - if ReactNativePodsUtils.has_pod(installer, 'hermes-engine') && ENV['HERMES_BUILD_FROM_SOURCE'] == "1" + package = JSON.parse(File.read(File.join(react_native_path, "package.json"))) + version = package['version'] + + if ReactNativePodsUtils.has_pod(installer, 'hermes-engine') && is_building_hermes_from_source(version) add_copy_hermes_framework_script_phase(installer, react_native_path) else remove_copy_hermes_framework_script_phase(installer, react_native_path) diff --git a/sdks/hermes-engine/hermes-engine.podspec b/sdks/hermes-engine/hermes-engine.podspec index 47973a6f7f4943..9f3b90bf77e8b3 100644 --- a/sdks/hermes-engine/hermes-engine.podspec +++ b/sdks/hermes-engine/hermes-engine.podspec @@ -86,8 +86,6 @@ Pod::Spec.new do |spec| elsif source[:git] then - ENV['HERMES_BUILD_FROM_SOURCE'] = "1" - spec.subspec 'Hermes' do |ss| ss.source_files = '' ss.public_header_files = 'API/hermes/*.h' @@ -114,6 +112,7 @@ Pod::Spec.new do |spec| # Keep hermesc_path synchronized with .gitignore entry. ENV['REACT_NATIVE_PATH'] = react_native_path hermesc_path = "${REACT_NATIVE_PATH}/sdks/hermes-engine/build_host_hermesc" + # NOTE: Prepare command is not run if the pod is not downloaded. spec.prepare_command = ". #{react_native_path}/sdks/hermes-engine/utils/build-hermesc-xcode.sh #{hermesc_path}" end From cb7f1b1f0b9d50ae8a923043d0ed77b2171bf59f Mon Sep 17 00:00:00 2001 From: David Angulo Date: Mon, 21 Nov 2022 05:59:19 -0800 Subject: [PATCH 16/58] Read `.ruby-version` file in `Gemfile` (#35410) Summary: When updating the Ruby version, 2 files are always needed to be updated (`.ruby-version` and `Gemfile`). When not in sync it can lead to an error like `Your Ruby version is 2.7.6, but your Gemfile specified 2.7.5`. This lessens the files that need to be updated when upgrading the Ruby version and makes it in sync always. It makes the `.ruby-version` the source of truth. ### Example 1: Screenshot 2022-11-20 at 13 56 08 When upgrading from `0.70.0` to `0.71.0-rc.0`. 2 files needs to be updated when it could have been just 1. Source: https://react-native-community.github.io/upgrade-helper/?from=0.70.0&to=0.71.0-rc.0 ### Example 2: 21c8837c1264cd96f5899e33132fa764bb9c2293 updates 4 files (`.ruby-version`, `Gemfile`, `template/Gemfile`, `template/_ruby-version`) when it could have been just 2. ### Other Sources: * https://andycroll.com/ruby/read-ruby-version-in-your-gemfile/ * https://render.com/docs/ruby-version (Heroku alternative) * https://stackoverflow.com/a/35823132/9375533 ## Changelog [General] [Changed] - Read `.ruby-version` file in `Gemfile` Pull Request resolved: https://github.com/facebook/react-native/pull/35410 Test Plan: Only `.ruby-version` and `template/_ruby-version` needs to be updated when upgrading Ruby version. Reviewed By: christophpurrer, cipolleschi Differential Revision: D41429147 Pulled By: rshest fbshipit-source-id: 9e541a1d84aed5dca1e6f465c61bb0ba15574211 --- Gemfile | 2 +- scripts/update-ruby.sh | 7 +------ template/Gemfile | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index b15113b7e057d4..567e59805c4a73 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version -ruby '2.7.6' +ruby File.read(File.join(__dir__, '.ruby-version')).strip gem 'cocoapods', '~> 1.11', '>= 1.11.3' diff --git a/scripts/update-ruby.sh b/scripts/update-ruby.sh index 20ab62ca9e9f02..2e8f39bb74be45 100755 --- a/scripts/update-ruby.sh +++ b/scripts/update-ruby.sh @@ -50,9 +50,6 @@ fi echo "$VERSION" > template/_ruby-version -sed_i -e "s/^\(ruby '\)[^']*\('.*\)$/\1$VERSION\2/" Gemfile -sed_i -e "s/^\(ruby '\)[^']*\('.*\)$/\1$VERSION\2/" template/Gemfile - rm -f Gemfile.lock export BUNDLE_APP_CONFIG="$ROOT/.bundle" @@ -67,10 +64,8 @@ export GIT_DISCOVERY_ACROSS_FILESYSTEM=0; if [ "$IS_GIT_REPO" = "true" ]; then git add \ .ruby-version \ - Gemfile \ Gemfile.lock \ - template/_ruby-version \ - template/Gemfile + template/_ruby-version else echo "Detected that you're not in Git. If on another SCM, don't forget to commit the edited files." fi diff --git a/template/Gemfile b/template/Gemfile index b15113b7e057d4..567e59805c4a73 100644 --- a/template/Gemfile +++ b/template/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version -ruby '2.7.6' +ruby File.read(File.join(__dir__, '.ruby-version')).strip gem 'cocoapods', '~> 1.11', '>= 1.11.3' From 5dd0f7327bf6ef1e2d559e6f65769dab3c84fb19 Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Mon, 21 Nov 2022 07:09:18 -0800 Subject: [PATCH 17/58] Various fixes for Hermes build-from-source behaviour Summary: Original title: **[RN] Do not encode path to cmake in hermes-engine Pod, build hermesc in prepare_pods** The result of `#{%x(command -v cmake | tr -d '\n')}` was being encoded into the `hermes-engine` Pod. This can lead to conflicts in the CocoaPods cache when `pod install` is run on different machines. Instead of running the command during `pod install`, we defer to the actual build scripts so they can find `cmake` when `$CMAKE_BINARY` is not set. More importantly, this fixes an issue that crept into the Sandcastle CocoaPods offline mirrors, but which would only manifest itself when people run `js1 oss prepare-pods`. RNTester would not build due to RNTesterPods.xcworkspace being configured to use cmake from an arbitrary path instead of using the cmake from $PATH. This does not affect Sandcastle due to `CMAKE_BINARY` getting overriden in Sandcastle. --- **Update** by dmytrorykun: It is impossible to address the problem described in the original title by simply adding `CMAKE_BINARY=${CMAKE_BINARY:-cmake}` to `build-hermes-xcode.sh`. This script is supposed to run from Xcode. Since Xcode doesn't have access to system `PATH` variable, it is unable to locate `cmake`, and build fails. However this diff contains other useful changes: 1. Remove trailing newline in `cmake` path in `build-hermes-xcode.sh`. 2. Fix inverted logic in `copy-hermes-xcode.sh`. 3. Fix typo in `remove xcuserdata` step in Sandcastle. 4. Remove unused `HERMES_DISABLE_HERMESC_BUILD`. Changelog: [iOS] [Fixed] - Various fixes for Hermes build-from-source behaviour. Reviewed By: cipolleschi Differential Revision: D41139384 fbshipit-source-id: 4a4a44a7ac201d279718d84cd02d60b4eaf3956b --- sdks/hermes-engine/utils/build-hermesc-xcode.sh | 2 +- sdks/hermes-engine/utils/copy-hermes-xcode.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdks/hermes-engine/utils/build-hermesc-xcode.sh b/sdks/hermes-engine/utils/build-hermesc-xcode.sh index 59de6a74e9a3f6..6b1ea9184d76c9 100755 --- a/sdks/hermes-engine/utils/build-hermesc-xcode.sh +++ b/sdks/hermes-engine/utils/build-hermesc-xcode.sh @@ -8,7 +8,7 @@ set -x hermesc_dir_path="$1" -CMAKE_BINARY=${CMAKE_BINARY:-cmake} +CMAKE_BINARY=${CMAKE_BINARY:-$(command -v cmake | tr -d '\n')} if ! "$CMAKE_BINARY" -S . -B "$hermesc_dir_path" then diff --git a/sdks/hermes-engine/utils/copy-hermes-xcode.sh b/sdks/hermes-engine/utils/copy-hermes-xcode.sh index 62cc99c064a72f..6768d4ecb28ed0 100755 --- a/sdks/hermes-engine/utils/copy-hermes-xcode.sh +++ b/sdks/hermes-engine/utils/copy-hermes-xcode.sh @@ -8,7 +8,7 @@ set -x source="${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/${PLATFORM_NAME}/hermes.framework" -if [[ ! -f "$source" ]]; then +if [[ -f "$source" ]]; then cp -R "$source" "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework" cp -R "$source" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" fi From 850f855eb67edfbf777b4bf89f8b6e8e884b853e Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 21 Nov 2022 07:12:56 -0800 Subject: [PATCH 18/58] chore: fail prepare package for release if tag exists (#35305) Summary: This PR makes sure that the `preapre_package_for_release` script fail fast if there is already a tag for the desired version on github. ## Changelog [General] [Added] - Make the `prepare_package_for_release` fail if there is already a git tag with that version Pull Request resolved: https://github.com/facebook/react-native/pull/35305 Test Plan: Tested manually. The script is currently only invoked during the release process. Screenshot 2022-11-10 at 12 24 03 Reviewed By: cortinico Differential Revision: D41403159 Pulled By: cipolleschi fbshipit-source-id: fb87df345b14568c750482e5c68be53551a9acbb --- scripts/bump-oss-version.js | 2 ++ scripts/prepare-package-for-release.js | 3 +++ scripts/release-utils.js | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/scripts/bump-oss-version.js b/scripts/bump-oss-version.js index ed14b1015270a0..b76f161ad874cd 100755 --- a/scripts/bump-oss-version.js +++ b/scripts/bump-oss-version.js @@ -21,6 +21,7 @@ const request = require('request'); const {getBranchName, exitIfNotOnGit} = require('./scm-utils'); const {parseVersion, isReleaseBranch} = require('./version-utils'); +const {failIfTagExists} = require('./release-utils'); let argv = yargs .option('r', { @@ -75,6 +76,7 @@ async function main() { ); const token = argv.token; const releaseVersion = argv.toVersion; + failIfTagExists(releaseVersion); const {pushed} = await inquirer.prompt({ type: 'confirm', diff --git a/scripts/prepare-package-for-release.js b/scripts/prepare-package-for-release.js index 4f89743c618827..2191e8eb026acb 100755 --- a/scripts/prepare-package-for-release.js +++ b/scripts/prepare-package-for-release.js @@ -21,6 +21,7 @@ const {echo, exec, exit} = require('shelljs'); const yargs = require('yargs'); const {isReleaseBranch, parseVersion} = require('./version-utils'); +const {failIfTagExists} = require('./release-utils'); const argv = yargs .option('r', { @@ -49,6 +50,8 @@ const releaseVersion = argv.toVersion; const isLatest = argv.latest; const isDryRun = argv.dryRun; +failIfTagExists(releaseVersion); + if (branch && !isReleaseBranch(branch) && !isDryRun) { console.error(`This needs to be on a release branch. On branch: ${branch}`); exit(1); diff --git a/scripts/release-utils.js b/scripts/release-utils.js index 870ec0187edd47..077096aa48fdec 100644 --- a/scripts/release-utils.js +++ b/scripts/release-utils.js @@ -117,8 +117,27 @@ function generateiOSArtifacts( return tarballOutputPath; } +function failIfTagExists(version) { + if (checkIfTagExists(version)) { + echo(`Tag v${version} already exists.`); + echo('You may want to rollback the last commit'); + echo('git reset --hard HEAD~1'); + exit(1); + } +} + +function checkIfTagExists(version) { + const {code, stdout} = exec('git tag -l', {silent: true}); + if (code !== 0) { + throw new Error('Failed to retrieve the list of tags'); + } + const tags = new Set(stdout.split('\n')); + return tags.has(`v${version}`); +} + module.exports = { generateAndroidArtifacts, generateiOSArtifacts, publishAndroidArtifactsToMaven, + failIfTagExists, }; From d9ade19b711fae03838581ff2564185d5b7a24cb Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 21 Nov 2022 09:09:23 -0800 Subject: [PATCH 19/58] Make links in LogBox tappable Summary: changelog: [General][Add] LogBox now makes URL links tappable. Logbox messages may contain URLs with more information about the given error. Right now, they are not tappable or copyable. So engineers need to resort to manually retype the link to browser. This diff tries to address that. Example of StrictMode error that has link in it. {F798509909} Reviewed By: yungsters Differential Revision: D41305784 fbshipit-source-id: 456a9faf34f8b9e443759dd6903ba67d0b9de73c --- Libraries/LogBox/UI/LogBoxMessage.js | 87 +++++++++- .../LogBox/UI/__tests__/LogBoxMessage-test.js | 69 ++++++-- .../__snapshots__/LogBoxMessage-test.js.snap | 161 ++++++++++++------ 3 files changed, 247 insertions(+), 70 deletions(-) diff --git a/Libraries/LogBox/UI/LogBoxMessage.js b/Libraries/LogBox/UI/LogBoxMessage.js index 02ecf3d37e6fe6..772c6680103557 100644 --- a/Libraries/LogBox/UI/LogBoxMessage.js +++ b/Libraries/LogBox/UI/LogBoxMessage.js @@ -11,6 +11,8 @@ import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; import type {Message} from '../Data/parseLogBoxLog'; +import Linking from '../../Linking/Linking'; +import StyleSheet from '../../StyleSheet/StyleSheet'; import Text from '../../Text/Text'; import * as React from 'react'; @@ -22,6 +24,81 @@ type Props = { ... }; +type Range = { + lowerBound: number, + upperBound: number, +}; + +function getLinkRanges(string: string): $ReadOnlyArray { + const regex = /https?:\/\/[^\s$.?#].[^\s]*/gi; + const matches = []; + + let regexResult: RegExp$matchResult | null; + while ((regexResult = regex.exec(string)) !== null) { + if (regexResult != null) { + matches.push({ + lowerBound: regexResult.index, + upperBound: regex.lastIndex, + }); + } + } + + return matches; +} + +function TappableLinks(props: { + content: string, + style: void | TextStyleProp, +}): React.Node { + const matches = getLinkRanges(props.content); + + if (matches.length === 0) { + // No URLs detected. Just return the content. + return {props.content}; + } + + // URLs were detected. Construct array of Text nodes. + + let fragments: Array = []; + let indexCounter = 0; + let startIndex = 0; + + for (const linkRange of matches) { + if (startIndex < linkRange.lowerBound) { + const text = props.content.substring(startIndex, linkRange.lowerBound); + fragments.push({text}); + } + + const link = props.content.substring( + linkRange.lowerBound, + linkRange.upperBound, + ); + fragments.push( + { + Linking.openURL(link); + }} + key={++indexCounter} + style={styles.linkText}> + {link} + , + ); + + startIndex = linkRange.upperBound; + } + + if (startIndex < props.content.length) { + const text = props.content.substring(startIndex); + fragments.push( + + {text} + , + ); + } + + return {fragments}; +} + const cleanContent = (content: string) => content.replace(/^(TransformError |Warning: (Warning: )?|Error: )/g, ''); @@ -49,9 +126,7 @@ function LogBoxMessage(props: Props): React.Node { if (length < maxLength) { elements.push( - - {cleanMessage} - , + , ); } @@ -87,4 +162,10 @@ function LogBoxMessage(props: Props): React.Node { return <>{elements}; } +const styles = StyleSheet.create({ + linkText: { + textDecorationLine: 'underline', + }, +}); + export default LogBoxMessage; diff --git a/Libraries/LogBox/UI/__tests__/LogBoxMessage-test.js b/Libraries/LogBox/UI/__tests__/LogBoxMessage-test.js index fba7dc725d9073..889593faa1afb5 100644 --- a/Libraries/LogBox/UI/__tests__/LogBoxMessage-test.js +++ b/Libraries/LogBox/UI/__tests__/LogBoxMessage-test.js @@ -17,7 +17,7 @@ const React = require('react'); describe('LogBoxMessage', () => { it('should render message', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render message truncated to 6 chars', () => { - const output = render.shallowRender( + const output = render.create( { it('should render the whole message when maxLength = message length', () => { const message = 'Some kind of message'; - const output = render.shallowRender( + const output = render.create( { }); it('should render message with substitution', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render message with substitution, truncating the first word 3 letters in', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render message with substitution, truncating the second word 6 letters in', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render message with substitution, truncating the third word 2 letters in', () => { - const output = render.shallowRender( + const output = render.create( { it('should render the whole message with substitutions when maxLength = message length', () => { const message = 'normal substitution normal'; - const output = render.shallowRender( + const output = render.create( { }); it('should render a plaintext message with no substitutions', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render a plaintext message and clean the content', () => { - const output = render.shallowRender( + const output = render.create( { }); it('Should strip "TransformError " without breaking substitution', () => { - const output = render.shallowRender( + const output = render.create( { }); it('Should strip "Warning: " without breaking substitution', () => { - const output = render.shallowRender( + const output = render.create( { }); it('Should strip "Warning: Warning: " without breaking substitution', () => { - const output = render.shallowRender( + const output = render.create( { expect(output).toMatchSnapshot(); }); + + it('Should make links tappable', () => { + const output = render.create( + , + ); + + expect(output).toMatchSnapshot(); + }); + + it('Should handle multiple links', () => { + const output = render.create( + , + ); + + expect(output).toMatchSnapshot(); + }); + + it('Should handle truncated links', () => { + const output = render.create( + , + ); + + expect(output).toMatchSnapshot(); + }); }); diff --git a/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxMessage-test.js.snap b/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxMessage-test.js.snap index 9f9260a0429072..ab09f2b290ab21 100644 --- a/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxMessage-test.js.snap +++ b/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxMessage-test.js.snap @@ -1,51 +1,112 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`LogBoxMessage Should handle multiple links 1`] = ` + + + http://reactnative.dev + + + and + + + http://reactjs.org + + +`; + +exports[`LogBoxMessage Should handle truncated links 1`] = ` + + + http://reactnative.dev + + + and http://r + + +`; + +exports[`LogBoxMessage Should make links tappable 1`] = ` + + + http://reactnative.dev + + +`; + exports[`LogBoxMessage Should strip "TransformError " without breaking substitution 1`] = ` - +Array [ normal - + , substitution - + , normal - - + , +] `; exports[`LogBoxMessage Should strip "Warning: " without breaking substitution 1`] = ` - +Array [ normal - + , substitution - + , normal - - + , +] `; exports[`LogBoxMessage Should strip "Warning: Warning: " without breaking substitution 1`] = ` - +Array [ normal - + , substitution - + , normal - - + , +] `; exports[`LogBoxMessage should render a plaintext message and clean the content 1`] = ` @@ -61,94 +122,86 @@ exports[`LogBoxMessage should render a plaintext message with no substitutions 1 `; exports[`LogBoxMessage should render message 1`] = ` - - - Some kind of message - - + + Some kind of message + `; exports[`LogBoxMessage should render message truncated to 6 chars 1`] = ` - - - Some - - + + Some + `; exports[`LogBoxMessage should render message with substitution 1`] = ` - +Array [ normal - + , substitution - + , normal - - + , +] `; exports[`LogBoxMessage should render message with substitution, truncating the first word 3 letters in 1`] = ` - - - nor - - + + nor + `; exports[`LogBoxMessage should render message with substitution, truncating the second word 6 letters in 1`] = ` - +Array [ normal - + , substi - - + , +] `; exports[`LogBoxMessage should render message with substitution, truncating the third word 2 letters in 1`] = ` - +Array [ normal - + , substitution - + , no - - + , +] `; exports[`LogBoxMessage should render the whole message when maxLength = message length 1`] = ` - - - Some kind of message - - + + Some kind of message + `; exports[`LogBoxMessage should render the whole message with substitutions when maxLength = message length 1`] = ` - +Array [ normal - + , substitution - + , normal - - + , +] `; From ef66856bae599a8371edce389b611b9e27a9bb89 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 21 Nov 2022 10:36:05 -0800 Subject: [PATCH 20/58] Fix packager liveness check broken on internal builds Summary: Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D41437735 fbshipit-source-id: 83dbea41512c196bfcb4b8b9e5d94847f2b11ce4 --- React/Base/RCTBundleURLProvider.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/React/Base/RCTBundleURLProvider.mm b/React/Base/RCTBundleURLProvider.mm index bee7394ee29f07..33a9ae8ae9c9a1 100644 --- a/React/Base/RCTBundleURLProvider.mm +++ b/React/Base/RCTBundleURLProvider.mm @@ -74,7 +74,7 @@ - (void)resetToDefaults (unsigned long)kRCTBundleURLProviderDefaultPort]]; } -#if RCT_DEV_MENU +#if RCT_DEV_MENU | RCT_PACKAGER_LOADING_FUNCTIONALITY + (BOOL)isPackagerRunning:(NSString *)hostPort { return [RCTBundleURLProvider isPackagerRunning:hostPort scheme:nil]; @@ -82,6 +82,10 @@ + (BOOL)isPackagerRunning:(NSString *)hostPort + (BOOL)isPackagerRunning:(NSString *)hostPort scheme:(NSString *)scheme { + if (!kRCTAllowPackagerAccess) { + return NO; + } + NSURL *url = [serverRootWithHostPort(hostPort, scheme) URLByAppendingPathComponent:@"status"]; NSURLSession *session = [NSURLSession sharedSession]; From f12b12c999fb36e66bcef242f7cf1f0751afedcd Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 21 Nov 2022 10:52:17 -0800 Subject: [PATCH 21/58] Improve version checks to avoid mistakes in the versioning (#35296) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35296 This change adds some version checks and enforces that every version matches some specific format based on the build type we are trying to run. ## Changelog [General][Changed] - Improve version checks Reviewed By: cortinico Differential Revision: D41161756 fbshipit-source-id: 4172195c5e031c1eaf7b33bb74f381c04e9adaf5 --- .circleci/config.yml | 11 +- scripts/__tests__/version-utils-test.js | 275 ++++++++++++++++++++++-- scripts/bump-oss-version.js | 2 +- scripts/prepare-package-for-release.js | 14 +- scripts/publish-npm.js | 15 +- scripts/set-rn-version.js | 46 ++-- scripts/test-e2e-local.js | 11 +- scripts/version-utils.js | 139 +++++++++++- 8 files changed, 455 insertions(+), 58 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea68661ca20478..12264e6fd30e7f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1363,7 +1363,14 @@ jobs: - run: name: "Set new react-native version and commit changes" command: | - node ./scripts/prepare-package-for-release.js -v << parameters.version >> -l << parameters.latest >> --dry-run << parameters.dryrun >> + VERSION=<< parameters.version >> + + if [[ -z "$VERSION" ]]; then + VERSION=$(grep '"version"' package.json | cut -d '"' -f 4 | head -1) + echo "Using the version from the package.json: $VERSION" + fi + + node ./scripts/prepare-package-for-release.js -v "$VERSION" -l << parameters.latest >> --dry-run << parameters.dryrun >> build_npm_package: parameters: @@ -1643,7 +1650,7 @@ workflows: jobs: - prepare_package_for_release: name: prepare_package_for_release - version: 'v1000.0.1' + version: '' latest : false dryrun: true - prepare_hermes_workspace: diff --git a/scripts/__tests__/version-utils-test.js b/scripts/__tests__/version-utils-test.js index 19450483399d06..0dd087e20b01ba 100644 --- a/scripts/__tests__/version-utils-test.js +++ b/scripts/__tests__/version-utils-test.js @@ -7,7 +7,11 @@ * @format */ -const {parseVersion, isReleaseBranch} = require('../version-utils'); +const { + parseVersion, + isReleaseBranch, + validateBuildType, +} = require('../version-utils'); let execResult = null; jest.mock('shelljs', () => ({ @@ -38,18 +42,53 @@ describe('version-utils', () => { }); describe('parseVersion', () => { - it('should throw error if invalid match', () => { + it('should throw error if buildType is undefined', () => { function testInvalidVersion() { - parseVersion(''); + parseVersion('v0.10.5'); + } + expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( + `"Unsupported build type: undefined"`, + ); + }); + + it('should throw error if buildType is not `release`, `dry-run` or `nightly`', () => { + function testInvalidVersion() { + parseVersion('v0.10.5', 'invalid_build_type'); + } + expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( + `"Unsupported build type: invalid_build_type"`, + ); + }); + it('should throw error if invalid match with release', () => { + function testInvalidVersion() { + parseVersion('', 'release'); + } + expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( + `"You must pass a correctly formatted version; couldn't parse "`, + ); + }); + it('should throw error if invalid match with dry-run', () => { + function testInvalidVersion() { + parseVersion('', 'dry-run'); + } + expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( + `"You must pass a correctly formatted version; couldn't parse "`, + ); + }); + it('should throw error if invalid match with nightly', () => { + function testInvalidVersion() { + parseVersion('', 'nightly'); } expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( `"You must pass a correctly formatted version; couldn't parse "`, ); }); - it('should parse pre-release version with .', () => { - const {version, major, minor, patch, prerelease} = - parseVersion('0.66.0-rc.4'); + it('should parse pre-release version with release and `.`', () => { + const {version, major, minor, patch, prerelease} = parseVersion( + '0.66.0-rc.4', + 'release', + ); expect(version).toBe('0.66.0-rc.4'); expect(major).toBe('0'); expect(minor).toBe('66'); @@ -57,9 +96,11 @@ describe('version-utils', () => { expect(prerelease).toBe('rc.4'); }); - it('should parse pre-release version with -', () => { - const {version, major, minor, patch, prerelease} = - parseVersion('0.66.0-rc-4'); + it('should parse pre-release version with release and `-`', () => { + const {version, major, minor, patch, prerelease} = parseVersion( + '0.66.0-rc-4', + 'release', + ); expect(version).toBe('0.66.0-rc-4'); expect(major).toBe('0'); expect(minor).toBe('66'); @@ -67,8 +108,20 @@ describe('version-utils', () => { expect(prerelease).toBe('rc-4'); }); + it('should reject pre-release version with random prerelease pattern', () => { + function testInvalidVersion() { + parseVersion('0.66.0-something_invalid', 'release'); + } + expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( + `"Version 0.66.0-something_invalid is not valid for Release"`, + ); + }); + it('should parse stable version', () => { - const {version, major, minor, patch, prerelease} = parseVersion('0.66.0'); + const {version, major, minor, patch, prerelease} = parseVersion( + '0.66.0', + 'release', + ); expect(version).toBe('0.66.0'); expect(major).toBe('0'); expect(minor).toBe('66'); @@ -77,18 +130,40 @@ describe('version-utils', () => { }); it('should parse pre-release version from tag', () => { - const {version, major, minor, patch, prerelease} = - parseVersion('v0.66.1-rc.4'); - expect(version).toBe('0.66.1-rc.4'); + const {version, major, minor, patch, prerelease} = parseVersion( + 'v0.66.0-rc.4', + 'release', + ); + expect(version).toBe('0.66.0-rc.4'); expect(major).toBe('0'); expect(minor).toBe('66'); - expect(patch).toBe('1'); + expect(patch).toBe('0'); expect(prerelease).toBe('rc.4'); }); + it('should reject pre-release version with patch != 0', () => { + function testInvalidVersion() { + parseVersion('0.66.3-rc.4', 'release'); + } + expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( + `"Version 0.66.3-rc.4 is not valid for Release"`, + ); + }); + + it('should reject pre-release version from tag with random prerelease pattern', () => { + function testInvalidVersion() { + parseVersion('v0.66.0-something_invalid', 'release'); + } + expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot( + `"Version 0.66.0-something_invalid is not valid for Release"`, + ); + }); + it('should parse stable version from tag', () => { - const {version, major, minor, patch, prerelease} = - parseVersion('v0.66.0'); + const {version, major, minor, patch, prerelease} = parseVersion( + 'v0.66.0', + 'release', + ); expect(version).toBe('0.66.0'); expect(major).toBe('0'); expect(minor).toBe('66'); @@ -96,23 +171,179 @@ describe('version-utils', () => { expect(prerelease).toBeUndefined(); }); - it('should parse nightly fake version', () => { - const {version, major, minor, patch, prerelease} = parseVersion('0.0.0'); - expect(version).toBe('0.0.0'); + it('should reject nightly with no prerelease', () => { + // this should fail + function testInvalidFunction() { + parseVersion('0.0.0', 'nightly'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 0.0.0 is not valid for nightlies"`, + ); + }); + + it('should reject nightly with prerelease but wrong version numbers', () => { + // this should fail + function testInvalidFunction() { + parseVersion('1.2.3-pre-release', 'nightly'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 1.2.3-pre-release is not valid for nightlies"`, + ); + }); + + it('should parse nightly with 0.0.0 and a prerelease part', () => { + // this should fail + const {version, major, minor, patch, prerelease} = parseVersion( + '0.0.0-pre-release', + 'nightly', + ); + + expect(version).toBe('0.0.0-pre-release'); expect(major).toBe('0'); expect(minor).toBe('0'); expect(patch).toBe('0'); + expect(prerelease).toBe('pre-release'); + }); + it('should parse dryrun with release version', () => { + const {version, major, minor, patch, prerelease} = parseVersion( + '0.7.3', + 'dry-run', + ); + expect(version).toBe('0.7.3'); + expect(major).toBe('0'); + expect(minor).toBe('7'); + expect(patch).toBe('3'); expect(prerelease).toBeUndefined(); }); - it('should parse dryrun fake version', () => { - const {version, major, minor, patch, prerelease} = - parseVersion('1000.0.0'); + it('should parse dryrun with prerelease . version', () => { + const {version, major, minor, patch, prerelease} = parseVersion( + '0.20.0-rc.0', + 'dry-run', + ); + expect(version).toBe('0.20.0-rc.0'); + expect(major).toBe('0'); + expect(minor).toBe('20'); + expect(patch).toBe('0'); + expect(prerelease).toBe('rc.0'); + }); + + it('should reject dryrun with prerelease . version with patch different from 0', () => { + function testInvalidFunction() { + parseVersion('0.20.3-rc.0', 'dry-run'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 0.20.3-rc.0 is not valid for dry-runs"`, + ); + }); + + it('should parse dryrun with prerelease - version', () => { + const {version, major, minor, patch, prerelease} = parseVersion( + '0.20.0-rc-0', + 'dry-run', + ); + expect(version).toBe('0.20.0-rc-0'); + expect(major).toBe('0'); + expect(minor).toBe('20'); + expect(patch).toBe('0'); + expect(prerelease).toBe('rc-0'); + }); + + it('should reject dryrun with prerelease - version with patch different from 0', () => { + function testInvalidFunction() { + parseVersion('0.20.3-rc-0', 'dry-run'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 0.20.3-rc-0 is not valid for dry-runs"`, + ); + }); + + it('should parse dryrun with main version', () => { + const {version, major, minor, patch, prerelease} = parseVersion( + '1000.0.0', + 'dry-run', + ); expect(version).toBe('1000.0.0'); expect(major).toBe('1000'); expect(minor).toBe('0'); expect(patch).toBe('0'); expect(prerelease).toBeUndefined(); }); + + it('should fail for dryrun with v1000.0.1 version', () => { + function testInvalidFunction() { + parseVersion('v1000.0.1', 'dry-run'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 1000.0.1 is not valid for dry-runs"`, + ); + }); + it('should parse dryrun with nightly version', () => { + const {version, major, minor, patch, prerelease} = parseVersion( + '0.0.0-something-else', + 'dry-run', + ); + expect(version).toBe('0.0.0-something-else'); + expect(major).toBe('0'); + expect(minor).toBe('0'); + expect(patch).toBe('0'); + expect(prerelease).toBe('something-else'); + }); + + it('should reject dryrun invalid values', () => { + function testInvalidFunction() { + parseVersion('1000.0.4', 'dry-run'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 1000.0.4 is not valid for dry-runs"`, + ); + }); + + it('should reject dryrun for invalid prerelease', () => { + function testInvalidFunction() { + parseVersion('0.6.4-something-else', 'dry-run'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 0.6.4-something-else is not valid for dry-runs"`, + ); + }); + + it('should reject dryrun for nightlies with invalid prerelease', () => { + function testInvalidFunction() { + parseVersion('0.0.0', 'dry-run'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Version 0.0.0 is not valid for dry-runs"`, + ); + }); + }); + + describe('Validate version', () => { + it('Throw error if the buildType is unknown', () => { + function testInvalidFunction() { + validateBuildType('wrong_build'); + } + expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot( + `"Unsupported build type: wrong_build"`, + ); + }); + it('Does not throw if the buildType is release', () => { + function testValidCall() { + validateBuildType('release'); + } + expect(testValidCall).not.toThrowError(); + }); + it('Does not throw if the buildType is nightly', () => { + function testValidCall() { + validateBuildType('nightly'); + } + expect(testValidCall).not.toThrowError(); + }); + it('Does not throw if the buildType is dry-run', () => { + function testValidCall() { + validateBuildType('dry-run'); + } + expect(testValidCall).not.toThrowError(); + }); }); }); diff --git a/scripts/bump-oss-version.js b/scripts/bump-oss-version.js index b76f161ad874cd..21bf2d71043ade 100755 --- a/scripts/bump-oss-version.js +++ b/scripts/bump-oss-version.js @@ -91,7 +91,7 @@ async function main() { } let latest = false; - const {version, prerelease} = parseVersion(releaseVersion); + const {version, prerelease} = parseVersion(releaseVersion, 'release'); if (!prerelease) { const {setLatest} = await inquirer.prompt({ type: 'confirm', diff --git a/scripts/prepare-package-for-release.js b/scripts/prepare-package-for-release.js index 2191e8eb026acb..05d72be149f5dd 100755 --- a/scripts/prepare-package-for-release.js +++ b/scripts/prepare-package-for-release.js @@ -60,13 +60,23 @@ if (branch && !isReleaseBranch(branch) && !isDryRun) { exit(1); } -const {version} = parseVersion(releaseVersion); +const buildType = isDryRun + ? 'dry-run' + : isReleaseBranch(branch) + ? 'release' + : 'nightly'; + +const {version} = parseVersion(releaseVersion, buildType); if (version == null) { console.error(`Invalid version provided: ${releaseVersion}`); exit(1); } -if (exec(`node scripts/set-rn-version.js --to-version ${version}`).code) { +if ( + exec( + `node scripts/set-rn-version.js --to-version ${version} --build-type ${buildType}`, + ).code +) { echo(`Failed to set React Native version to ${version}`); exit(1); } diff --git a/scripts/publish-npm.js b/scripts/publish-npm.js index 4f2939b47928fd..1ee22e34b3b54e 100755 --- a/scripts/publish-npm.js +++ b/scripts/publish-npm.js @@ -65,15 +65,22 @@ const argv = yargs default: false, }) .option('r', { - alias: 'release', // useless but needed for CI + alias: 'release', type: 'boolean', default: false, }) .strict().argv; const nightlyBuild = argv.nightly; const dryRunBuild = argv.dryRun; +const releaseBuild = argv.release; const isCommitly = nightlyBuild || dryRunBuild; +const buildType = releaseBuild + ? 'release' + : nightlyBuild + ? 'nightly' + : 'dry-run'; + if (!argv.help) { echo(`The temp publishing folder is ${tmpPublishingFolder}`); } @@ -97,7 +104,7 @@ let version, minor, prerelease = null; try { - ({version, major, minor, prerelease} = parseVersion(rawVersion)); + ({version, major, minor, prerelease} = parseVersion(rawVersion, buildType)); } catch (e) { echo(e.message); exit(1); @@ -122,7 +129,9 @@ if (dryRunBuild) { // For stable, pre-release releases, we rely on CircleCI job `prepare_package_for_release` to handle this if (isCommitly) { if ( - exec(`node scripts/set-rn-version.js --to-version ${releaseVersion}`).code + exec( + `node scripts/set-rn-version.js --to-version ${releaseVersion} --build-type ${buildType}`, + ).code ) { echo(`Failed to set version number to ${releaseVersion}`); exit(1); diff --git a/scripts/set-rn-version.js b/scripts/set-rn-version.js index 23705ed53fc194..44f9ae4764a47a 100755 --- a/scripts/set-rn-version.js +++ b/scripts/set-rn-version.js @@ -21,37 +21,41 @@ const os = require('os'); const path = require('path'); const {cat, echo, exec, exit, sed} = require('shelljs'); const yargs = require('yargs'); -const {parseVersion} = require('./version-utils'); +const {parseVersion, validateBuildType} = require('./version-utils'); const {saveFiles} = require('./scm-utils'); -const tmpVersioningFolder = fs.mkdtempSync( - path.join(os.tmpdir(), 'rn-set-version'), -); -echo(`The temp versioning folder is ${tmpVersioningFolder}`); - -let argv = yargs.option('v', { - alias: 'to-version', - type: 'string', -}).argv; - +let argv = yargs + .option('v', { + alias: 'to-version', + type: 'string', + required: true, + }) + .option('b', { + alias: 'build-type', + type: 'string', + required: true, + }).argv; + +const buildType = argv.buildType; const version = argv.toVersion; - -if (!version) { - echo('You must specify a version using -v'); - exit(1); -} +validateBuildType(buildType); let major, minor, patch, prerelease = -1; try { - ({major, minor, patch, prerelease} = parseVersion(version)); + ({major, minor, patch, prerelease} = parseVersion(version, buildType)); } catch (e) { echo(e.message); exit(1); } +const tmpVersioningFolder = fs.mkdtempSync( + path.join(os.tmpdir(), 'rn-set-version'), +); +echo(`The temp versioning folder is ${tmpVersioningFolder}`); + saveFiles(['package.json', 'template/package.json'], tmpVersioningFolder); fs.writeFileSync( @@ -161,13 +165,17 @@ const numberOfChangedLinesWithNewVersion = exec( ).stdout.trim(); if (+numberOfChangedLinesWithNewVersion !== filesToValidate.length) { + // TODO: the logic that checks whether all the changes have been applied + // is missing several files. For example, it is not checking Ruby version nor that + // the Objecive-C files, the codegen and other files are properly updated. + // We are going to work on this in another PR. + echo('WARNING:'); echo( `Failed to update all the files: [${filesToValidate.join( ', ', )}] must have versions in them`, ); - echo('Fix the issue and try again'); - exit(1); + echo(`These files already had version ${version} set.`); } exit(0); diff --git a/scripts/test-e2e-local.js b/scripts/test-e2e-local.js index b4c2175d4afea0..09b095d9ad59b0 100644 --- a/scripts/test-e2e-local.js +++ b/scripts/test-e2e-local.js @@ -21,6 +21,7 @@ const yargs = require('yargs'); const fs = require('fs'); const path = require('path'); const os = require('os'); +const {getBranchName} = require('./scm-utils'); const { launchAndroidEmulator, @@ -155,6 +156,12 @@ if (argv.target === 'RNTester') { // we need to add the unique timestamp to avoid npm/yarn to use some local caches const baseVersion = require('../package.json').version; + const branchName = getBranchName(); + const buildType = + branchName.endsWith('-stable') && baseVersion !== '1000.0.0' + ? 'release' + : 'dry-run'; + const dateIdentifier = new Date() .toISOString() .slice(0, -8) @@ -164,7 +171,9 @@ if (argv.target === 'RNTester') { const releaseVersion = `${baseVersion}-${dateIdentifier}`; // this is needed to generate the Android artifacts correctly - exec(`node scripts/set-rn-version.js --to-version ${releaseVersion}`).code; + exec( + `node scripts/set-rn-version.js --to-version ${releaseVersion} --build-type ${buildType}`, + ).code; // Generate native files for Android generateAndroidArtifacts(releaseVersion, tmpPublishingFolder); diff --git a/scripts/version-utils.js b/scripts/version-utils.js index daae4e7d60c923..e73ea62ed44249 100644 --- a/scripts/version-utils.js +++ b/scripts/version-utils.js @@ -9,21 +9,140 @@ const VERSION_REGEX = /^v?((\d+)\.(\d+)\.(\d+)(?:-(.+))?)$/; -function parseVersion(versionStr) { - const match = versionStr.match(VERSION_REGEX); - if (!match) { - throw new Error( - `You must pass a correctly formatted version; couldn't parse ${versionStr}`, - ); - } +/** + * Parses a version string and performs some checks to verify its validity. + * A valid version is in the format vX.Y.Z[-KKK] where X, Y, Z are numbers and KKK can be something else. + * The `builtType` is used to enforce that the major version can assume only specific + * values. + * + * Some examples of valid versions are: + * - stable: 0.68.1 + * - stable prerelease: 0.70.0-rc.0 + * - nightly: 0.0.0-20221116-2018-0bc4547fc + * - dryrun: 1000.0.0 + * + * Parameters: + * - @versionStr the string representing a version + * - @buildType the build type. It can be of values: `dry-run`, `release`, `nightly` + * + * Returns: an object with the shape: + * ``` + * { + * version: string, + * major: number, + * minor: number, + * patch: number, + * prerelease: string + * } + * ``` + * + */ +function parseVersion(versionStr, buildType) { + validateBuildType(buildType); + + const match = extractMatchIfValid(versionStr); const [, version, major, minor, patch, prerelease] = match; - return { + + const versionObject = { version, major, minor, patch, prerelease, }; + + validateVersion(versionObject, buildType); + + return versionObject; +} + +function validateBuildType(buildType) { + const validBuildTypes = new Set(['release', 'dry-run', 'nightly']); + if (!validBuildTypes.has(buildType)) { + throw new Error(`Unsupported build type: ${buildType}`); + } +} + +function extractMatchIfValid(versionStr) { + const match = versionStr.match(VERSION_REGEX); + if (!match) { + throw new Error( + `You must pass a correctly formatted version; couldn't parse ${versionStr}`, + ); + } + return match; +} + +function validateVersion(versionObject, buildType) { + const map = { + release: validateRelease, + 'dry-run': validateDryRun, + nightly: validateNightly, + }; + + const validationFunction = map[buildType]; + validationFunction(versionObject); +} + +/** + * Releases are in the form of 0.Y.Z[-RC.0] + */ +function validateRelease(version) { + const validRelease = isStableRelease(version) || isStablePrerelease(version); + if (!validRelease) { + throw new Error(`Version ${version.version} is not valid for Release`); + } +} + +function validateDryRun(version) { + const isNightly = isNightlyBuild(version) && version.prerelease != null; + + if ( + !isMain(version) && + !isNightly && + !isStableRelease(version) && + !isStablePrerelease(version) + ) { + throw new Error(`Version ${version.version} is not valid for dry-runs`); + } +} + +function validateNightly(version) { + // a valid nightly is a prerelease + const isPrerelease = version.prerelease != null; + const isValidNightly = isNightlyBuild(version) && isPrerelease; + if (!isValidNightly) { + throw new Error(`Version ${version.version} is not valid for nightlies`); + } +} + +function isStableRelease(version) { + return ( + version.major === '0' && version.minor !== '0' && version.prerelease == null + ); +} + +function isStablePrerelease(version) { + return ( + version.major === '0' && + version.minor !== '0' && + version.patch === '0' && + version.prerelease != null && + (version.prerelease.startsWith('rc.') || + version.prerelease.startsWith('rc-')) + ); +} + +function isNightlyBuild(version) { + return ( + version.major === '0' && version.minor === '0' && version.patch === '0' + ); +} + +function isMain(version) { + return ( + version.major === '1000' && version.minor === '0' && version.patch === '0' + ); } function isReleaseBranch(branch) { @@ -31,6 +150,10 @@ function isReleaseBranch(branch) { } module.exports = { + validateBuildType, parseVersion, isReleaseBranch, + isMain, + isStableRelease, + isStablePrerelease, }; From 6c315de2260318134ebfbe84aac65ae08085c198 Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Mon, 21 Nov 2022 11:17:01 -0800 Subject: [PATCH 22/58] Add butter/function.h (#35385) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35385 In OpenSource builds folly:: types are not always easy to consume. With butter:: we actually allow consumers to opt-into other/non folly:: types (by providing a custom butter:: implementation). This change adds a butter::function for that purpose. It is especially useful for react-native-windows which prefers Mso::Functor over folly::Function. You can use it by setting those compiler flags: -DBUTTER_FUNCTION_OVERRIDE_INCLUDE= -DBUTTER_FUNCTION_OVERRIDE=Mso::Functor std::function is no option as it is not move-only and we can't wait till 2025 > https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0288r9.html Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D41388193 fbshipit-source-id: 56f58b9ddc602aa4b13000031d50de5228b4a16b --- ReactCommon/butter/function.h | 51 +++++++++++++++++++++++++++ ReactCommon/react/bridging/Base.h | 6 ++-- ReactCommon/react/bridging/Function.h | 18 ++++++---- 3 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 ReactCommon/butter/function.h diff --git a/ReactCommon/butter/function.h b/ReactCommon/butter/function.h new file mode 100644 index 00000000000000..724752498f8878 --- /dev/null +++ b/ReactCommon/butter/function.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +#pragma once + +#include + +#if ( \ + defined(BUTTER_FUNCTION_OVERRIDE_INCLUDE) && \ + defined(BUTTER_FUNCTION_OVERRIDE)) + +#include BUTTER_FUNCTION_OVERRIDE_INCLUDE + +#elif defined(BUTTER_USE_FOLLY_CONTAINERS) + +#include + +#else + +#include + +#endif + +namespace facebook { +namespace butter { + +#if ( \ + defined(BUTTER_FUNCTION_OVERRIDE_INCLUDE) && \ + defined(BUTTER_FUNCTION_OVERRIDE)) + +template +using function = BUTTER_FUNCTION_OVERRIDE; + +#elif defined(BUTTER_USE_FOLLY_CONTAINERS) + +template +using function = folly::Function; + +#else + +template +using function = std::function; + +#endif + +} // namespace butter +} // namespace facebook diff --git a/ReactCommon/react/bridging/Base.h b/ReactCommon/react/bridging/Base.h index 4a65364753aa79..4ff8ef3a8e4bb4 100644 --- a/ReactCommon/react/bridging/Base.h +++ b/ReactCommon/react/bridging/Base.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include @@ -36,12 +36,12 @@ struct function_wrapper; template struct function_wrapper { - using type = folly::Function; + using type = butter::function; }; template struct function_wrapper { - using type = folly::Function; + using type = butter::function; }; template diff --git a/ReactCommon/react/bridging/Function.h b/ReactCommon/react/bridging/Function.h index fdac94bb6fd3b1..a1d555acddaf9a 100644 --- a/ReactCommon/react/bridging/Function.h +++ b/ReactCommon/react/bridging/Function.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace facebook::react { @@ -154,8 +154,8 @@ struct Bridging> { }; template -struct Bridging> { - using Func = folly::Function; +struct Bridging> { + using Func = butter::function; using IndexSequence = std::index_sequence_for; static constexpr size_t kArgumentCount = sizeof...(Args); @@ -202,13 +202,17 @@ struct Bridging> { }; template -struct Bridging> - : Bridging> {}; +struct Bridging< + std::function, + std::enable_if_t, + butter::function>>> + : Bridging> {}; template -struct Bridging : Bridging> {}; +struct Bridging : Bridging> {}; template -struct Bridging : Bridging> {}; +struct Bridging : Bridging> {}; } // namespace facebook::react From 662b51fad2fb4c267da519c9122ab4d12dcfdaae Mon Sep 17 00:00:00 2001 From: Arushi Kesarwani Date: Mon, 21 Nov 2022 11:59:01 -0800 Subject: [PATCH 23/58] Adding Dev Loading controller without activity for VR (#35392) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35392 Changelog: [General][Added] - For supporting Dev Loading View across platforms, adding the DevLoadingViewController without an activity/context. Reviewed By: rshest Differential Revision: D40947239 fbshipit-source-id: de124b0a7ee39dc7da3c1c45972a6703eff2f0ef --- .../facebook/react/ReactInstanceManager.java | 7 ++++-- .../react/ReactInstanceManagerBuilder.java | 12 ++++++++- .../com/facebook/react/ReactNativeHost.java | 9 +++++++ .../devsupport/BridgeDevSupportManager.java | 7 ++++-- ... DefaultDevLoadingViewImplementation.java} | 9 ++++--- .../DefaultDevSupportManagerFactory.java | 11 +++++--- .../devsupport/DevSupportManagerBase.java | 25 +++++++++++-------- .../devsupport/DevSupportManagerFactory.java | 4 ++- 8 files changed, 62 insertions(+), 22 deletions(-) rename ReactAndroid/src/main/java/com/facebook/react/devsupport/{DevLoadingViewController.java => DefaultDevLoadingViewImplementation.java} (92%) diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 6e7a9af39bd1c6..554144a8a8913a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -82,6 +82,7 @@ import com.facebook.react.devsupport.DevSupportManagerFactory; import com.facebook.react.devsupport.ReactInstanceDevHelper; import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.PackagerStatusCallback; import com.facebook.react.devsupport.interfaces.RedBoxHandler; @@ -233,7 +234,8 @@ public static ReactInstanceManagerBuilder builder() { @Nullable JSIModulePackage jsiModulePackage, @Nullable Map customPackagerCommandHandlers, @Nullable ReactPackageTurboModuleManagerDelegate.Builder tmmDelegateBuilder, - @Nullable SurfaceDelegateFactory surfaceDelegateFactory) { + @Nullable SurfaceDelegateFactory surfaceDelegateFactory, + @Nullable DevLoadingViewManager devLoadingViewManager) { FLog.d(TAG, "ReactInstanceManager.ctor()"); initializeSoLoaderIfNecessary(applicationContext); @@ -261,7 +263,8 @@ public static ReactInstanceManagerBuilder builder() { devBundleDownloadListener, minNumShakes, customPackagerCommandHandlers, - surfaceDelegateFactory); + surfaceDelegateFactory, + devLoadingViewManager); Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); mBridgeIdleDebugListener = bridgeIdleDebugListener; mLifecycleState = initialLifecycleState; diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java index 68ac1ed63451e1..2715b01c75a87b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java @@ -28,6 +28,7 @@ import com.facebook.react.devsupport.DefaultDevSupportManagerFactory; import com.facebook.react.devsupport.DevSupportManagerFactory; import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.RedBoxHandler; import com.facebook.react.jscexecutor.JSCExecutor; @@ -67,6 +68,7 @@ public class ReactInstanceManagerBuilder { private @Nullable Map mCustomPackagerCommandHandlers; private @Nullable ReactPackageTurboModuleManagerDelegate.Builder mTMMDelegateBuilder; private @Nullable SurfaceDelegateFactory mSurfaceDelegateFactory; + private @Nullable DevLoadingViewManager mDevLoadingViewManager; private JSEngineResolutionAlgorithm jsEngineResolutionAlgorithm = null; /* package protected */ ReactInstanceManagerBuilder() {} @@ -216,6 +218,13 @@ public ReactInstanceManagerBuilder setSurfaceDelegateFactory( return this; } + /** Sets the Dev Loading View Manager. */ + public ReactInstanceManagerBuilder setDevLoadingViewManager( + @Nullable DevLoadingViewManager devLoadingViewManager) { + mDevLoadingViewManager = devLoadingViewManager; + return this; + } + /** * Sets the initial lifecycle state of the host. For example, if the host is already resumed at * creation time, we wouldn't expect an onResume call until we get an onPause call. @@ -337,7 +346,8 @@ public ReactInstanceManager build() { mJSIModulesPackage, mCustomPackagerCommandHandlers, mTMMDelegateBuilder, - mSurfaceDelegateFactory); + mSurfaceDelegateFactory, + mDevLoadingViewManager); } private JavaScriptExecutorFactory getDefaultJSExecutorFactory( diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactNativeHost.java b/ReactAndroid/src/main/java/com/facebook/react/ReactNativeHost.java index d030019b035373..11880869d94349 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactNativeHost.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactNativeHost.java @@ -18,6 +18,7 @@ import com.facebook.react.common.SurfaceDelegate; import com.facebook.react.common.SurfaceDelegateFactory; import com.facebook.react.devsupport.DevSupportManagerFactory; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.RedBoxHandler; import java.util.List; @@ -71,6 +72,7 @@ protected ReactInstanceManager createReactInstanceManager() { .setJSMainModulePath(getJSMainModuleName()) .setUseDeveloperSupport(getUseDeveloperSupport()) .setDevSupportManagerFactory(getDevSupportManagerFactory()) + .setDevLoadingViewManager(getDevLoadingViewManager()) .setRequireActivity(getShouldRequireActivity()) .setSurfaceDelegateFactory(getSurfaceDelegateFactory()) .setLazyViewManagersEnabled(getLazyViewManagersEnabled()) @@ -149,6 +151,13 @@ public SurfaceDelegateFactory getSurfaceDelegateFactory() { }; } + /** + * Get the {@link DevLoadingViewManager}. Override this to use a custom dev loading view manager + */ + protected @Nullable DevLoadingViewManager getDevLoadingViewManager() { + return null; + } + /** * Returns the name of the main module. Determines the URL used to fetch the JS bundle from Metro. * It is only used when dev support is enabled. This is the first file to be executed once the diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java index 205de052d7cefc..fdec95c5696193 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java @@ -25,6 +25,7 @@ import com.facebook.react.common.SurfaceDelegateFactory; import com.facebook.react.common.futures.SimpleSettableFuture; import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.DevOptionHandler; import com.facebook.react.devsupport.interfaces.DevSplitBundleCallback; import com.facebook.react.devsupport.interfaces.RedBoxHandler; @@ -74,7 +75,8 @@ public BridgeDevSupportManager( @Nullable DevBundleDownloadListener devBundleDownloadListener, int minNumShakes, @Nullable Map customPackagerCommandHandlers, - @Nullable SurfaceDelegateFactory surfaceDelegateFactory) { + @Nullable SurfaceDelegateFactory surfaceDelegateFactory, + @Nullable DevLoadingViewManager devLoadingViewManager) { super( applicationContext, reactInstanceManagerHelper, @@ -84,7 +86,8 @@ public BridgeDevSupportManager( devBundleDownloadListener, minNumShakes, customPackagerCommandHandlers, - surfaceDelegateFactory); + surfaceDelegateFactory, + devLoadingViewManager); if (getDevSettings().isStartSamplingProfilerOnInit()) { // Only start the profiler. If its already running, there is an error diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevLoadingViewController.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevLoadingViewImplementation.java similarity index 92% rename from ReactAndroid/src/main/java/com/facebook/react/devsupport/DevLoadingViewController.java rename to ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevLoadingViewImplementation.java index 95fafd3c5e2b65..ef203fbf125899 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevLoadingViewController.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevLoadingViewImplementation.java @@ -25,8 +25,11 @@ import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import java.util.Locale; -/** Controller to display loading messages on top of the screen. All methods are thread safe. */ -public class DevLoadingViewController implements DevLoadingViewManager { +/** + * Default implementation of Dev Loading View Manager to display loading messages on top of the + * screen. All methods are thread safe. + */ +public class DefaultDevLoadingViewImplementation implements DevLoadingViewManager { private static boolean sEnabled = true; private final ReactInstanceDevHelper mReactInstanceManagerHelper; private @Nullable TextView mDevLoadingView; @@ -36,7 +39,7 @@ public static void setDevLoadingEnabled(boolean enabled) { sEnabled = enabled; } - public DevLoadingViewController(ReactInstanceDevHelper reactInstanceManagerHelper) { + public DefaultDevLoadingViewImplementation(ReactInstanceDevHelper reactInstanceManagerHelper) { mReactInstanceManagerHelper = reactInstanceManagerHelper; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevSupportManagerFactory.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevSupportManagerFactory.java index a7bd81ad600ec9..0a9a2338ceb356 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevSupportManagerFactory.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevSupportManagerFactory.java @@ -11,6 +11,7 @@ import androidx.annotation.Nullable; import com.facebook.react.common.SurfaceDelegateFactory; import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.RedBoxHandler; import com.facebook.react.packagerconnection.RequestHandler; @@ -46,6 +47,7 @@ public DevSupportManager create( null, minNumShakes, null, + null, null); } @@ -59,7 +61,8 @@ public DevSupportManager create( @Nullable DevBundleDownloadListener devBundleDownloadListener, int minNumShakes, @Nullable Map customPackagerCommandHandlers, - @Nullable SurfaceDelegateFactory surfaceDelegateFactory) { + @Nullable SurfaceDelegateFactory surfaceDelegateFactory, + @Nullable DevLoadingViewManager devLoadingViewManager) { if (!enableOnCreate) { return new DisabledDevSupportManager(); } @@ -87,7 +90,8 @@ public DevSupportManager create( DevBundleDownloadListener.class, int.class, Map.class, - SurfaceDelegateFactory.class); + SurfaceDelegateFactory.class, + DevLoadingViewManager.class); return (DevSupportManager) constructor.newInstance( applicationContext, @@ -98,7 +102,8 @@ public DevSupportManager create( devBundleDownloadListener, minNumShakes, customPackagerCommandHandlers, - surfaceDelegateFactory); + surfaceDelegateFactory, + devLoadingViewManager); } catch (Exception e) { return new PerftestDevSupportManager(applicationContext); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java index 2bf304a6b1ea4c..c5ea09166e882d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java @@ -46,6 +46,7 @@ import com.facebook.react.devsupport.DevServerHelper.PackagerCommandListener; import com.facebook.react.devsupport.interfaces.BundleLoadCallback; import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.DevOptionHandler; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.ErrorCustomizer; @@ -95,7 +96,7 @@ public interface CallbackWithBundleLoader { private final File mJSBundleDownloadedFile; private final File mJSSplitBundlesDir; private final DefaultJSExceptionHandler mDefaultJSExceptionHandler; - private final DevLoadingViewController mDevLoadingViewController; + private final DevLoadingViewManager mDevLoadingViewManager; private @Nullable SurfaceDelegate mRedBoxSurfaceDelegate; private @Nullable AlertDialog mDevOptionsDialog; @@ -132,7 +133,8 @@ public DevSupportManagerBase( @Nullable DevBundleDownloadListener devBundleDownloadListener, int minNumShakes, @Nullable Map customPackagerCommandHandlers, - @Nullable SurfaceDelegateFactory surfaceDelegateFactory) { + @Nullable SurfaceDelegateFactory surfaceDelegateFactory, + @Nullable DevLoadingViewManager devLoadingViewManager) { mReactInstanceDevHelper = reactInstanceDevHelper; mApplicationContext = applicationContext; mJSAppBundleName = packagerPathForJSBundleName; @@ -206,7 +208,10 @@ public void onReceive(Context context, Intent intent) { setDevSupportEnabled(enableOnCreate); mRedBoxHandler = redBoxHandler; - mDevLoadingViewController = new DevLoadingViewController(reactInstanceDevHelper); + mDevLoadingViewManager = + devLoadingViewManager != null + ? devLoadingViewManager + : new DefaultDevLoadingViewImplementation(reactInstanceDevHelper); mSurfaceDelegateFactory = surfaceDelegateFactory; }; @@ -766,7 +771,7 @@ private void showDevLoadingViewForUrl(String bundleUrl) { } int port = parsedURL.getPort() != -1 ? parsedURL.getPort() : parsedURL.getDefaultPort(); - mDevLoadingViewController.showMessage( + mDevLoadingViewManager.showMessage( mApplicationContext.getString( R.string.catalyst_loading_from_url, parsedURL.getHost() + ":" + port)); mDevLoadingViewVisible = true; @@ -778,14 +783,14 @@ protected void showDevLoadingViewForRemoteJSEnabled() { return; } - mDevLoadingViewController.showMessage( + mDevLoadingViewManager.showMessage( mApplicationContext.getString(R.string.catalyst_debug_connecting)); mDevLoadingViewVisible = true; } @UiThread protected void hideDevLoadingView() { - mDevLoadingViewController.hide(); + mDevLoadingViewManager.hide(); mDevLoadingViewVisible = false; } @@ -827,7 +832,7 @@ public void run() { @Override public void onProgress( @Nullable String status, @Nullable Integer done, @Nullable Integer total) { - mDevLoadingViewController.updateProgress(status, done, total); + mDevLoadingViewManager.updateProgress(status, done, total); } @Override @@ -983,7 +988,7 @@ public void onProgress( @Nullable final String status, @Nullable final Integer done, @Nullable final Integer total) { - mDevLoadingViewController.updateProgress(status, done, total); + mDevLoadingViewManager.updateProgress(status, done, total); if (mBundleDownloadListener != null) { mBundleDownloadListener.onProgress(status, done, total); } @@ -1125,7 +1130,7 @@ private void reload() { // show the dev loading if it should be if (mDevLoadingViewVisible) { - mDevLoadingViewController.showMessage("Reloading..."); + mDevLoadingViewManager.showMessage("Reloading..."); } mDevServerHelper.openPackagerConnection( @@ -1206,7 +1211,7 @@ public void run() { hideDevOptionsDialog(); // hide loading view - mDevLoadingViewController.hide(); + mDevLoadingViewManager.hide(); mDevServerHelper.closePackagerConnection(); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java index 3b1c71dc75a986..fea7416c11c259 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java @@ -11,6 +11,7 @@ import androidx.annotation.Nullable; import com.facebook.react.common.SurfaceDelegateFactory; import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.RedBoxHandler; import com.facebook.react.packagerconnection.RequestHandler; @@ -26,5 +27,6 @@ DevSupportManager create( @Nullable DevBundleDownloadListener devBundleDownloadListener, int minNumShakes, @Nullable Map customPackagerCommandHandlers, - @Nullable SurfaceDelegateFactory surfaceDelegateFactory); + @Nullable SurfaceDelegateFactory surfaceDelegateFactory, + @Nullable DevLoadingViewManager devLoadingViewManager); } From 78e7311cd50e32ebe4404c986d7f29d35180b510 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 21 Nov 2022 12:27:24 -0800 Subject: [PATCH 24/58] Fix lints and clean up interfaces Summary: quick diff to fix lints and clean-up interfaces in com.facebook.react.uimanager changelog: [internal] internal Reviewed By: NickGerleman Differential Revision: D41382839 fbshipit-source-id: 7c28fb7b0120e13e6a601c96a58b144161f64d5f --- .../react/uimanager/IViewManagerWithChildren.java | 2 +- .../facebook/react/uimanager/events/RCTEventEmitter.java | 8 ++++---- .../facebook/react/uimanager/util/ReactFindViewUtil.java | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewManagerWithChildren.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewManagerWithChildren.java index 8b9ea09e14862a..f3946567645470 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewManagerWithChildren.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewManagerWithChildren.java @@ -16,5 +16,5 @@ public interface IViewManagerWithChildren { * of automatically laying out children without going through the ViewGroup's onLayout method. In * that case, onLayout for this View type must *not* call layout on its children. */ - public boolean needsCustomLayoutForChildren(); + boolean needsCustomLayoutForChildren(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTEventEmitter.java index 82e26d5f6a542f..49234af84d69ec 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTEventEmitter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTEventEmitter.java @@ -20,12 +20,12 @@ public interface RCTEventEmitter extends JavaScriptModule { /** * Deprecated in favor of RCTModernEventEmitter.receiveEvent. * - * @param targetTag - * @param eventName - * @param event + * @param targetReactTag react tag of the view that receives the event + * @param eventName name of event + * @param event event params */ @Deprecated - void receiveEvent(int targetTag, String eventName, @Nullable WritableMap event); + void receiveEvent(int targetReactTag, String eventName, @Nullable WritableMap event); /** * Receive and process touches diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java index c86e7319922776..18312c37107b1f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java @@ -43,11 +43,6 @@ public interface OnViewFoundListener { public interface OnMultipleViewsFoundListener { void onViewFound(View view, String nativeId); - /** - * Called when all teh views have been found - * - * @param map - */ } /** From c0a04816564f3d307733eb2d139d15bb44c9178c Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 21 Nov 2022 12:27:24 -0800 Subject: [PATCH 25/58] Introduce IViewGroupManager Summary: In this diff I'm introducing IViewGroupManager to extract methods required to add/remove views from a viewGroup This will be used by ViewManagers that require to add views but don't depend on ViewGroupmanager changelog: [internal] internal Reviewed By: javache Differential Revision: D41386920 fbshipit-source-id: a7d893d92d0f12766dcc71dfd1b22539c3b9687d --- .../react/uimanager/IViewGroupManager.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewGroupManager.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewGroupManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewGroupManager.java new file mode 100644 index 00000000000000..95b2531de41855 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/IViewGroupManager.java @@ -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. + */ + +package com.facebook.react.uimanager; + +import android.view.View; + +/** Interface providing children management API for view managers of classes extending ViewGroup. */ +public interface IViewGroupManager extends IViewManagerWithChildren { + + /** Adds a child view into the parent at the index specified as a parameter */ + void addView(T parent, View child, int index); + + /** @return child of the parent view at the index specified as a parameter. */ + View getChildAt(T parent, int index); + + /** Removes View from the parent View at the index specified as a parameter. */ + void removeViewAt(T parent, int index); + + /** Return the amount of children contained by the view specified as a parameter. */ + int getChildCount(T parent); +} From 2f06b2663446d5eea4838988c0d9700261729894 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 21 Nov 2022 12:27:24 -0800 Subject: [PATCH 26/58] refactor ViewGroupManager to use IViewGroupManager Summary: In this diff I'm refactoring ViewGroupManager to implement IViewGroupManager This will be used by ViewManagers that require to add views but don't depend on ViewGroupmanager changelog: [internal] internal Reviewed By: javache Differential Revision: D41386918 fbshipit-source-id: 427b9689eb3408c2477cf38494d42280b41fd7d8 --- .../fabric/mounting/SurfaceMountingManager.java | 12 ++++++------ .../facebook/react/uimanager/ViewGroupManager.java | 6 +++++- .../react/views/view/ReactViewManagerWrapper.kt | 8 ++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java index 804a77ade78c1d..79f56f86ddd545 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java @@ -36,6 +36,7 @@ import com.facebook.react.fabric.mounting.mountitems.MountItem; import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.touch.JSResponderHandler; +import com.facebook.react.uimanager.IViewGroupManager; import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.uimanager.ReactOverflowViewWithInset; import com.facebook.react.uimanager.ReactRoot; @@ -44,7 +45,6 @@ import com.facebook.react.uimanager.RootViewManager; import com.facebook.react.uimanager.StateWrapper; import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManagerRegistry; import com.facebook.react.uimanager.events.EventCategoryDef; @@ -478,7 +478,7 @@ public void removeViewAt(final int tag, final int parentTag, int index) { logViewHierarchy(parentView, false); } - ViewGroupManager viewGroupManager = getViewGroupManager(parentViewState); + IViewGroupManager viewGroupManager = getViewGroupManager(parentViewState); // Verify that the view we're about to remove has the same tag we expect View view = viewGroupManager.getChildAt(parentView, index); @@ -639,7 +639,7 @@ public void removeDeleteTreeAt(final int tag, final int parentTag, int index) { logViewHierarchy(parentView, false); } - ViewGroupManager viewGroupManager = getViewGroupManager(parentViewState); + IViewGroupManager viewGroupManager = getViewGroupManager(parentViewState); // Verify that the view we're about to remove has the same tag we expect View view = viewGroupManager.getChildAt(parentView, index); @@ -979,7 +979,7 @@ public void updateLayout( } ViewState parentViewState = getViewState(parentTag); - ViewGroupManager parentViewManager = null; + IViewGroupManager parentViewManager = null; if (parentViewState.mViewManager != null) { parentViewManager = parentViewState.mViewManager.getViewGroupManager(); } @@ -1257,12 +1257,12 @@ public View getView(int reactTag) { } @SuppressWarnings("unchecked") // prevents unchecked conversion warn of the type - private static @NonNull ViewGroupManager getViewGroupManager( + private static @NonNull IViewGroupManager getViewGroupManager( @NonNull ViewState viewState) { if (viewState.mViewManager == null) { throw new IllegalStateException("Unable to find ViewManager for view: " + viewState); } - return (ViewGroupManager) viewState.mViewManager.getViewGroupManager(); + return (IViewGroupManager) viewState.mViewManager.getViewGroupManager(); } public void printSurfaceState() { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java index 86054051773bc0..caa82eb8d47541 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java @@ -16,7 +16,7 @@ /** Class providing children management API for view managers of classes extending ViewGroup. */ public abstract class ViewGroupManager - extends BaseViewManager implements IViewManagerWithChildren { + extends BaseViewManager implements IViewGroupManager { private static WeakHashMap mZIndexHash = new WeakHashMap<>(); @@ -33,6 +33,7 @@ public Class getShadowNodeClass() { @Override public void updateExtraData(T root, Object extraData) {} + @Override public void addView(T parent, View child, int index) { parent.addView(child, index); } @@ -60,14 +61,17 @@ public static void setViewZIndex(View view, int zIndex) { return mZIndexHash.get(view); } + @Override public int getChildCount(T parent) { return parent.getChildCount(); } + @Override public View getChildAt(T parent, int index) { return parent.getChildAt(index); } + @Override public void removeViewAt(T parent, int index) { UiThreadUtil.assertOnUiThread(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManagerWrapper.kt b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManagerWrapper.kt index ac9327e190a165..9b04d8cc7ed84d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManagerWrapper.kt +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManagerWrapper.kt @@ -10,10 +10,10 @@ package com.facebook.react.views.view import android.view.View import com.facebook.react.bridge.ReadableArray import com.facebook.react.touch.JSResponderHandler +import com.facebook.react.uimanager.IViewGroupManager import com.facebook.react.uimanager.ReactStylesDiffMap import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext -import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.ViewManager interface ReactViewManagerWrapper { @@ -41,7 +41,7 @@ interface ReactViewManagerWrapper { fun getName(): String - val viewGroupManager: ViewGroupManager<*> + val viewGroupManager: IViewGroupManager<*> class DefaultViewManager(private val viewManager: ViewManager) : ReactViewManagerWrapper { @@ -84,7 +84,7 @@ interface ReactViewManagerWrapper { override fun getName(): String = viewManager.name - override val viewGroupManager: ViewGroupManager<*> - get() = viewManager as ViewGroupManager<*> + override val viewGroupManager: IViewGroupManager<*> + get() = viewManager as IViewGroupManager<*> } } From 45a9b9f99221341e134dfa141876614459976b23 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 21 Nov 2022 12:27:24 -0800 Subject: [PATCH 27/58] Remove unused method Summary: Remove unused method changelog: [internal] intenral Reviewed By: makovkastar Differential Revision: D41386919 fbshipit-source-id: d0ce952ea5f52effb7791d3b97605ce9c4c65957 --- .../com/facebook/react/uimanager/ViewGroupManager.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java index caa82eb8d47541..12fca8747f38a6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java @@ -109,14 +109,4 @@ public void removeAllViews(T parent) { public boolean needsCustomLayoutForChildren() { return false; } - - /** - * Returns whether or not this View type should promote its grandchildren as Views. This is an - * optimization for Scrollable containers when using Nodes, where instead of having one ViewGroup - * containing a large number of draw commands (and thus being more expensive in the case of an - * invalidate or re-draw), we split them up into several draw commands. - */ - public boolean shouldPromoteGrandchildren() { - return false; - } } From a02bd0ded1d193e3fe6f0bfb961138e0f212fccc Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Mon, 21 Nov 2022 16:33:36 -0800 Subject: [PATCH 28/58] Add explicit defaulted copy ctor to `Values` (#1176) Summary: X-link: https://github.com/facebook/yoga/pull/1176 `Values` is a wrapper to story an array of YGValue's as CompactValues. From https://github.com/facebook/yoga/issues/1174 we see a warning `Wdeprecated-copy` beacuse a user-defined copy constructor is not present, but a user-defined asignment operator is (the defaulted one). This adds an explicitly defaulted copy contructor which should silence the warning I think. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D41447490 fbshipit-source-id: 8cc8f291cf12014d87cc71c4598bb84fdd6cd930 --- ReactCommon/yoga/yoga/Yoga-internal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReactCommon/yoga/yoga/Yoga-internal.h b/ReactCommon/yoga/yoga/Yoga-internal.h index 4e0efa6074dc17..9444bb5d1db768 100644 --- a/ReactCommon/yoga/yoga/Yoga-internal.h +++ b/ReactCommon/yoga/yoga/Yoga-internal.h @@ -110,6 +110,8 @@ class Values { public: Values() = default; + Values(const Values& other) = default; + explicit Values(const YGValue& defaultValue) noexcept { values_.fill(defaultValue); } From 285a98084e183d3719fb6cf5060266ee30c67453 Mon Sep 17 00:00:00 2001 From: Rujin Cao Date: Tue, 22 Nov 2022 01:36:05 -0800 Subject: [PATCH 29/58] @emails -> @oncall (miscs) Differential Revision: D41063745 fbshipit-source-id: 395ccd254c7410b96915156d59a584d3b255faa8 --- Libraries/Components/View/__tests__/View-test.js | 2 +- Libraries/Text/__tests__/Text-test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Components/View/__tests__/View-test.js b/Libraries/Components/View/__tests__/View-test.js index 78e547a673319e..66fac79f4ab4e2 100644 --- a/Libraries/Components/View/__tests__/View-test.js +++ b/Libraries/Components/View/__tests__/View-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Text/__tests__/Text-test.js b/Libraries/Text/__tests__/Text-test.js index ad565833a1f820..af02de98211cbe 100644 --- a/Libraries/Text/__tests__/Text-test.js +++ b/Libraries/Text/__tests__/Text-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; From cc311ff01ae2fd03b42d3adbfac9f41f5db5412c Mon Sep 17 00:00:00 2001 From: matiassalles99 Date: Tue, 22 Nov 2022 06:16:24 -0800 Subject: [PATCH 30/58] =?UTF-8?q?Extract=20the=20UnsupportedArrayElementTy?= =?UTF-8?q?peAnnotationParserError=20in=20its=20o=E2=80=A6=20(#35167)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This PR is part of https://github.com/facebook/react-native/issues/34872 This PR extracts the [UnsupportedArrayElementTypeAnnotationParserError](https://github.com/facebook/react-native/blob/main/packages/react-native-codegen/src/parsers/flow/modules/index.js#L132) in its own throwing function. ## Changelog [Internal] [Changed] - Extract the UnsupportedArrayElementTypeAnnotationParserError in its own throwing function Pull Request resolved: https://github.com/facebook/react-native/pull/35167 Test Plan: Screen Shot 2022-11-02 at 15 21 15 Reviewed By: cipolleschi Differential Revision: D41437971 Pulled By: rshest fbshipit-source-id: 14a6e09297d96f3b57568e0303e5cafff76e6f32 --- .../src/parsers/__tests__/error-utils-test.js | 57 ++++++++++++++++++ .../src/parsers/error-utils.js | 29 +++++++++ .../src/parsers/flow/modules/index.js | 48 ++++----------- .../src/parsers/typescript/modules/index.js | 59 ++++--------------- 4 files changed, 108 insertions(+), 85 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/__tests__/error-utils-test.js b/packages/react-native-codegen/src/parsers/__tests__/error-utils-test.js index ad40475d417a80..59facf536401d9 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/error-utils-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/error-utils-test.js @@ -23,6 +23,7 @@ const { throwIfModuleTypeIsUnsupported, throwIfUntypedModule, throwIfUnsupportedFunctionParamTypeAnnotationParserError, + throwIfArrayElementTypeAnnotationIsUnsupported, } = require('../error-utils'); const { UnsupportedModulePropertyParserError, @@ -637,3 +638,59 @@ describe('throwIfUnsupportedFunctionParamTypeAnnotationParserError', () => { }).toThrow(UnsupportedFunctionParamTypeAnnotationParserError); }); }); + +describe('throwIfArrayElementTypeAnnotationIsUnsupported', () => { + const { + UnsupportedArrayElementTypeAnnotationParserError, + } = require('../errors.js'); + const moduleName = 'moduleName'; + const language = 'Flow'; + + it('throws the error if it is the type is void type annotation', () => { + expect(() => { + throwIfArrayElementTypeAnnotationIsUnsupported( + moduleName, + undefined, + 'Array', + 'VoidTypeAnnotation', + language, + ); + }).toThrow(UnsupportedArrayElementTypeAnnotationParserError); + }); + + it('throws the error if it is the type is promise type annotation', () => { + expect(() => { + throwIfArrayElementTypeAnnotationIsUnsupported( + moduleName, + undefined, + 'Array', + 'PromiseTypeAnnotation', + language, + ); + }).toThrow(UnsupportedArrayElementTypeAnnotationParserError); + }); + + it('throws the error if it is the type is function type annotation', () => { + expect(() => { + throwIfArrayElementTypeAnnotationIsUnsupported( + moduleName, + undefined, + 'Array', + 'FunctionTypeAnnotation', + language, + ); + }).toThrow(UnsupportedArrayElementTypeAnnotationParserError); + }); + + it('does not throw the error if the type is NativeModuleTypeAnnotation', () => { + expect(() => { + throwIfArrayElementTypeAnnotationIsUnsupported( + moduleName, + undefined, + 'Array', + 'StringTypeAnnotation', + language, + ); + }).not.toThrow(UnsupportedArrayElementTypeAnnotationParserError); + }); +}); diff --git a/packages/react-native-codegen/src/parsers/error-utils.js b/packages/react-native-codegen/src/parsers/error-utils.js index 31e81e5f852687..d835d05773e75f 100644 --- a/packages/react-native-codegen/src/parsers/error-utils.js +++ b/packages/react-native-codegen/src/parsers/error-utils.js @@ -27,6 +27,7 @@ const { UnsupportedModulePropertyParserError, MoreThanOneModuleInterfaceParserError, UnsupportedFunctionParamTypeAnnotationParserError, + UnsupportedArrayElementTypeAnnotationParserError, } = require('./errors.js'); function throwIfModuleInterfaceIsMisnamed( @@ -250,6 +251,33 @@ function throwIfUnsupportedFunctionParamTypeAnnotationParserError( ); } +function throwIfArrayElementTypeAnnotationIsUnsupported( + hasteModuleName: string, + flowElementType: $FlowFixMe, + flowArrayType: 'Array' | '$ReadOnlyArray' | 'ReadonlyArray', + type: string, + language: ParserType, +) { + const TypeMap = { + FunctionTypeAnnotation: 'FunctionTypeAnnotation', + VoidTypeAnnotation: 'void', + PromiseTypeAnnotation: 'Promise', + // TODO: Added as a work-around for now until TupleTypeAnnotation are fully supported in both flow and TS + // Right now they are partially treated as UnionTypeAnnotation + UnionTypeAnnotation: 'UnionTypeAnnotation', + }; + + if (type in TypeMap) { + throw new UnsupportedArrayElementTypeAnnotationParserError( + hasteModuleName, + flowElementType, + flowArrayType, + TypeMap[type], + language, + ); + } +} + module.exports = { throwIfModuleInterfaceIsMisnamed, throwIfUnsupportedFunctionReturnTypeAnnotationParserError, @@ -263,4 +291,5 @@ module.exports = { throwIfModuleTypeIsUnsupported, throwIfMoreThanOneModuleInterfaceParserError, throwIfUnsupportedFunctionParamTypeAnnotationParserError, + throwIfArrayElementTypeAnnotationIsUnsupported, }; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 23678b216f7943..90f3568c406f2d 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -13,7 +13,6 @@ import type { NamedShape, NativeModuleAliasMap, - NativeModuleArrayTypeAnnotation, NativeModuleBaseTypeAnnotation, NativeModuleTypeAnnotation, NativeModulePropertyShape, @@ -55,7 +54,6 @@ const { } = require('../../parsers-primitives'); const { - UnsupportedArrayElementTypeAnnotationParserError, UnsupportedTypeAnnotationParserError, IncorrectModuleRegistryCallArgumentTypeParserError, } = require('../../errors.js'); @@ -63,6 +61,7 @@ const { const { throwIfModuleInterfaceNotFound, throwIfModuleInterfaceIsMisnamed, + throwIfArrayElementTypeAnnotationIsUnsupported, throwIfUnusedModuleInterfaceParserError, throwIfWrongNumberOfCallExpressionArgs, throwIfMoreThanOneModuleRegistryCalls, @@ -110,44 +109,19 @@ function translateArrayTypeAnnotation( ), ); - if (elementType.type === 'VoidTypeAnnotation') { - throw new UnsupportedArrayElementTypeAnnotationParserError( - hasteModuleName, - flowElementType, - flowArrayType, - 'void', - language, - ); - } - - if (elementType.type === 'PromiseTypeAnnotation') { - throw new UnsupportedArrayElementTypeAnnotationParserError( - hasteModuleName, - flowElementType, - flowArrayType, - 'Promise', - language, - ); - } - - if (elementType.type === 'FunctionTypeAnnotation') { - throw new UnsupportedArrayElementTypeAnnotationParserError( - hasteModuleName, - flowElementType, - flowArrayType, - 'FunctionTypeAnnotation', - language, - ); - } + throwIfArrayElementTypeAnnotationIsUnsupported( + hasteModuleName, + flowElementType, + flowArrayType, + elementType.type, + language, + ); - const finalTypeAnnotation: NativeModuleArrayTypeAnnotation< - Nullable, - > = { + return wrapNullable(nullable, { type: 'ArrayTypeAnnotation', + // $FlowFixMe[incompatible-call] elementType: wrapNullable(isElementTypeNullable, elementType), - }; - - return wrapNullable(nullable, finalTypeAnnotation); + }); } catch (ex) { return wrapNullable(nullable, { type: 'ArrayTypeAnnotation', diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/index.js b/packages/react-native-codegen/src/parsers/typescript/modules/index.js index f122081f93fb64..c184e715479ae5 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -13,7 +13,6 @@ import type { NamedShape, NativeModuleAliasMap, - NativeModuleArrayTypeAnnotation, NativeModuleBaseTypeAnnotation, NativeModulePropertyShape, NativeModuleTypeAnnotation, @@ -70,6 +69,7 @@ const { throwIfMoreThanOneModuleRegistryCalls, throwIfMoreThanOneModuleInterfaceParserError, throwIfIncorrectModuleRegistryCallTypeParameterParserError, + throwIfArrayElementTypeAnnotationIsUnsupported, } = require('../../error-utils'); const {TypeScriptParser} = require('../parser'); @@ -111,56 +111,19 @@ function translateArrayTypeAnnotation( ), ); - if (elementType.type === 'VoidTypeAnnotation') { - throw new UnsupportedArrayElementTypeAnnotationParserError( - hasteModuleName, - tsElementType, - tsArrayType, - 'void', - language, - ); - } - - if (elementType.type === 'PromiseTypeAnnotation') { - throw new UnsupportedArrayElementTypeAnnotationParserError( - hasteModuleName, - tsElementType, - tsArrayType, - 'Promise', - language, - ); - } - - if (elementType.type === 'FunctionTypeAnnotation') { - throw new UnsupportedArrayElementTypeAnnotationParserError( - hasteModuleName, - tsElementType, - tsArrayType, - 'FunctionTypeAnnotation', - language, - ); - } - - // TODO: Added as a work-around for now until TupleTypeAnnotation are fully supported in both flow and TS - // Right now they are partially treated as UnionTypeAnnotation - if (elementType.type === 'UnionTypeAnnotation') { - throw new UnsupportedArrayElementTypeAnnotationParserError( - hasteModuleName, - tsElementType, - tsArrayType, - 'UnionTypeAnnotation', - language, - ); - } + throwIfArrayElementTypeAnnotationIsUnsupported( + hasteModuleName, + tsElementType, + tsArrayType, + elementType.type, + language, + ); - const finalTypeAnnotation: NativeModuleArrayTypeAnnotation< - Nullable, - > = { + return wrapNullable(nullable, { type: 'ArrayTypeAnnotation', + // $FlowFixMe[incompatible-call] elementType: wrapNullable(isElementTypeNullable, elementType), - }; - - return wrapNullable(nullable, finalTypeAnnotation); + }); } catch (ex) { return wrapNullable(nullable, { type: 'ArrayTypeAnnotation', From 0d3d00287cf3e743d1ab9a6f313f6d81d8195069 Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Tue, 22 Nov 2022 09:17:33 -0800 Subject: [PATCH 31/58] Backport fix copy-hermes-xcode.sh from 0.71-stable (#35431) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35431 `[ -f "$source" ]` was wrong. `man test` reads: > -f file True if file exists and is a regular file. -e file True if file exists (regardless of type). hermes.framework is not a regular file but a directory. `-e` is beter here. Also intermediate destiantion directories are now created if they didn't exist. Changelog: [iOS][Fixed] - Make copy-hermes-xcode.sh more reliable. Reviewed By: robhogan Differential Revision: D41472846 fbshipit-source-id: 87de0b48d178ca542299b8e5fa741fdc0570d4e2 --- sdks/hermes-engine/utils/copy-hermes-xcode.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sdks/hermes-engine/utils/copy-hermes-xcode.sh b/sdks/hermes-engine/utils/copy-hermes-xcode.sh index 6768d4ecb28ed0..1b14941e6a14b3 100755 --- a/sdks/hermes-engine/utils/copy-hermes-xcode.sh +++ b/sdks/hermes-engine/utils/copy-hermes-xcode.sh @@ -6,9 +6,17 @@ set -x -source="${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/${PLATFORM_NAME}/hermes.framework" +src="${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/${PLATFORM_NAME}/hermes.framework" -if [[ -f "$source" ]]; then - cp -R "$source" "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework" - cp -R "$source" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +if [[ ! -e "$src" ]]; then + echo "$src does not exist." + exit 1 fi + +dst1="${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes" +[ ! -f "$dst1" ] && mkdir -p "$dst1" +cp -R "$src" "$dst1" + +dst2="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +[ ! -f "$dst2" ] && mkdir -p "$dst2" +cp -R "$src" "$dst2" From 6410a621cedc122352ed7453ea920464331fda50 Mon Sep 17 00:00:00 2001 From: GabeDahl <45904434+GabeDahl@users.noreply.github.com> Date: Tue, 22 Nov 2022 14:58:33 -0800 Subject: [PATCH 32/58] Fix typo in renderItem usage snippet (#35416) Summary: Fix typo in renderItem usage snippet - TouchableOpacity's JSX closing tag ## Changelog [General] [Fixed] - Message Pull Request resolved: https://github.com/facebook/react-native/pull/35416 Test Plan: N/A - Typo is in a comment Reviewed By: christophpurrer Differential Revision: D41445946 Pulled By: NickGerleman fbshipit-source-id: 147226f9b0ef443908f71d25ccf8063b8c1c6142 --- Libraries/Lists/FlatList.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Lists/FlatList.d.ts b/Libraries/Lists/FlatList.d.ts index 0cb4302f1ee080..f09464025a0c0a 100644 --- a/Libraries/Lists/FlatList.d.ts +++ b/Libraries/Lists/FlatList.d.ts @@ -187,7 +187,7 @@ export interface FlatListProps extends VirtualizedListProps { * _renderItem = ({item}) => ( * this._onPress(item)}> * {item.title} - * + * * ); * ... * From 3eb69f24ddc281f4bff2f250f88cb875d6d721d0 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Tue, 22 Nov 2022 15:15:44 -0800 Subject: [PATCH 33/58] Animated: Revert `setNativeView` Workaround Summary: Reverts {D41122065 (https://github.com/facebook/react-native/commit/1b1b26a099cc2f213bb270bfc0e56a202e618638)}, which is no longer necessary because {D41208895 (https://github.com/facebook/react-native/commit/7cf4cf3afbea4463427944fbed30768a796db724)} fixed the `ref` invalidation in `ScrollView`. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D41390543 fbshipit-source-id: 36c3db80af6e426f233ef0aaf5909942fb7103b2 --- Libraries/Animated/useAnimatedProps.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Libraries/Animated/useAnimatedProps.js b/Libraries/Animated/useAnimatedProps.js index b63d54789760ab..1b7d81009fd885 100644 --- a/Libraries/Animated/useAnimatedProps.js +++ b/Libraries/Animated/useAnimatedProps.js @@ -35,7 +35,6 @@ export default function useAnimatedProps( ): [ReducedProps, CallbackRef] { const [, scheduleUpdate] = useReducer(count => count + 1, 0); const onUpdateRef = useRef void>(null); - const cachedRef = useRef(null); // TODO: Only invalidate `node` if animated props or `style` change. In the // previous implementation, we permitted `style` to override props with the @@ -65,7 +64,6 @@ export default function useAnimatedProps( // NOTE: This may be called more often than necessary (e.g. when `props` // changes), but `setNativeView` already optimizes for that. node.setNativeView(instance); - cachedRef.current = instance; // NOTE: This callback is only used by the JavaScript animation driver. onUpdateRef.current = () => { @@ -115,16 +113,6 @@ export default function useAnimatedProps( ); const callbackRef = useRefEffect(refEffect); - useEffect(() => { - // Call `setNativeView` any time `node` changes to make sure - // `AnimatedProps._animatedView` is up to date. - // This would not be necessary in an ideal world. - // In React, anytime identity of function passed to `ref` changes, - // the old function is called with null and the new function is called with value. - // ScrollView does not behave like this and this workaround is necessary. - node.setNativeView(cachedRef.current); - }, [node]); - return [reduceAnimatedProps(node), callbackRef]; } From 6c10df5c90a92ad04d2fa97fff8fad36126dc5b3 Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Wed, 23 Nov 2022 01:41:23 -0800 Subject: [PATCH 34/58] update graphics imports Summary: i recently made a change to modularize some of our graphics dependencies i think this codegen will be incorrect now after my diff, so i updated it so we would codegen the correct deps Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D41451842 fbshipit-source-id: 98b5576e9fbd2d693c8bcfeac39d8dfb1b1e0584 --- .../__snapshots__/GeneratePropsH-test.js.snap | 8 ++++---- .../components/ComponentsGeneratorUtils.js | 4 ++-- .../__snapshots__/GeneratePropsH-test.js.snap | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap index ba79b2cf4149fb..d272afef823b9a 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap @@ -18,7 +18,7 @@ Object { #include #include #include -#include +#include #include #include @@ -567,7 +567,7 @@ Object { #include #include #include -#include +#include #include namespace facebook { @@ -647,7 +647,7 @@ Object { #include #include #include -#include +#include #include #include @@ -810,7 +810,7 @@ Object { #include #include #include -#include +#include namespace facebook { namespace react { diff --git a/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js b/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js index 5e6b6c9aeb3b69..22755be313d908 100644 --- a/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js +++ b/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js @@ -234,10 +234,10 @@ function getLocalImports( imports.add('#include '); return; case 'PointPrimitive': - imports.add('#include '); + imports.add('#include '); return; case 'EdgeInsetsPrimitive': - imports.add('#include '); + imports.add('#include '); return; default: (name: empty); diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap index 7f8a84fe002064..621f2e95fa8eca 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap @@ -18,7 +18,7 @@ Map { #include #include #include -#include +#include #include #include @@ -235,7 +235,7 @@ Map { #include #include #include -#include +#include #include #include @@ -800,7 +800,7 @@ Map { #include #include #include -#include +#include namespace facebook { namespace react { @@ -975,7 +975,7 @@ Map { #include #include #include -#include +#include #include namespace facebook { @@ -1055,7 +1055,7 @@ Map { #include #include #include -#include +#include #include #include @@ -1308,7 +1308,7 @@ Map { #include #include #include -#include +#include namespace facebook { namespace react { From c5a8425fada10b715f356731426db666975569c9 Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Wed, 23 Nov 2022 01:41:23 -0800 Subject: [PATCH 35/58] more Geometry.h cleanup Summary: Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D41452147 fbshipit-source-id: f427b8d95572c4b602b96962be187b62b801d62b --- ReactCommon/react/renderer/components/text/TextProps.h | 1 - 1 file changed, 1 deletion(-) diff --git a/ReactCommon/react/renderer/components/text/TextProps.h b/ReactCommon/react/renderer/components/text/TextProps.h index 53df63702b10c5..38502bc40efea8 100644 --- a/ReactCommon/react/renderer/components/text/TextProps.h +++ b/ReactCommon/react/renderer/components/text/TextProps.h @@ -12,7 +12,6 @@ #include #include #include -#include namespace facebook { namespace react { From e11cfe98e95feb8aeef3431294b8bb201d6a4839 Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Wed, 23 Nov 2022 13:20:00 -0800 Subject: [PATCH 36/58] feat(react-native/template): use verdaccio to publish local packages before testing template app (#35444) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35444 Changelog: [Internal][Changed] - now using Verdaccio to publish necessary packages for template app - Adds script `/scripts/template/install-dependencies.js`, which incapsulates the logic of installing dependencies of template app - The idea of the script is to run verdaccio and publish all necessary packages to node_modules, since these packages might not yet be present on npm - This should also potentially resolve some template app test failures on CircleCI related to package-ifying Animated, VirtualizedList, FlatList modules Reviewed By: cortinico Differential Revision: D41498086 fbshipit-source-id: 48fbbb1c9334e7a9e7657e6275b7b04f9ce290b5 --- .circleci/config.yml | 9 ++-- scripts/run-ci-e2e-tests.js | 7 ++- scripts/setup-verdaccio.js | 49 +++++++++++------ scripts/template/README.md | 30 +++++++++++ scripts/template/install-dependencies.js | 67 ++++++++++++++++++++++++ scripts/template/verdaccio.yml | 27 ++++++++++ 6 files changed, 166 insertions(+), 23 deletions(-) create mode 100644 scripts/template/README.md create mode 100644 scripts/template/install-dependencies.js create mode 100644 scripts/template/verdaccio.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 12264e6fd30e7f..c8ccedeb0b6769 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -780,9 +780,7 @@ jobs: REPO_ROOT=$(pwd) node ./scripts/set-rn-template-version.js "file:$REPO_ROOT/build/$(cat build/react-native-package-version)" node cli.js init $PROJECT_NAME --directory "/tmp/$PROJECT_NAME" --template $REPO_ROOT --verbose --skip-install - cd /tmp/$PROJECT_NAME - yarn - + node ./scripts/template/install-dependencies.js --reactNativeRootPath $REPO_ROOT --templatePath "/tmp/$PROJECT_NAME" - run: name: Build the template application for << parameters.flavor >> with Architecture set to << parameters.architecture >>, and using the << parameters.jsengine>> JS engine. command: | @@ -863,12 +861,11 @@ jobs: PATH_TO_PACKAGE="$REPO_ROOT/build/$PACKAGE" node ./scripts/set-rn-template-version.js "file:$PATH_TO_PACKAGE" node cli.js init $PROJECT_NAME --directory "/tmp/$PROJECT_NAME" --template $REPO_ROOT --verbose --skip-install + node ./scripts/template/install-dependencies.js --reactNativeRootPath $REPO_ROOT --templatePath "/tmp/$PROJECT_NAME" - run: name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>>; Flipper << parameters.flipper >> command: | - cd /tmp/$PROJECT_NAME - yarn install - cd ios + cd /tmp/$PROJECT_NAME/ios bundle install diff --git a/scripts/run-ci-e2e-tests.js b/scripts/run-ci-e2e-tests.js index ee4ae4fea95371..f9a2f98fe549f7 100644 --- a/scripts/run-ci-e2e-tests.js +++ b/scripts/run-ci-e2e-tests.js @@ -23,7 +23,7 @@ const {cd, cp, echo, exec, exit, mv} = require('shelljs'); const spawn = require('child_process').spawn; const argv = require('yargs').argv; const path = require('path'); -const {setupVerdaccio} = require('./setup-verdaccio'); +const setupVerdaccio = require('./setup-verdaccio'); const SCRIPTS = __dirname; const ROOT = path.normalize(path.join(__dirname, '..')); @@ -34,6 +34,9 @@ const REACT_NATIVE_TEMP_DIR = exec( ).stdout.trim(); const REACT_NATIVE_APP_DIR = `${REACT_NATIVE_TEMP_DIR}/template`; const numberOfRetries = argv.retries || 1; + +const VERDACCIO_CONFIG_PATH = path.join(ROOT, '.circleci/verdaccio.yml'); + let SERVER_PID; let APPIUM_PID; let VERDACCIO_PID; @@ -73,7 +76,7 @@ try { const REACT_NATIVE_PACKAGE = path.join(ROOT, 'react-native-*.tgz'); describe('Set up Verdaccio'); - VERDACCIO_PID = setupVerdaccio(); + VERDACCIO_PID = setupVerdaccio(ROOT, VERDACCIO_CONFIG_PATH); describe('Publish packages'); const packages = JSON.parse( diff --git a/scripts/setup-verdaccio.js b/scripts/setup-verdaccio.js index e62e7918540d2a..3dc32a261dbe60 100644 --- a/scripts/setup-verdaccio.js +++ b/scripts/setup-verdaccio.js @@ -9,22 +9,41 @@ 'use strict'; -const {exec} = require('shelljs'); -const spawn = require('child_process').spawn; - -function setupVerdaccio() { - const verdaccioProcess = spawn('npx', [ - 'verdaccio@5.15.3', - '--config', - '.circleci/verdaccio.yml', - ]); +const {execSync, spawn} = require('child_process'); + +function setupVerdaccio( + reactNativeRootPath, // Path to React Native root folder + verdaccioConfigPath, // Path to Verdaccio config file, which you want to use for bootstrapping Verdaccio + verdaccioStoragePath, // Path to Verdaccio storage, where it should keep packages. Optional. Default value will be decided by your Verdaccio config +) { + if (!reactNativeRootPath) { + throw new Error( + 'Path to React Native repo root is not specified. You should provide it as a first argument', + ); + } + + if (!verdaccioConfigPath) { + throw new Error( + 'Path to Verdaccio config is not specified. You should provide it as a second argument', + ); + } + + const verdaccioProcess = spawn( + 'npx', + ['verdaccio@5.16.3', '--config', verdaccioConfigPath], + {env: {...process.env, VERDACCIO_STORAGE_PATH: verdaccioStoragePath}}, + ); + const VERDACCIO_PID = verdaccioProcess.pid; - exec('npx wait-on@6.0.1 http://localhost:4873'); - exec('npm set registry http://localhost:4873'); - exec('echo "//localhost:4873/:_authToken=secretToken" > .npmrc'); + + execSync('npx wait-on@6.0.1 http://localhost:4873'); + + execSync('npm set registry http://localhost:4873'); + execSync('echo "//localhost:4873/:_authToken=secretToken" > .npmrc', { + cwd: reactNativeRootPath, + }); + return VERDACCIO_PID; } -module.exports = { - setupVerdaccio: setupVerdaccio, -}; +module.exports = setupVerdaccio; diff --git a/scripts/template/README.md b/scripts/template/README.md new file mode 100644 index 00000000000000..657b9c39b99f65 --- /dev/null +++ b/scripts/template/README.md @@ -0,0 +1,30 @@ +## Why? + +The main purpose of `install-dependencies.js` is to bootstrap [Verdaccio](https://verdaccio.org/docs/what-is-verdaccio). It will host all the local packages, which are not yet present on npm registry. In the near future this should help us in keep template tests green, because once we move to [monorepo structure](https://github.com/react-native-community/discussions-and-proposals/pull/480), template app may use some versions of dependencies that are not yet present on npm registry. + +## I have migrated some module to package, which is not yet published to npm, how to use it? + +First of all, you need to modify [Verdaccio config](https://github.com/facebook/react-native/tree/main/scripts/template/verdaccio.yml): +```diff + packages: ++ '': ++ access: $all ++ publish: $all + '@*/*': + access: $all + publish: $authenticated + proxy: npmjs + '**': + access: $all + publish: $all + proxy: npmjs +``` + +After that, you should modify [install-dependencies script](https://github.com/facebook/react-native/tree/main/scripts/template/install-dependencies.js) to include your package for publishing + +```diff +const PACKAGES_TO_PUBLISH_PATHS = [ + ... ++ "packages/" +]; +``` diff --git a/scripts/template/install-dependencies.js b/scripts/template/install-dependencies.js new file mode 100644 index 00000000000000..47f4eb492c41e4 --- /dev/null +++ b/scripts/template/install-dependencies.js @@ -0,0 +1,67 @@ +/** + * 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 + */ + +'use strict'; + +const yargs = require('yargs'); +const {execSync, spawnSync} = require('child_process'); +const setupVerdaccio = require('../setup-verdaccio'); + +const {argv} = yargs + .option('r', { + alias: 'reactNativeRootPath', + describe: 'Path to root folder of react-native', + required: true, + }) + .option('c', { + alias: 'templatePath', + describe: 'Path to template application folder', + required: true, + }) + .strict(); + +const {reactNativeRootPath, templatePath} = argv; + +const VERDACCIO_CONFIG_PATH = `${reactNativeRootPath}/scripts/template/verdaccio.yml`; +const VERDACCIO_STORAGE_PATH = `${templatePath}/node_modules`; + +const PACKAGES_TO_PUBLISH_PATHS = []; + +function install() { + const VERDACCIO_PID = setupVerdaccio( + reactNativeRootPath, + VERDACCIO_CONFIG_PATH, + VERDACCIO_STORAGE_PATH, + ); + process.stdout.write('Bootstrapped Verdaccio \u2705\n'); + + // Publish all necessary packages... + for (const packagePath of PACKAGES_TO_PUBLISH_PATHS) { + execSync('npm publish --registry http://localhost:4873 --access public', { + cwd: `${reactNativeRootPath}/${packagePath}`, + stdio: [process.stdin, process.stdout, process.stderr], + }); + + process.stdout.write(`Published /${packagePath} to proxy \u2705\n`); + } + + spawnSync('yarn', ['install'], { + cwd: templatePath, + stdio: [process.stdin, process.stdout, process.stderr], + }); + process.stdout.write('Installed dependencies via Yarn \u2705\n'); + + process.stdout.write(`Killing verdaccio. PID — ${VERDACCIO_PID}...\n`); + execSync(`kill -9 ${VERDACCIO_PID}`); + process.stdout.write('Killed Verdaccio process \u2705\n'); + + process.exit(); +} + +install(); diff --git a/scripts/template/verdaccio.yml b/scripts/template/verdaccio.yml new file mode 100644 index 00000000000000..03ebcfdc7e1dc0 --- /dev/null +++ b/scripts/template/verdaccio.yml @@ -0,0 +1,27 @@ +storage: ./storage +auth: + htpasswd: + file: ./htpasswd +uplinks: + npmjs: + url: https://registry.npmjs.org/ + max_fails: 40 + maxage: 30m + timeout: 60s + fail_timeout: 10m + cache: false + agent_options: + keepAlive: true + maxSockets: 40 + maxFreeSockets: 10 +packages: + '@*/*': + access: $all + publish: $authenticated + proxy: npmjs + '**': + access: $all + publish: $all + proxy: npmjs +logs: + - {type: file, path: verdaccio.log, format: json, level: warn} From 9d068ba8b90be0d439b8761936d8eacb5e5d8bb8 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 23 Nov 2022 15:33:45 -0800 Subject: [PATCH 37/58] Do not suggest users to report on MessageQueue Summary: This is a nit. We have this message "Please Report" which is really confusing in the error message. Users are opening Github Issues but that's not really actionable for us. We should clean it up. Changelog: [Internal] [Changed] - Do not suggest users to report on MessageQueue Reviewed By: shwanton Differential Revision: D41501707 fbshipit-source-id: fa57e50114a6e67b98f4b0b5d805031ae07d8776 --- Libraries/BatchedBridge/MessageQueue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/BatchedBridge/MessageQueue.js b/Libraries/BatchedBridge/MessageQueue.js index 24e00b0a029fe1..932d309fc1bd0a 100644 --- a/Libraries/BatchedBridge/MessageQueue.js +++ b/Libraries/BatchedBridge/MessageQueue.js @@ -207,7 +207,7 @@ class MessageQueue { }); warnOnce( 'excessive-number-of-pending-callbacks', - `Please report: Excessive number of pending callbacks: ${ + `Excessive number of pending callbacks: ${ this._successCallbacks.size }. Some pending callbacks that might have leaked by never being called from native code: ${stringifySafe( info, From e6cba997443ad72961cee1eee39346f80b48184e Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Wed, 23 Nov 2022 16:16:38 -0800 Subject: [PATCH 38/58] rename Geometry.h -> Vector.h Summary: Geometry only contains the Vector struct now, renaming it for accuracy Changelog: [Internal] Reviewed By: stephinphection Differential Revision: D41453351 fbshipit-source-id: 973b4a03208f4eeb0e209ea0aa58f5beca17c483 --- ReactCommon/react/renderer/graphics/Transform.h | 2 +- ReactCommon/react/renderer/graphics/{Geometry.h => Vector.h} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename ReactCommon/react/renderer/graphics/{Geometry.h => Vector.h} (100%) diff --git a/ReactCommon/react/renderer/graphics/Transform.h b/ReactCommon/react/renderer/graphics/Transform.h index 76c0d1d6cea782..8ccd908b577476 100644 --- a/ReactCommon/react/renderer/graphics/Transform.h +++ b/ReactCommon/react/renderer/graphics/Transform.h @@ -12,10 +12,10 @@ #include #include -#include #include #include #include +#include #ifdef ANDROID #include diff --git a/ReactCommon/react/renderer/graphics/Geometry.h b/ReactCommon/react/renderer/graphics/Vector.h similarity index 100% rename from ReactCommon/react/renderer/graphics/Geometry.h rename to ReactCommon/react/renderer/graphics/Vector.h From 9517320176ee410fe6c78e8fae6c257060f4a819 Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Wed, 23 Nov 2022 18:48:47 -0800 Subject: [PATCH 39/58] Enable C++17 for cxxreact and jsiexecutor/inspector and ... (#35435) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35435 This raises the C++ language standard to C++17 which is needed to remove some folly:: dependencies changelog: [Internal] Reviewed By: cortinico Differential Revision: D41482821 fbshipit-source-id: 62af6e95e6e78378112a4ce4e9c3ab7df0587218 --- ReactAndroid/src/main/jni/CMakeLists.txt | 2 +- .../src/main/jni/react/hermes/reactexecutor/CMakeLists.txt | 1 + ReactCommon/cxxreact/CMakeLists.txt | 1 + ReactCommon/cxxreact/React-cxxreact.podspec | 3 ++- ReactCommon/hermes/React-hermes.podspec | 3 ++- ReactCommon/hermes/executor/CMakeLists.txt | 2 ++ ReactCommon/hermes/inspector/CMakeLists.txt | 1 + ReactCommon/jsiexecutor/CMakeLists.txt | 6 +++++- ReactCommon/jsiexecutor/React-jsiexecutor.podspec | 3 ++- ReactCommon/jsinspector/CMakeLists.txt | 4 +++- ReactCommon/jsinspector/React-jsinspector.podspec | 1 + 11 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ReactAndroid/src/main/jni/CMakeLists.txt b/ReactAndroid/src/main/jni/CMakeLists.txt index 420794146092e8..bd13fa34b5e7e0 100644 --- a/ReactAndroid/src/main/jni/CMakeLists.txt +++ b/ReactAndroid/src/main/jni/CMakeLists.txt @@ -17,7 +17,7 @@ endif(CCACHE_FOUND) # Make sure every shared lib includes a .note.gnu.build-id header add_link_options(-Wl,--build-id) -add_compile_options(-Wall -Werror -std=c++1y) +add_compile_options(-Wall -Werror -std=c++17) function(add_react_android_subdir relative_path) add_subdirectory(${REACT_ANDROID_DIR}/${relative_path} ReactAndroid/${relative_path}) diff --git a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt index d446141c7ed92d..3145a733fe5c4d 100644 --- a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt +++ b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt @@ -25,6 +25,7 @@ target_compile_options( ${HERMES_TARGET_NAME} PRIVATE $<$:-DHERMES_ENABLE_DEBUGGER=1> + -std=c++17 -fexceptions ) target_include_directories(${HERMES_TARGET_NAME} PRIVATE .) diff --git a/ReactCommon/cxxreact/CMakeLists.txt b/ReactCommon/cxxreact/CMakeLists.txt index 5518b0909efc27..2aa8c299dc1c38 100644 --- a/ReactCommon/cxxreact/CMakeLists.txt +++ b/ReactCommon/cxxreact/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_VERBOSE_MAKEFILE on) add_compile_options( -fexceptions -frtti + -std=c++17 -Wno-unused-lambda-capture -DLOG_TAG=\"ReactNative\") diff --git a/ReactCommon/cxxreact/React-cxxreact.podspec b/ReactCommon/cxxreact/React-cxxreact.podspec index b672f5489764b2..a2c66cf7eb5c4b 100644 --- a/ReactCommon/cxxreact/React-cxxreact.podspec +++ b/ReactCommon/cxxreact/React-cxxreact.podspec @@ -33,7 +33,8 @@ Pod::Spec.new do |s| s.source_files = "*.{cpp,h}" s.exclude_files = "SampleCxxModule.*" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\"" } + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\"", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" } s.header_dir = "cxxreact" s.dependency "boost", "1.76.0" diff --git a/ReactCommon/hermes/React-hermes.podspec b/ReactCommon/hermes/React-hermes.podspec index 02a072c313df67..dc1036c0bb3f61 100644 --- a/ReactCommon/hermes/React-hermes.podspec +++ b/ReactCommon/hermes/React-hermes.podspec @@ -40,7 +40,8 @@ Pod::Spec.new do |s| s.public_header_files = "executor/HermesExecutorFactory.h" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"${PODS_ROOT}/hermes-engine/destroot/include\" \"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/libevent/include\"" + "HEADER_SEARCH_PATHS" => "\"${PODS_ROOT}/hermes-engine/destroot/include\" \"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/libevent/include\"", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }.merge!(build_type == :debug ? { "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" } : {}) s.header_dir = "reacthermes" s.dependency "React-cxxreact", version diff --git a/ReactCommon/hermes/executor/CMakeLists.txt b/ReactCommon/hermes/executor/CMakeLists.txt index a6d8bbac1ddf01..b6575a08e19937 100644 --- a/ReactCommon/hermes/executor/CMakeLists.txt +++ b/ReactCommon/hermes/executor/CMakeLists.txt @@ -6,6 +6,8 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_VERBOSE_MAKEFILE on) +add_compile_options(-std=c++17) + file(GLOB_RECURSE hermes_executor_SRC CONFIGURE_DEPENDS *.cpp) add_library( hermes-executor-common diff --git a/ReactCommon/hermes/inspector/CMakeLists.txt b/ReactCommon/hermes/inspector/CMakeLists.txt index 14f6f1ce263900..e08a1eaadd2817 100644 --- a/ReactCommon/hermes/inspector/CMakeLists.txt +++ b/ReactCommon/hermes/inspector/CMakeLists.txt @@ -17,6 +17,7 @@ target_compile_options( PRIVATE -DHERMES_ENABLE_DEBUGGER=1 -DHERMES_INSPECTOR_FOLLY_KLUDGE=1 + -std=c++17 -fexceptions ) diff --git a/ReactCommon/jsiexecutor/CMakeLists.txt b/ReactCommon/jsiexecutor/CMakeLists.txt index 68597560a0c69c..ae63005ed6d022 100644 --- a/ReactCommon/jsiexecutor/CMakeLists.txt +++ b/ReactCommon/jsiexecutor/CMakeLists.txt @@ -6,7 +6,11 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_VERBOSE_MAKEFILE on) -add_compile_options(-fexceptions -frtti -O3) +add_compile_options( + -fexceptions + -frtti + -std=c++17 + -O3) add_library(jsireact STATIC diff --git a/ReactCommon/jsiexecutor/React-jsiexecutor.podspec b/ReactCommon/jsiexecutor/React-jsiexecutor.podspec index cbfaf3879a3270..cedebb9e6479ce 100644 --- a/ReactCommon/jsiexecutor/React-jsiexecutor.podspec +++ b/ReactCommon/jsiexecutor/React-jsiexecutor.podspec @@ -31,7 +31,8 @@ Pod::Spec.new do |s| s.source = source s.source_files = "jsireact/*.{cpp,h}" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\"" } + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\"", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" } s.header_dir = "jsireact" s.dependency "React-cxxreact", version diff --git a/ReactCommon/jsinspector/CMakeLists.txt b/ReactCommon/jsinspector/CMakeLists.txt index 511afcb9a43d52..dd361e90b9a132 100644 --- a/ReactCommon/jsinspector/CMakeLists.txt +++ b/ReactCommon/jsinspector/CMakeLists.txt @@ -6,7 +6,9 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_VERBOSE_MAKEFILE on) -add_compile_options(-fexceptions) +add_compile_options( + -fexceptions + -std=c++17) file(GLOB jsinspector_SRC CONFIGURE_DEPENDS *.cpp) add_library(jsinspector SHARED ${jsinspector_SRC}) diff --git a/ReactCommon/jsinspector/React-jsinspector.podspec b/ReactCommon/jsinspector/React-jsinspector.podspec index cf77de1da3044b..4b6d9a9287f0bd 100644 --- a/ReactCommon/jsinspector/React-jsinspector.podspec +++ b/ReactCommon/jsinspector/React-jsinspector.podspec @@ -27,4 +27,5 @@ Pod::Spec.new do |s| s.source = source s.source_files = "*.{cpp,h}" s.header_dir = 'jsinspector' + s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" } end From 25c97bbb2265b482b545af931a86b9742c5dd4b4 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 07:45:17 -0800 Subject: [PATCH 40/58] RNGP - Correctly Support Gradle Configuration Cache (#35455) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35455 This little change allows to support Gradle Configuration cache in user projects: https://docs.gradle.org/current/userguide/configuration_cache.html It allows to save several seconds on the build time. We'll keep it disabled for now, but Gradle plans to enable it by default for everyone in the future, so this changes makes us ready for it. Changelog: [Internal] [Changed] - RNGP - Correctly Support Gradle Configuration Cache Reviewed By: cipolleschi Differential Revision: D41519506 fbshipit-source-id: 6252546e811deb0777c0aab5332291368be7fa8f --- .../src/main/kotlin/com/facebook/react/ReactPlugin.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt index 8538eaa9941d48..b6523cdf607c1b 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt @@ -96,7 +96,8 @@ class ReactPlugin : Plugin { // Please note that appNeedsCodegen is triggering a read of the package.json at // configuration time as we need to feed the onlyIf condition of this task. // Therefore, the appNeedsCodegen needs to be invoked inside this lambda. - it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(extension) } + val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension) + it.onlyIf { isLibrary || needsCodegenFromPackageJson } } // We create the task to produce schema from JS files. @@ -120,7 +121,8 @@ class ReactPlugin : Plugin { } else { it.jsRootDir.set(extension.jsRootDir) } - it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(parsedPackageJson) } + val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension) + it.onlyIf { isLibrary || needsCodegenFromPackageJson } } // We create the task to generate Java code from schema. @@ -139,7 +141,8 @@ class ReactPlugin : Plugin { // Please note that appNeedsCodegen is triggering a read of the package.json at // configuration time as we need to feed the onlyIf condition of this task. // Therefore, the appNeedsCodegen needs to be invoked inside this lambda. - it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(extension) } + val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension) + it.onlyIf { isLibrary || needsCodegenFromPackageJson } } // We update the android configuration to include the generated sources. From db3ac93001f65bad84b748ec257fe79b79432976 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Thu, 24 Nov 2022 07:46:00 -0800 Subject: [PATCH 41/58] Bump Flipper to 0.174.0 (#35445) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35445 As Flipper version is a bit old, let's bump it to the latest stable: 0.174.0. This is a follow-up from D33583090 (https://github.com/facebook/react-native/commit/50057158ca32842d70160541e3cb5d4bd512f8f5). At the time, it wasn't possible to update to the latest stable Flipper as crashes were observed due to NDK mismatch. Changelog: [Android] [Changed] - Bump Flipper to 0.174.0 Reviewed By: cortinico Differential Revision: D41492705 fbshipit-source-id: 9ec205bb0b8e4ddcb56355a194cae0a64f3345d6 --- packages/rn-tester/android/app/gradle.properties | 2 +- template/android/gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rn-tester/android/app/gradle.properties b/packages/rn-tester/android/app/gradle.properties index 18b9871789b1b0..89a9accfeb72a3 100644 --- a/packages/rn-tester/android/app/gradle.properties +++ b/packages/rn-tester/android/app/gradle.properties @@ -10,7 +10,7 @@ android.useAndroidX=true android.enableJetifier=true # Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.125.0 +FLIPPER_VERSION=0.174.0 # RN-Tester is building with NewArch always enabled newArchEnabled=true diff --git a/template/android/gradle.properties b/template/android/gradle.properties index e4af465e8a1857..b56dd868f96e8f 100644 --- a/template/android/gradle.properties +++ b/template/android/gradle.properties @@ -25,7 +25,7 @@ android.useAndroidX=true android.enableJetifier=true # Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.125.0 +FLIPPER_VERSION=0.174.0 # Use this property to specify which architecture you want to build. # You can also override it from the CLI using From af6c9e218305c70e479c75e5ce1a8d633b1e2947 Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Thu, 24 Nov 2022 08:43:21 -0800 Subject: [PATCH 42/58] Do not add "Copy Hermes Framework" script phase to hermes-engine target Summary: This script phase is added to the main target of the user project. Adding it to the hermes-engine target is redundant and does nothing useful. Changelog: [iOS][Changed] - Do not add "Copy Hermes Framework" script phase to hermes-engine target. Reviewed By: cipolleschi Differential Revision: D41521276 fbshipit-source-id: a024fa33f7ec1605d1d6021f436d3d397871a50c --- sdks/hermes-engine/hermes-engine.podspec | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sdks/hermes-engine/hermes-engine.podspec b/sdks/hermes-engine/hermes-engine.podspec index 9f3b90bf77e8b3..d25e633536c231 100644 --- a/sdks/hermes-engine/hermes-engine.podspec +++ b/sdks/hermes-engine/hermes-engine.podspec @@ -133,10 +133,6 @@ Pod::Spec.new do |spec| export CMAKE_BINARY=${CMAKE_BINARY:-#{%x(command -v cmake | tr -d '\n')}} . ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/build-hermes-xcode.sh #{version} #{hermesc_path}/ImportHermesc.cmake EOS - }, - { - :name => 'Copy Hermes Framework', - :script => ". ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/copy-hermes-xcode.sh" } ] end From fe2716b8ae3599d6a042f0f92a50e4b7ebee3fb0 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 08:45:15 -0800 Subject: [PATCH 43/58] Consolidate hermes-executor-debug and -release inside a single target (#35454) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35454 Historically, we used to have hermes-executor debug and release as separate dynamic libraries. This makes it impossible to prefab this library, so I have to reconcile it into a single library. This will also help keep the setup consistent with the internal (BUCK) where we have a single target. Changelog: [Internal] [Changed] - Consolidate hermes-executor-debug and -release inside a single target Reviewed By: cipolleschi Differential Revision: D41519119 fbshipit-source-id: d9ddc30b72164daa29c735836ea433fd4d917fc8 --- ReactAndroid/build.gradle | 19 +----- .../com/facebook/hermes/reactexecutor/BUCK | 1 + .../hermes/reactexecutor/HermesExecutor.java | 9 +-- .../react/hermes/reactexecutor/CMakeLists.txt | 17 ++---- .../com/facebook/react/TaskConfiguration.kt | 3 +- .../react/utils/NdkConfiguratorUtils.kt | 19 ++---- .../react/utils/NdkConfiguratorUtilsTest.kt | 58 +++---------------- 7 files changed, 24 insertions(+), 102 deletions(-) diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index d43535934995e3..f14aa4d2352e99 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -404,6 +404,7 @@ android { targets "reactnativejni", "jscexecutor", + "hermes-executor", "jsijniprofiler", "reactnativeblob", "reactperfloggerjni", @@ -434,24 +435,6 @@ android { } } - buildTypes { - debug { - externalNativeBuild { - cmake { - targets "hermes-executor-debug" - } - } - } - - release { - externalNativeBuild { - cmake { - targets "hermes-executor-release" - } - } - } - } - externalNativeBuild { cmake { path "src/main/jni/CMakeLists.txt" diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK index 0c00d480eddb44..2c954374c38dcf 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK @@ -17,6 +17,7 @@ rn_android_library( react_native_target("java/com/facebook/hermes/instrumentation:instrumentation"), react_native_target("java/com/facebook/hermes/instrumentation:hermes_samplingprofiler"), react_native_target("java/com/facebook/react/bridge:bridge"), + react_native_target("java/com/facebook/react/common:common"), react_native_target("jni/react/hermes/reactexecutor:jni"), ":runtimeconfig", ], diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java index 48eaaa4c0668ba..e72bca607c1c96 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java +++ b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java @@ -9,6 +9,7 @@ import com.facebook.jni.HybridData; import com.facebook.react.bridge.JavaScriptExecutor; +import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.soloader.SoLoader; import javax.annotation.Nullable; @@ -23,11 +24,11 @@ public static void loadLibrary() throws UnsatisfiedLinkError { if (mode_ == null) { // libhermes must be loaded explicitly to invoke its JNI_OnLoad. SoLoader.loadLibrary("hermes"); - try { - SoLoader.loadLibrary("hermes-executor-debug"); + SoLoader.loadLibrary("hermes-executor"); + // libhermes-executor is built differently for Debug & Release so we load the proper mode. + if (ReactBuildConfig.DEBUG == true) { mode_ = "Debug"; - } catch (UnsatisfiedLinkError e) { - SoLoader.loadLibrary("hermes-executor-release"); + } else { mode_ = "Release"; } } diff --git a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt index 3145a733fe5c4d..fcf9f93e4c417d 100644 --- a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt +++ b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt @@ -8,29 +8,20 @@ set(CMAKE_VERBOSE_MAKEFILE on) file(GLOB_RECURSE hermes_executor_SRC CONFIGURE_DEPENDS *.cpp) -if(${CMAKE_BUILD_TYPE} MATCHES Debug) - set(HERMES_TARGET_SUFFIX debug) -else() - set(HERMES_TARGET_SUFFIX release) -endif() - -set(HERMES_TARGET_NAME hermes-executor-${HERMES_TARGET_SUFFIX}) - -add_library( - ${HERMES_TARGET_NAME} +add_library(hermes-executor SHARED ${hermes_executor_SRC} ) target_compile_options( - ${HERMES_TARGET_NAME} + hermes-executor PRIVATE $<$:-DHERMES_ENABLE_DEBUGGER=1> -std=c++17 -fexceptions ) -target_include_directories(${HERMES_TARGET_NAME} PRIVATE .) +target_include_directories(hermes-executor PRIVATE .) target_link_libraries( - ${HERMES_TARGET_NAME} + hermes-executor hermes-executor-common jsireact fb diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt index bb3699d58df095..a2b60f425794d8 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt @@ -46,8 +46,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio config.debuggableVariants.get().any { it.equals(variant.name, ignoreCase = true) } configureNewArchPackagingOptions(project, variant) - configureJsEnginePackagingOptions( - config, variant, isHermesEnabledInThisVariant, isDebuggableVariant) + configureJsEnginePackagingOptions(config, variant, isHermesEnabledInThisVariant) if (!isDebuggableVariant) { val bundleTask = diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt index 479c3f742eda99..13bbb3ab8c51dd 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt @@ -112,36 +112,25 @@ internal object NdkConfiguratorUtils { config: ReactExtension, variant: Variant, hermesEnabled: Boolean, - debuggableVariant: Boolean ) { if (config.enableSoCleanup.get()) { - val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled, debuggableVariant) + val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled) variant.packaging.jniLibs.excludes.addAll(excludes) variant.packaging.jniLibs.pickFirsts.addAll(includes) } } - fun getPackagingOptionsForVariant( - hermesEnabled: Boolean, - debuggableVariant: Boolean - ): Pair, List> { + fun getPackagingOptionsForVariant(hermesEnabled: Boolean): Pair, List> { val excludes = mutableListOf() val includes = mutableListOf() if (hermesEnabled) { excludes.add("**/libjsc.so") excludes.add("**/libjscexecutor.so") includes.add("**/libhermes.so") - if (debuggableVariant) { - excludes.add("**/libhermes-executor-release.so") - includes.add("**/libhermes-executor-debug.so") - } else { - excludes.add("**/libhermes-executor-debug.so") - includes.add("**/libhermes-executor-release.so") - } + includes.add("**/libhermes-executor.so") } else { excludes.add("**/libhermes.so") - excludes.add("**/libhermes-executor-debug.so") - excludes.add("**/libhermes-executor-release.so") + excludes.add("**/libhermes-executor.so") includes.add("**/libjsc.so") includes.add("**/libjscexecutor.so") } diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt index 2d0093c6a565d2..41d498b23dccec 100644 --- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt @@ -15,70 +15,28 @@ import org.junit.Test class NdkConfiguratorUtilsTest { @Test - fun getPackagingOptionsForVariant_withHermesEnabled_andDebuggableVariant() { - val (excludes, includes) = - getPackagingOptionsForVariant(hermesEnabled = true, debuggableVariant = true) + fun getPackagingOptionsForVariant_withHermesEnabled() { + val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled = true) assertTrue("**/libjsc.so" in excludes) assertTrue("**/libjscexecutor.so" in excludes) - assertTrue("**/libhermes-executor-release.so" in excludes) assertFalse("**/libjsc.so" in includes) assertFalse("**/libjscexecutor.so" in includes) - assertFalse("**/libhermes-executor-release.so" in includes) assertTrue("**/libhermes.so" in includes) - assertTrue("**/libhermes-executor-debug.so" in includes) + assertTrue("**/libhermes-executor.so" in includes) assertFalse("**/libhermes.so" in excludes) - assertFalse("**/libhermes-executor-debug.so" in excludes) + assertFalse("**/libhermes-executor.so" in excludes) } @Test - fun getPackagingOptionsForVariant_withHermesEnabled_andNonDebuggableVariant() { - val (excludes, includes) = - getPackagingOptionsForVariant(hermesEnabled = true, debuggableVariant = false) - - assertTrue("**/libjsc.so" in excludes) - assertTrue("**/libjscexecutor.so" in excludes) - assertTrue("**/libhermes-executor-debug.so" in excludes) - assertFalse("**/libjsc.so" in includes) - assertFalse("**/libjscexecutor.so" in includes) - assertFalse("**/libhermes-executor-debug.so" in includes) - - assertTrue("**/libhermes.so" in includes) - assertTrue("**/libhermes-executor-release.so" in includes) - assertFalse("**/libhermes.so" in excludes) - assertFalse("**/libhermes-executor-release.so" in excludes) - } - - @Test - fun getPackagingOptionsForVariant_withHermesDisabled_andDebuggableVariant() { - val (excludes, includes) = - getPackagingOptionsForVariant(hermesEnabled = false, debuggableVariant = true) - - assertTrue("**/libhermes.so" in excludes) - assertTrue("**/libhermes-executor-debug.so" in excludes) - assertTrue("**/libhermes-executor-release.so" in excludes) - assertFalse("**/libhermes.so" in includes) - assertFalse("**/libhermes-executor-debug.so" in includes) - assertFalse("**/libhermes-executor-release.so" in includes) - - assertTrue("**/libjsc.so" in includes) - assertTrue("**/libjscexecutor.so" in includes) - assertFalse("**/libjsc.so" in excludes) - assertFalse("**/libjscexecutor.so" in excludes) - } - - @Test - fun getPackagingOptionsForVariant_withHermesDisabled_andNonDebuggableVariant() { - val (excludes, includes) = - getPackagingOptionsForVariant(hermesEnabled = false, debuggableVariant = false) + fun getPackagingOptionsForVariant_withHermesDisabled() { + val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled = false) assertTrue("**/libhermes.so" in excludes) - assertTrue("**/libhermes-executor-debug.so" in excludes) - assertTrue("**/libhermes-executor-release.so" in excludes) + assertTrue("**/libhermes-executor.so" in excludes) assertFalse("**/libhermes.so" in includes) - assertFalse("**/libhermes-executor-debug.so" in includes) - assertFalse("**/libhermes-executor-release.so" in includes) + assertFalse("**/libhermes-executor.so" in includes) assertTrue("**/libjsc.so" in includes) assertTrue("**/libjscexecutor.so" in includes) From b70707b96df399e2ed6f75afe744bb5d67d188da Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 08:45:15 -0800 Subject: [PATCH 44/58] Expose `hermes-executor` to be consumed via prefab (#35457) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35457 This exposes `hermes-executor` to be consumed via prefab so that libraries can depend on it and use its symbols if needed (Expo and Reanimated need it). Changelog: [Internal] [Changed] - Expose `hermes-executor` to be consumed via prefab Reviewed By: cipolleschi Differential Revision: D41520019 fbshipit-source-id: d590a043ea89fdd8ff41b0ed20900c9cf381a1e4 --- ReactAndroid/build.gradle | 14 ++++++++++++-- ReactCommon/hermes/executor/CMakeLists.txt | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index f14aa4d2352e99..1bf06ae88265f6 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -174,6 +174,13 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa "rrc_image", new Pair("../ReactCommon/react/renderer/components/image/", "react/renderer/components/image/") ), + // This prefab target is used by Expo & Reanimated to load a new instance of Hermes + new PrefabPreprocessingEntry( + "hermes-executor", + // "hermes-executor" is statically linking agaisnt "hermes-executor-common" + // and "hermes-inspector". Here we expose only the headers that we know are needed. + new Pair("../ReactCommon/hermes/inspector/", "hermes/inspector/") + ), ] ) it.outputDir.set(prefabHeadersDir) @@ -404,7 +411,6 @@ android { targets "reactnativejni", "jscexecutor", - "hermes-executor", "jsijniprofiler", "reactnativeblob", "reactperfloggerjni", @@ -427,7 +433,8 @@ android { "yoga", "folly_runtime", "react_nativemodule_core", - "react_render_imagemanager" + "react_render_imagemanager", + "hermes-executor" } } ndk { @@ -532,6 +539,9 @@ android { react_render_imagemanager { headers(new File(prefabHeadersDir, "react_render_imagemanager").absolutePath) } + "hermes-executor" { + headers(new File(prefabHeadersDir, "hermes-executor").absolutePath) + } } publishing { diff --git a/ReactCommon/hermes/executor/CMakeLists.txt b/ReactCommon/hermes/executor/CMakeLists.txt index b6575a08e19937..4a2f54b5984191 100644 --- a/ReactCommon/hermes/executor/CMakeLists.txt +++ b/ReactCommon/hermes/executor/CMakeLists.txt @@ -19,7 +19,8 @@ target_link_libraries(hermes-executor-common jsireact hermes-engine::libhermes jsi - debug hermes-inspector + debug + hermes-inspector ) if(${CMAKE_BUILD_TYPE} MATCHES Debug) From 055d09cb76f85c466d9bab4d66f4f9b580648633 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 08:45:15 -0800 Subject: [PATCH 45/58] Add prefab for _uimanager _scheduler and _mounting (#35458) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35458 We're adding prefab support for those modules as they're needed by Reanimated and we're exposing headers for them as well. Changelog: [Internal] [Changed] - Add prefab for _uimanager _scheduler and _mounting Reviewed By: cipolleschi Differential Revision: D41520606 fbshipit-source-id: 76f3c81705e99057b92cd9b86d0601a2b1410f95 --- ReactAndroid/build.gradle | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 1bf06ae88265f6..74051746fc7208 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -181,6 +181,18 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa // and "hermes-inspector". Here we expose only the headers that we know are needed. new Pair("../ReactCommon/hermes/inspector/", "hermes/inspector/") ), + new PrefabPreprocessingEntry( + "react_render_uimanager", + new Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"), + ), + new PrefabPreprocessingEntry( + "react_render_scheduler", + new Pair("../ReactCommon/react/renderer/scheduler/", "react/renderer/scheduler/"), + ), + new PrefabPreprocessingEntry( + "react_render_mounting", + new Pair("../ReactCommon/react/renderer/mounting/", "react/renderer/mounting/"), + ), ] ) it.outputDir.set(prefabHeadersDir) @@ -434,6 +446,9 @@ android { "folly_runtime", "react_nativemodule_core", "react_render_imagemanager", + "react_render_uimanager", + "react_render_scheduler", + "react_render_mounting", "hermes-executor" } } @@ -539,6 +554,15 @@ android { react_render_imagemanager { headers(new File(prefabHeadersDir, "react_render_imagemanager").absolutePath) } + react_render_uimanager { + headers(new File(prefabHeadersDir, "react_render_uimanager").absolutePath) + } + react_render_scheduler { + headers(new File(prefabHeadersDir, "react_render_scheduler").absolutePath) + } + react_render_mounting { + headers(new File(prefabHeadersDir, "react_render_mounting").absolutePath) + } "hermes-executor" { headers(new File(prefabHeadersDir, "hermes-executor").absolutePath) } From 332822150affcf73b5a50bab191232a51ae95bef Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 08:45:15 -0800 Subject: [PATCH 46/58] Add missing headers to `react_nativemodule_core` prefab module (#35460) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35460 Reanimated reported that `react_nativemodule_core` was missing some headers. Specifically the one from ReactAndroid::react_debug, ReactAndroid::react_render_core, ReactAndroid::glog, and ReactAndroid::react_render_debug. I'm adding them here so they get included in the shipped headers for `react_nativemodule_core` Changelog: [Internal] [Changed] - Add missing headers to `react_nativemodule_core` prefab module Reviewed By: cipolleschi Differential Revision: D41520751 fbshipit-source-id: 4627a2d0f880d4bb3ff2f0e43cd735cf9a3f2f9a --- ReactAndroid/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 74051746fc7208..e4f28debed1481 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -144,6 +144,7 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa new Pair(new File(buildDir, "third-party-ndk/boost/boost_1_76_0/").absolutePath, ""), new Pair(new File(buildDir, "third-party-ndk/double-conversion/").absolutePath, ""), new Pair(new File(buildDir, "third-party-ndk/folly/").absolutePath, ""), + new Pair(new File(buildDir, "third-party-ndk/glog/exported/").absolutePath, ""), new Pair("../ReactCommon/butter/", "butter/"), new Pair("../ReactCommon/callinvoker/", ""), new Pair("../ReactCommon/react/bridging/", "react/bridging/"), @@ -152,6 +153,8 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa new Pair("../ReactCommon/react/nativemodule/core/platform/android/", ""), new Pair("../ReactCommon/react/renderer/componentregistry/", "react/renderer/componentregistry/"), new Pair("../ReactCommon/react/renderer/components/root/", "react/renderer/components/root/"), + new Pair("../ReactCommon/react/renderer/core/", "react/renderer/core/"), + new Pair("../ReactCommon/react/renderer/debug/", "react/renderer/debug/"), new Pair("../ReactCommon/react/renderer/leakchecker/", "react/renderer/leakchecker/"), new Pair("../ReactCommon/react/renderer/mapbuffer/", "react/renderer/mapbuffer/"), new Pair("../ReactCommon/react/renderer/mounting/", "react/renderer/mounting/"), @@ -159,6 +162,7 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa new Pair("../ReactCommon/react/renderer/scheduler/", "react/renderer/scheduler/"), new Pair("../ReactCommon/react/renderer/telemetry/", "react/renderer/telemetry/"), new Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"), + new Pair("../ReactCommon/react/debug/", "react/debug/"), new Pair("../ReactCommon/react/utils/", "react/utils/"), new Pair("src/main/jni/react/jni", "react/jni/"), ] From 92be0e3fde19d5b0c89e4471c0b9a80464ba66f4 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 08:45:15 -0800 Subject: [PATCH 47/58] Allow `reactnativejni` to be consumed via prefab (#35461) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35461 This is another library which is adding prefab support as it's needed by Expo libraries and Reanimated. Changelog: [Internal] [Changed] - Allow `reactnativejni` to be consumed via prefab Reviewed By: cipolleschi Differential Revision: D41520801 fbshipit-source-id: 91142a5b5051cfba478d93a2475a178eed6fbb29 --- ReactAndroid/build.gradle | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index e4f28debed1481..041f546c668f6e 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -197,6 +197,10 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa "react_render_mounting", new Pair("../ReactCommon/react/renderer/mounting/", "react/renderer/mounting/"), ), + new PrefabPreprocessingEntry( + "reactnativejni", + new Pair("src/main/jni/react/jni", "react/jni/"), + ), ] ) it.outputDir.set(prefabHeadersDir) @@ -425,12 +429,12 @@ android { "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-21" - targets "reactnativejni", - "jscexecutor", + targets "jscexecutor", "jsijniprofiler", "reactnativeblob", "reactperfloggerjni", // prefab targets + "reactnativejni", "react_render_debug", "turbomodulejsijni", "runtimeexecutor", @@ -567,6 +571,9 @@ android { react_render_mounting { headers(new File(prefabHeadersDir, "react_render_mounting").absolutePath) } + reactnativejni { + headers(new File(prefabHeadersDir, "reactnativejni").absolutePath) + } "hermes-executor" { headers(new File(prefabHeadersDir, "hermes-executor").absolutePath) } From 4c5eb8dd2a8cfb78783ab9cc3ac5a1c3f7937b63 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 09:18:36 -0800 Subject: [PATCH 48/58] Bump AGP to 7.4.x (#35456) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35456 Fixes #35439 There is a bug in AGP 7.3.x which is causing assets to don't be copied properly inside the final artifact: issuetracker.google.com/issues/237421684 As AGP 7.4.x is really close to release (is in Beta5, should be released stable in the next weeks) we should be fine by bumping to beta5. This also requires a bump of RNGP Changelog: [Android] [Changed] - Bump AGP to 7.4.x allow-large-files Reviewed By: cipolleschi Differential Revision: D41519549 fbshipit-source-id: 60d568a3e49798a23f1d7bf4839ab58bd5549aba --- packages/react-native-gradle-plugin/build.gradle.kts | 6 +++--- .../src/main/kotlin/com/facebook/react/ReactPlugin.kt | 6 ++++-- template/android/build.gradle | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/react-native-gradle-plugin/build.gradle.kts b/packages/react-native-gradle-plugin/build.gradle.kts index dd9a08ae099193..b1b2dd61012c83 100644 --- a/packages/react-native-gradle-plugin/build.gradle.kts +++ b/packages/react-native-gradle-plugin/build.gradle.kts @@ -33,7 +33,7 @@ group = "com.facebook.react" dependencies { implementation(gradleApi()) - implementation("com.android.tools.build:gradle:7.3.1") + implementation("com.android.tools.build:gradle:7.4.0-beta05") implementation("com.google.code.gson:gson:2.8.9") implementation("com.google.guava:guava:31.0.1-jre") implementation("com.squareup:javapoet:1.13.0") @@ -50,8 +50,8 @@ dependencies { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } tasks.withType { diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt index b6523cdf607c1b..152a7667e4ca03 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt @@ -47,8 +47,10 @@ class ReactPlugin : Plugin { configureBuildConfigFields(project) configureDevPorts(project) - project.extensions.getByType(AndroidComponentsExtension::class.java).onVariants { variant -> - project.configureReactTasks(variant = variant, config = extension) + project.extensions.getByType(AndroidComponentsExtension::class.java).apply { + onVariants(selector().all()) { variant -> + project.configureReactTasks(variant = variant, config = extension) + } } configureCodegen(project, extension, isLibrary = false) } diff --git a/template/android/build.gradle b/template/android/build.gradle index 4631930d4a5c42..baa44e144bbac1 100644 --- a/template/android/build.gradle +++ b/template/android/build.gradle @@ -15,7 +15,7 @@ buildscript { mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:7.3.1") + classpath("com.android.tools.build:gradle:7.4.0-beta05") classpath("com.facebook.react:react-native-gradle-plugin") } } From 4a4cceef2570c2a68ae91db0648aaaf08cf6c426 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Thu, 24 Nov 2022 10:15:43 -0800 Subject: [PATCH 49/58] Fix hardcoded path to codegen cli for monorepos (#35430) Summary: Fixes https://github.com/facebook/react-native/issues/35429 This fix is fairly straightforward. Instead of hardcoding two separate paths for this repo or a simple user's project, we ask Node to resolve `react-native-codegen`. Because `react-native-codegen` is moved [into the `/packages/*` folder](https://github.com/facebook/react-native/blob/main/package.json#L104), it's part of a workspace in this repository. That means that this fix works not only for monorepos in general but also resolves the right path within the react native repository. You can test this out yourself when running this command in either the root, or any other workspace in this repository: ```bash node --print "require('path').dirname(require.resolve('react-native-codegen/package.json'))" ``` I've tested this on Node 16 and 18, and seems to work nicely. Note that you _**have to specify `react-native-codegen/package.json`**_. That's because the `react-native-codegen` package itself is technically invalid; it's missing an entry point within the package (no `main`). When running `node --print "require.resolve('react-native-codegen')"` Node can't resolve the main entry point, and will fail during this process. ## Changelog [iOS] [Fixed] - Fix incorrect codegen CLI paths in monorepo projects Pull Request resolved: https://github.com/facebook/react-native/pull/35430 Test Plan: See PR https://github.com/facebook/react-native/issues/35429 Reviewed By: cortinico Differential Revision: D41475878 Pulled By: cipolleschi fbshipit-source-id: f0c362b64cf9c3543a3a031d7eaf302c1314e3f0 --- .../react_native_pods_utils/script_phases.sh | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/scripts/react_native_pods_utils/script_phases.sh b/scripts/react_native_pods_utils/script_phases.sh index 32c59234407ad8..a46dc8ab17fba8 100755 --- a/scripts/react_native_pods_utils/script_phases.sh +++ b/scripts/react_native_pods_utils/script_phases.sh @@ -13,8 +13,6 @@ GENERATED_SCHEMA_FILE="$GENERATED_SRCS_DIR/schema.json" cd "$RCT_SCRIPT_RN_DIR" -CODEGEN_REPO_PATH="$RCT_SCRIPT_RN_DIR/packages/react-native-codegen" -CODEGEN_NPM_PATH="$RCT_SCRIPT_RN_DIR/../react-native-codegen" CODEGEN_CLI_PATH="" error () { @@ -23,15 +21,6 @@ error () { exit 1 } -# Determine path to react-native-codegen -if [ -d "$CODEGEN_REPO_PATH" ]; then - CODEGEN_CLI_PATH=$(cd "$CODEGEN_REPO_PATH" && pwd) -elif [ -d "$CODEGEN_NPM_PATH" ]; then - CODEGEN_CLI_PATH=$(cd "$CODEGEN_NPM_PATH" && pwd) -else - error "error: Could not determine react-native-codegen location in $CODEGEN_REPO_PATH or $CODEGEN_NPM_PATH. Try running 'yarn install' or 'npm install' in your project root." -fi - find_node () { NODE_BINARY="${NODE_BINARY:-$(command -v node || true)}" if [ -z "$NODE_BINARY" ]; then @@ -41,6 +30,13 @@ find_node () { fi } +find_codegen () { + CODEGEN_CLI_PATH=$("$NODE_BINARY" --print "require('path').dirname(require.resolve('react-native-codegen/package.json'))") + if ! [ -d "$CODEGEN_CLI_PATH" ]; then + error "error: Could not determine react-native-codegen location, using node module resolution. Try running 'yarn install' or 'npm install' in your project root." + fi +} + setup_dirs () { set +e rm -rf "$GENERATED_SRCS_DIR" @@ -116,6 +112,7 @@ moveOutputs () { withCodgenDiscovery () { setup_dirs find_node + find_codegen generateArtifacts moveOutputs } @@ -123,6 +120,7 @@ withCodgenDiscovery () { noCodegenDiscovery () { setup_dirs find_node + find_codegen generateCodegenSchemaFromJavaScript generateCodegenArtifactsFromSchema moveOutputs From 0c6a4f8c59bc608714e791849af98b53ef28c6a1 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 10:21:57 -0800 Subject: [PATCH 50/58] Remove AVD code from Android CI Summary: We don't really run AVD (Emulators on CI) so those steps are entirely unnecessary and skipped every time. I'm removing them. Changelog: [Internal] [Changed] - Remove AVD code from Android CI Reviewed By: cipolleschi Differential Revision: D41521976 fbshipit-source-id: 2737ef0dfc84198ab9b837819c16ae46280ba43f --- .circleci/config.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c8ccedeb0b6769..af5c36dd4ebbee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -710,16 +710,6 @@ jobs: - checkout - setup_artifacts - run_yarn - - # Starting emulator in advance as it takes some time to boot. - - run: - name: Create Android Virtual Device - command: source scripts/android-setup.sh && createAVD - - run: - name: Launch Android Virtual Device in Background - command: source scripts/android-setup.sh && launchAVD - background: true - - download_gradle_dependencies - run: @@ -730,11 +720,6 @@ jobs: name: Build RN Tester for Release using Gradle command: ./gradlew packages:rn-tester:android:app:assembleRelease - # Wait for AVD to finish booting before running tests - - run: - name: Wait for Android Virtual Device - command: source scripts/android-setup.sh && waitForAVD - - report_bundle_size: platform: android From 09843a009457615f1d843307dc600f8746d7504e Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 10:21:57 -0800 Subject: [PATCH 51/58] Store RN Tester and Template APKs for Android on CI (#35463) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35463 This will allow us to easily retrieve debug/release APK for both RN-Tester and the Template jobs for every run of the CI. Changelog: [Internal] [Changed] - Store RN Tester and Template APKs for Android on CI Reviewed By: cipolleschi Differential Revision: D41521977 fbshipit-source-id: e2ed60921fd005425d3915323b18dde2851e7fc2 --- .circleci/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index af5c36dd4ebbee..dbc543068e2943 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -723,6 +723,10 @@ jobs: - report_bundle_size: platform: android + - store_artifacts: + path: ~/react-native/packages/rn-tester/android/app/build/outputs/apk/ + destination: rntester-apk + # Optionally, run disabled tests - when: condition: << parameters.run_disabled_tests >> @@ -782,6 +786,10 @@ jobs: fi ./gradlew assemble<< parameters.flavor >> -PREACT_NATIVE_MAVEN_LOCAL_REPO=/root/react-native/maven-local + - store_artifacts: + path: /tmp/$PROJECT_NAME/android/app/build/outputs/apk/ + destination: template-apk + # ------------------------- # JOBS: Test iOS Template # ------------------------- From a5c77115ae94b46823dc788add516493ee8e82cb Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Thu, 24 Nov 2022 10:22:40 -0800 Subject: [PATCH 52/58] Build hermesc in Xcode run script phase Summary: Build hermesc in Xcode run script phase, so it ends up inside `Pods/hermes-engine/buld_host_hermesc`. All the the housekeeping is now done by CocoaPods and Xcode, and we can get rid of all the setup/cleanup code. Changelog: [iOS][Changed] - Build hermesc in Xcode run script phase. Reviewed By: cipolleschi Differential Revision: D41521987 fbshipit-source-id: 336854fa23582255cba6d161acf2cc791cac9d00 --- .gitignore | 1 - packages/rn-tester/Podfile.lock | 10 ++++----- scripts/cocoapods/jsengine.rb | 4 ---- scripts/react_native_pods.rb | 1 - sdks/hermes-engine/hermes-engine.podspec | 22 +++++++++++-------- .../utils/build-hermesc-xcode.sh | 11 ++++++++-- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index fa41a5729c3b34..7611c0691d574e 100644 --- a/.gitignore +++ b/.gitignore @@ -125,7 +125,6 @@ package-lock.json /sdks/download /sdks/hermes /sdks/hermesc -/sdks/hermes-engine/build_host_hermesc # Visual studio .vscode diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index cf594d49707e18..7aa96f4ed7e530 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -954,7 +954,7 @@ SPEC CHECKSUMS: FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - hermes-engine: d18f5a58d912c767ed56b58821bddd685d766712 + hermes-engine: e49758848596771dbb97c8f1b65e9d1ac353af69 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 @@ -965,14 +965,14 @@ SPEC CHECKSUMS: React-Codegen: 4f1e911c128928e425e11698ad7859dfd0f92e20 React-Core: 719bec4b41c93b1affb1e2c3a43956ec482ecb9f React-CoreModules: feaa45c54c58e1420981f6dd544c8b3d01200caa - React-cxxreact: c5f93e7a35f3545489d8e1f89beb9d2d56acfde5 + React-cxxreact: 97903bdac0fb53409663fd312e2183ae1dd730e5 React-Fabric: 8a854fd89c932ab073f67036bb45d1787d0d31a4 React-graphics: cb8a85648695c60f33a00d732b985f734d1470d8 - React-hermes: 299c7f56d32e8953480fd8e7fba2a7968a534b3f + React-hermes: af82687697f03ebb78aadd09dbc027df55fd87f8 React-jsi: d40e13b7f545f9af2af780f153f5321018b5e2f8 React-jsidynamic: 8aa406dfc1eff081f3443e55a28b51d11616a3bf - React-jsiexecutor: 04a945f040cc085d79655359ec29e5f501fb6e01 - React-jsinspector: a56861590ddfcb5cb544877ade3e007a32ff9616 + React-jsiexecutor: c402e7aeef68fab08a5f82adfea1f6874bf1b89b + React-jsinspector: 9b56a373a6797114e1d89a7dffa98ee98af67a8f React-logger: 07c9b44040a6f948b8e2033207b23cb623f0b9b4 React-perflogger: b4b9fb2ddd856b78003708ab3cf66ce03e6bc7c4 React-RCTActionSheet: 1b1501ef80928be10702cd0ce09120358094cd82 diff --git a/scripts/cocoapods/jsengine.rb b/scripts/cocoapods/jsengine.rb index 73030a8062a75e..b3e3e4d8173d90 100644 --- a/scripts/cocoapods/jsengine.rb +++ b/scripts/cocoapods/jsengine.rb @@ -60,10 +60,6 @@ def remove_copy_hermes_framework_script_phase(installer, react_native_path) project.save() end -def remove_hermesc_build_dir(react_native_path) - %x(rm -rf #{react_native_path}/sdks/hermes-engine/build_host_hermesc) -end - def is_building_hermes_from_source(react_native_version) is_nightly = react_native_version.start_with?('0.0.0-') has_tarball = ENV['HERMES_ENGINE_TARBALL_PATH'] != nil diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index 910213464d0cce..d3e69f755110fc 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -209,7 +209,6 @@ def react_native_post_install(installer, react_native_path = "../node_modules/re add_copy_hermes_framework_script_phase(installer, react_native_path) else remove_copy_hermes_framework_script_phase(installer, react_native_path) - remove_hermesc_build_dir(react_native_path) end ReactNativePodsUtils.exclude_i386_architecture_while_using_hermes(installer) diff --git a/sdks/hermes-engine/hermes-engine.podspec b/sdks/hermes-engine/hermes-engine.podspec index d25e633536c231..517bc1b247167a 100644 --- a/sdks/hermes-engine/hermes-engine.podspec +++ b/sdks/hermes-engine/hermes-engine.podspec @@ -104,16 +104,10 @@ Pod::Spec.new do |spec| ss.header_dir = 'hermes/Public' end - hermesc_path = "" + hermesc_path = "${PODS_ROOT}/hermes-engine/build_host_hermesc" if ENV.has_key?('HERMES_OVERRIDE_HERMESC_PATH') && File.exist?(ENV['HERMES_OVERRIDE_HERMESC_PATH']) then hermesc_path = ENV['HERMES_OVERRIDE_HERMESC_PATH'] - else - # Keep hermesc_path synchronized with .gitignore entry. - ENV['REACT_NATIVE_PATH'] = react_native_path - hermesc_path = "${REACT_NATIVE_PATH}/sdks/hermes-engine/build_host_hermesc" - # NOTE: Prepare command is not run if the pod is not downloaded. - spec.prepare_command = ". #{react_native_path}/sdks/hermes-engine/utils/build-hermesc-xcode.sh #{hermesc_path}" end spec.user_target_xcconfig = { @@ -125,12 +119,22 @@ Pod::Spec.new do |spec| 'HERMES_CLI_PATH' => "#{hermesc_path}/bin/hermesc" } + CMAKE_BINARY = %x(command -v cmake | tr -d '\n') + # NOTE: Script phases are sorted alphabetically inside Xcode project spec.script_phases = [ { - :name => 'Build Hermes', + :name => '[RN] [1] Build Hermesc', :script => <<-EOS . ${PODS_ROOT}/../.xcode.env - export CMAKE_BINARY=${CMAKE_BINARY:-#{%x(command -v cmake | tr -d '\n')}} + export CMAKE_BINARY=${CMAKE_BINARY:-#{CMAKE_BINARY}} + . ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/build-hermesc-xcode.sh #{hermesc_path} + EOS + }, + { + :name => '[RN] [2] Build Hermes', + :script => <<-EOS + . ${PODS_ROOT}/../.xcode.env + export CMAKE_BINARY=${CMAKE_BINARY:-#{CMAKE_BINARY}} . ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/build-hermes-xcode.sh #{version} #{hermesc_path}/ImportHermesc.cmake EOS } diff --git a/sdks/hermes-engine/utils/build-hermesc-xcode.sh b/sdks/hermes-engine/utils/build-hermesc-xcode.sh index 6b1ea9184d76c9..b8aef2d701ed0e 100755 --- a/sdks/hermes-engine/utils/build-hermesc-xcode.sh +++ b/sdks/hermes-engine/utils/build-hermesc-xcode.sh @@ -8,9 +8,16 @@ set -x hermesc_dir_path="$1" -CMAKE_BINARY=${CMAKE_BINARY:-$(command -v cmake | tr -d '\n')} +# This script is supposed to be executed from Xcode "run script" phase. +# Xcode sets up its build environment based on the build target. +# Here we override relevant envvars to make sure that we build hermesc for macosx, +# even if Xcode build target is iphone, iponesimulator, etc. +MACOSX_DEPLOYMENT_TARGET=$(sw_vers -productVersion) +export MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET +SDKROOT=$(xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk +export SDKROOT=$SDKROOT -if ! "$CMAKE_BINARY" -S . -B "$hermesc_dir_path" +if ! "$CMAKE_BINARY" -S "${PODS_ROOT}/hermes-engine" -B "$hermesc_dir_path" then echo "Failed to configure Hermesc cmake project." exit 1 From 50c6ee40eaf0e559fe272ec18671719eee1e5f29 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 24 Nov 2022 11:22:54 -0800 Subject: [PATCH 53/58] Build RNTester Release inside buildAll (#35464) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35464 This extends the buildAll task to build both RNTester Debug and Release We can finally do this now as debug and release are fully isolated and don't clash on each other. Changelog: [Internal] [Changed] - Build RNTester Release inside buildAll Reviewed By: cipolleschi Differential Revision: D41521995 fbshipit-source-id: 37ec5e3b55080372f01f2736c1bb020b3776b193 --- .circleci/config.yml | 4 ---- build.gradle.kts | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dbc543068e2943..b130c43d02b23f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -716,10 +716,6 @@ jobs: name: Build & Test React Native using Gradle command: ./gradlew buildAll - - run: - name: Build RN Tester for Release using Gradle - command: ./gradlew packages:rn-tester:android:app:assembleRelease - - report_bundle_size: platform: android diff --git a/build.gradle.kts b/build.gradle.kts index bd1b0dc5ac7f99..bcdbd6c874f2a8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -89,8 +89,8 @@ tasks.register("buildAll") { dependsOn(":ReactAndroid:assemble") // This creates all the Maven artifacts and makes them available in the /android folder dependsOn(":ReactAndroid:installArchives") - // This builds RN Tester for Hermes/JSC for debug only - dependsOn(":packages:rn-tester:android:app:assembleDebug") + // This builds RN Tester for Hermes/JSC for debug and release + dependsOn(":packages:rn-tester:android:app:assemble") // This compiles the Unit Test sources (without running them as they're partially broken) dependsOn(":ReactAndroid:compileDebugUnitTestSources") dependsOn(":ReactAndroid:compileReleaseUnitTestSources") From 6a45f2ce79e6ede3d7deac7802cb51fb9ec1cbd6 Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Thu, 24 Nov 2022 13:56:09 -0800 Subject: [PATCH 54/58] refactor(circleci/template): publish all packages to Verdaccio before template initialization (#35459) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35459 Changelog: [Internal] [Changed] - now bootstrapping Verdaccio before template app initialization, this is required because react-native migh depend on some package which version is not yet published to npm Reviewed By: cipolleschi Differential Revision: D41521496 fbshipit-source-id: 6183ab02c697d9d08e9dca5b323bd7a11a749c3a --- .circleci/config.yml | 6 +- scripts/template/README.md | 30 ------- scripts/template/initialize.js | 105 +++++++++++++++++++++++ scripts/template/install-dependencies.js | 67 --------------- scripts/template/verdaccio.yml | 27 ------ 5 files changed, 107 insertions(+), 128 deletions(-) delete mode 100644 scripts/template/README.md create mode 100644 scripts/template/initialize.js delete mode 100644 scripts/template/install-dependencies.js delete mode 100644 scripts/template/verdaccio.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index b130c43d02b23f..feaf635494811f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -764,8 +764,7 @@ jobs: command: | REPO_ROOT=$(pwd) node ./scripts/set-rn-template-version.js "file:$REPO_ROOT/build/$(cat build/react-native-package-version)" - node cli.js init $PROJECT_NAME --directory "/tmp/$PROJECT_NAME" --template $REPO_ROOT --verbose --skip-install - node ./scripts/template/install-dependencies.js --reactNativeRootPath $REPO_ROOT --templatePath "/tmp/$PROJECT_NAME" + node ./scripts/template/initialize.js --reactNativeRootPath $REPO_ROOT --templateName $PROJECT_NAME --templateConfigPath $REPO_ROOT --directory "/tmp/$PROJECT_NAME" - run: name: Build the template application for << parameters.flavor >> with Architecture set to << parameters.architecture >>, and using the << parameters.jsengine>> JS engine. command: | @@ -849,8 +848,7 @@ jobs: PACKAGE=$(cat build/react-native-package-version) PATH_TO_PACKAGE="$REPO_ROOT/build/$PACKAGE" node ./scripts/set-rn-template-version.js "file:$PATH_TO_PACKAGE" - node cli.js init $PROJECT_NAME --directory "/tmp/$PROJECT_NAME" --template $REPO_ROOT --verbose --skip-install - node ./scripts/template/install-dependencies.js --reactNativeRootPath $REPO_ROOT --templatePath "/tmp/$PROJECT_NAME" + node ./scripts/template/initialize.js --reactNativeRootPath $REPO_ROOT --templateName $PROJECT_NAME --templateConfigPath $REPO_ROOT --directory "/tmp/$PROJECT_NAME" - run: name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>>; Flipper << parameters.flipper >> command: | diff --git a/scripts/template/README.md b/scripts/template/README.md deleted file mode 100644 index 657b9c39b99f65..00000000000000 --- a/scripts/template/README.md +++ /dev/null @@ -1,30 +0,0 @@ -## Why? - -The main purpose of `install-dependencies.js` is to bootstrap [Verdaccio](https://verdaccio.org/docs/what-is-verdaccio). It will host all the local packages, which are not yet present on npm registry. In the near future this should help us in keep template tests green, because once we move to [monorepo structure](https://github.com/react-native-community/discussions-and-proposals/pull/480), template app may use some versions of dependencies that are not yet present on npm registry. - -## I have migrated some module to package, which is not yet published to npm, how to use it? - -First of all, you need to modify [Verdaccio config](https://github.com/facebook/react-native/tree/main/scripts/template/verdaccio.yml): -```diff - packages: -+ '': -+ access: $all -+ publish: $all - '@*/*': - access: $all - publish: $authenticated - proxy: npmjs - '**': - access: $all - publish: $all - proxy: npmjs -``` - -After that, you should modify [install-dependencies script](https://github.com/facebook/react-native/tree/main/scripts/template/install-dependencies.js) to include your package for publishing - -```diff -const PACKAGES_TO_PUBLISH_PATHS = [ - ... -+ "packages/" -]; -``` diff --git a/scripts/template/initialize.js b/scripts/template/initialize.js new file mode 100644 index 00000000000000..eb8dc7e82b999f --- /dev/null +++ b/scripts/template/initialize.js @@ -0,0 +1,105 @@ +/** + * 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 + */ + +'use strict'; + +const yargs = require('yargs'); +const {execSync, spawnSync} = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +const setupVerdaccio = require('../setup-verdaccio'); + +const {argv} = yargs + .option('r', { + alias: 'reactNativeRootPath', + describe: 'Path to root folder of react-native', + required: true, + }) + .option('n', { + alias: 'templateName', + describe: 'Template App name', + required: true, + }) + .option('tcp', { + alias: 'templateConfigPath', + describe: 'Path to folder containing template config', + required: true, + }) + .option('d', { + alias: 'directory', + describe: 'Path to template application folder', + required: true, + }) + .strict(); + +const {reactNativeRootPath, templateName, templateConfigPath, directory} = argv; + +const VERDACCIO_CONFIG_PATH = `${reactNativeRootPath}/.circleci/verdaccio.yml`; + +function readPackageJSON(pathToPackage) { + return JSON.parse(fs.readFileSync(path.join(pathToPackage, 'package.json'))); +} + +function install() { + const yarnWorkspacesStdout = execSync('yarn --json workspaces info', { + cwd: reactNativeRootPath, + encoding: 'utf8', + }); + const packages = JSON.parse(JSON.parse(yarnWorkspacesStdout).data); + + const VERDACCIO_PID = setupVerdaccio( + reactNativeRootPath, + VERDACCIO_CONFIG_PATH, + ); + process.stdout.write('Bootstrapped Verdaccio \u2705\n'); + + process.stdout.write('Starting to publish all the packages...\n'); + Object.entries(packages).forEach(([packageName, packageEntity]) => { + const packageManifest = readPackageJSON(packageAbsolutePath); + if (packageManifest.private) { + return; + } + + const packageRelativePath = packageEntity.location; + const packageAbsolutePath = `${reactNativeRootPath}/${packageRelativePath}`; + + execSync('npm publish --registry http://localhost:4873 --access public', { + cwd: `${reactNativeRootPath}/${packageEntity.location}`, + stdio: [process.stdin, process.stdout, process.stderr], + }); + + process.stdout.write(`Published ${packageName} to proxy \u2705\n`); + }); + process.stdout.write('Published all packages \u2705\n'); + + execSync( + `node cli.js init ${templateName} --directory ${directory} --template ${templateConfigPath} --verbose --skip-install`, + { + cwd: reactNativeRootPath, + stdio: [process.stdin, process.stdout, process.stderr], + }, + ); + process.stdout.write('Completed initialization of template app \u2705\n'); + + process.stdout.write('Installing dependencies in template app folder...\n'); + spawnSync('yarn', ['install'], { + cwd: directory, + stdio: [process.stdin, process.stdout, process.stderr], + }); + process.stdout.write('Installed dependencies via Yarn \u2705\n'); + + process.stdout.write(`Killing verdaccio. PID — ${VERDACCIO_PID}...\n`); + execSync(`kill -9 ${VERDACCIO_PID}`); + process.stdout.write('Killed Verdaccio process \u2705\n'); + + process.exit(); +} + +install(); diff --git a/scripts/template/install-dependencies.js b/scripts/template/install-dependencies.js deleted file mode 100644 index 47f4eb492c41e4..00000000000000 --- a/scripts/template/install-dependencies.js +++ /dev/null @@ -1,67 +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 - */ - -'use strict'; - -const yargs = require('yargs'); -const {execSync, spawnSync} = require('child_process'); -const setupVerdaccio = require('../setup-verdaccio'); - -const {argv} = yargs - .option('r', { - alias: 'reactNativeRootPath', - describe: 'Path to root folder of react-native', - required: true, - }) - .option('c', { - alias: 'templatePath', - describe: 'Path to template application folder', - required: true, - }) - .strict(); - -const {reactNativeRootPath, templatePath} = argv; - -const VERDACCIO_CONFIG_PATH = `${reactNativeRootPath}/scripts/template/verdaccio.yml`; -const VERDACCIO_STORAGE_PATH = `${templatePath}/node_modules`; - -const PACKAGES_TO_PUBLISH_PATHS = []; - -function install() { - const VERDACCIO_PID = setupVerdaccio( - reactNativeRootPath, - VERDACCIO_CONFIG_PATH, - VERDACCIO_STORAGE_PATH, - ); - process.stdout.write('Bootstrapped Verdaccio \u2705\n'); - - // Publish all necessary packages... - for (const packagePath of PACKAGES_TO_PUBLISH_PATHS) { - execSync('npm publish --registry http://localhost:4873 --access public', { - cwd: `${reactNativeRootPath}/${packagePath}`, - stdio: [process.stdin, process.stdout, process.stderr], - }); - - process.stdout.write(`Published /${packagePath} to proxy \u2705\n`); - } - - spawnSync('yarn', ['install'], { - cwd: templatePath, - stdio: [process.stdin, process.stdout, process.stderr], - }); - process.stdout.write('Installed dependencies via Yarn \u2705\n'); - - process.stdout.write(`Killing verdaccio. PID — ${VERDACCIO_PID}...\n`); - execSync(`kill -9 ${VERDACCIO_PID}`); - process.stdout.write('Killed Verdaccio process \u2705\n'); - - process.exit(); -} - -install(); diff --git a/scripts/template/verdaccio.yml b/scripts/template/verdaccio.yml deleted file mode 100644 index 03ebcfdc7e1dc0..00000000000000 --- a/scripts/template/verdaccio.yml +++ /dev/null @@ -1,27 +0,0 @@ -storage: ./storage -auth: - htpasswd: - file: ./htpasswd -uplinks: - npmjs: - url: https://registry.npmjs.org/ - max_fails: 40 - maxage: 30m - timeout: 60s - fail_timeout: 10m - cache: false - agent_options: - keepAlive: true - maxSockets: 40 - maxFreeSockets: 10 -packages: - '@*/*': - access: $all - publish: $authenticated - proxy: npmjs - '**': - access: $all - publish: $all - proxy: npmjs -logs: - - {type: file, path: verdaccio.log, format: json, level: warn} From 1f8c0c88609c655541d525ed1f9e5e37255fbac7 Mon Sep 17 00:00:00 2001 From: Petr Bela Date: Thu, 24 Nov 2022 18:26:36 -0800 Subject: [PATCH 55/58] remove return type from constructor (#35466) Summary: I'm getting `node_modules/react-native/Libraries/Events/EventPolyfill.js: Unexpected token, expected "{"` when building an app. Looking at the source code, it seems odd there'd be a return type defined for a constructor. Unless I'm missing something (I don't use flow), I think it should be removed? ## Changelog [Internal] [Fixed] - Remove return type from constructor Pull Request resolved: https://github.com/facebook/react-native/pull/35466 Test Plan: N/A Reviewed By: jacdebug Differential Revision: D41527010 Pulled By: yungsters fbshipit-source-id: 9f4faf1305ebe1915f5bcf07fc86b7437aed0c97 --- Libraries/Events/EventPolyfill.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Events/EventPolyfill.js b/Libraries/Events/EventPolyfill.js index e6e0e7b12805b8..dda91a3f4e5739 100644 --- a/Libraries/Events/EventPolyfill.js +++ b/Libraries/Events/EventPolyfill.js @@ -159,7 +159,7 @@ class EventPolyfill implements IEvent { // data with the other in sync. _syntheticEvent: mixed; - constructor(type: string, eventInitDict?: Event$Init): void { + constructor(type: string, eventInitDict?: Event$Init) { this.type = type; this.bubbles = !!(eventInitDict?.bubbles || false); this.cancelable = !!(eventInitDict?.cancelable || false); From e6800181094f7b998e95844d993b03991a4ff865 Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Fri, 25 Nov 2022 01:07:42 -0800 Subject: [PATCH 56/58] fix(ci/template): fixed unresolved variable in script Summary: Changelog: [Internal] [Changed] - fixed unresolved variable in template initialization script Reviewed By: cipolleschi Differential Revision: D41527165 fbshipit-source-id: acdd8d4cf9fb6153022b0395d3715ca9ca6363c9 --- scripts/template/initialize.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/template/initialize.js b/scripts/template/initialize.js index eb8dc7e82b999f..b0cfaf9365af2b 100644 --- a/scripts/template/initialize.js +++ b/scripts/template/initialize.js @@ -62,14 +62,14 @@ function install() { process.stdout.write('Starting to publish all the packages...\n'); Object.entries(packages).forEach(([packageName, packageEntity]) => { + const packageRelativePath = packageEntity.location; + const packageAbsolutePath = `${reactNativeRootPath}/${packageRelativePath}`; + const packageManifest = readPackageJSON(packageAbsolutePath); if (packageManifest.private) { return; } - const packageRelativePath = packageEntity.location; - const packageAbsolutePath = `${reactNativeRootPath}/${packageRelativePath}`; - execSync('npm publish --registry http://localhost:4873 --access public', { cwd: `${reactNativeRootPath}/${packageEntity.location}`, stdio: [process.stdin, process.stdout, process.stderr], From c4959b98069ffbd1e82cc13e031d154ce0e88083 Mon Sep 17 00:00:00 2001 From: Lorenzo Sciandra Date: Fri, 25 Nov 2022 03:26:20 -0800 Subject: [PATCH 57/58] fix(e2e script): backport from 71 fixes to the E2E script (#35477) Summary: Because the /scripts folder for some reason is not typechecked at all, some changes broke the script and went undetected until we tried running it. This is a backport of those fixes: * https://github.com/facebook/react-native/commit/67c373ff3a4ab0dfaaa752f08f6cc22657d4dadc * https://github.com/facebook/react-native/commit/6107793fda11a85297b3a3e2b8f259930d6c0f41 * https://github.com/facebook/react-native/commit/6107793fda11a85297b3a3e2b8f259930d6c0f41 Also, it's backporting an improvement to the e2e local script clean to remove the hermes-engine pod cache which has been proven annoyingly in the way while testing: * https://github.com/facebook/react-native/commit/9979e38c7093ba78db5d5b4b11456c78592ea8c5 ## Changelog [Internal] [Fixed] - Fix e2e script not working and augment clean script Pull Request resolved: https://github.com/facebook/react-native/pull/35477 Test Plan: Works on 0.71 ;) Reviewed By: dmytrorykun Differential Revision: D41530272 Pulled By: jacdebug fbshipit-source-id: d45650d919ad5ef08438b307f122817d72771f46 --- scripts/release-utils.js | 2 -- scripts/test-e2e-local-clean.js | 3 +++ scripts/test-e2e-local.js | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/release-utils.js b/scripts/release-utils.js index 077096aa48fdec..8c55be3d3bce03 100644 --- a/scripts/release-utils.js +++ b/scripts/release-utils.js @@ -85,7 +85,6 @@ function generateiOSArtifacts( jsiFolder, hermesCoreSourceFolder, buildType, - releaseVersion, targetFolder, ) { pushd(`${hermesCoreSourceFolder}`); @@ -109,7 +108,6 @@ function generateiOSArtifacts( const tarballOutputPath = createHermesPrebuiltArtifactsTarball( hermesCoreSourceFolder, buildType, - releaseVersion, targetFolder, true, // this is excludeDebugSymbols, we keep it as the default ); diff --git a/scripts/test-e2e-local-clean.js b/scripts/test-e2e-local-clean.js index 59f6333d793ffa..37ca37032732b5 100644 --- a/scripts/test-e2e-local-clean.js +++ b/scripts/test-e2e-local-clean.js @@ -49,6 +49,9 @@ exec('rm -rf /tmp/maven-local'); console.info('\n** Nuking the derived data folder **\n'); exec('rm -rf ~/Library/Developer/Xcode/DerivedData'); +console.info('\n** Removing the hermes-engine pod cache **\n'); +exec('rm -rf ~/Library/Caches/CocoaPods/Pods/External/hermes-engine'); + // RNTester Pods console.info('\n** Removing the RNTester Pods **\n'); exec('rm -rf packages/rn-tester/Pods'); diff --git a/scripts/test-e2e-local.js b/scripts/test-e2e-local.js index 09b095d9ad59b0..03605481c676a0 100644 --- a/scripts/test-e2e-local.js +++ b/scripts/test-e2e-local.js @@ -198,7 +198,7 @@ if (argv.target === 'RNTester') { // for this scenario, we only need to create the debug build // (env variable PRODUCTION defines that podspec side) - const buildType = 'Debug'; + const buildTypeiOSArtifacts = 'Debug'; // the android ones get set into /private/tmp/maven-local const localMavenPath = '/private/tmp/maven-local'; @@ -207,8 +207,7 @@ if (argv.target === 'RNTester') { const tarballOutputPath = generateiOSArtifacts( jsiFolder, hermesCoreSourceFolder, - buildType, - releaseVersion, + buildTypeiOSArtifacts, localMavenPath, ); From 2d1d61a38c7de800aae35771873b00cba50aefc9 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 25 Nov 2022 04:01:31 -0800 Subject: [PATCH 58/58] Move on-issue-labeled to use actions/github-script@v6 (#35474) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35474 This cleans up our `on-issue-labeled` workflow and makes sure we use only github-scripts. So we don't need to checkout the code & run an external action. Changelog: [Internal] [Changed] - Move on-issue-labeled to use actions/github-script@v6 Reviewed By: cipolleschi Differential Revision: D41522650 fbshipit-source-id: c93d10eddf5be2ca9f779389e8059633291c0138 --- .github/respond-to-issue-based-on-label.yml | 52 ------- .github/workflows/on-issue-labeled.yml | 163 ++++++++++++++++++-- 2 files changed, 153 insertions(+), 62 deletions(-) delete mode 100644 .github/respond-to-issue-based-on-label.yml diff --git a/.github/respond-to-issue-based-on-label.yml b/.github/respond-to-issue-based-on-label.yml deleted file mode 100644 index acb89311bc4fb9..00000000000000 --- a/.github/respond-to-issue-based-on-label.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Configuration for Respond To Issue Based on Label https://github.com/marketplace/actions/respond-to-issue-based-on-label - -"Type: Invalid": - close: true -"Type: Question": - comment: > - We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/). - close: true -"Type: Docs": - comment: > - Please report documentation issues in the [`react-native-website`](https://github.com/facebook/react-native-website/issues) repository. - close: true -"Resolution: For Stack Overflow": - comment: > - We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question. - close: true -"Needs: Issue Template": - comment: > -
:warning: - Missing Required Fields -
:information_source: - It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a new issue is created. Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one. -
- labels: - - "Needs: Author Feedback" -"Needs: Environment Info": - comment: > -
:warning: - Missing Environment Information -
:information_source: - Your issue may be missing information about your development environment. You can obtain the missing information by running react-native info in a console. -
- labels: - - "Needs: Author Feedback" -"Needs: Verify on Latest Version": - comment: > -
:warning: - Using Old Version -
:information_source: - It looks like you are using an older version of React Native. Please upgrade to the latest version, and verify if the issue persists. If it does not, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the current release. -
- labels: - - "Needs: Author Feedback" -"Needs: Repro": - comment: > -
:warning: - Missing Reproducible Example -
:information_source: - It looks like your issue is missing a reproducible example. Please provide a Snack or a repository that demonstrates the issue you are reporting in a minimal, complete, and reproducible manner. -
- labels: - - "Needs: Author Feedback" diff --git a/.github/workflows/on-issue-labeled.yml b/.github/workflows/on-issue-labeled.yml index f99404e94fae8a..60401ecf5b1f0d 100644 --- a/.github/workflows/on-issue-labeled.yml +++ b/.github/workflows/on-issue-labeled.yml @@ -5,18 +5,161 @@ on: types: labeled permissions: - contents: read + contents: write + issues: write jobs: - respondToIssueBasedOnLabel: - permissions: - contents: read # for hramos/respond-to-issue-based-on-label to fetch config file - issues: write # for hramos/respond-to-issue-based-on-label to update issues - name: Respond to Issue Based on Label + type-invalid: runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Type: Invalid') }}" steps: - - uses: actions/checkout@v3 - - name: Respond to Issue Based on Label - uses: hramos/respond-to-issue-based-on-label@v2 + - uses: actions/github-script@v6 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + script: | + await github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + state: "closed", + }) + type-question: + runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Type: Question') }}" + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).`, + }) + await github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + state: "closed", + }) + type-docs: + runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Type: Docs') }}" + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository.`, + }) + await github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + state: "closed", + }) + resolution-for-stack-overflow: + runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Resolution: For Stack Overflow') }}" + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question.`, + }) + await github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + state: "closed", + }) + needs-issue-template: + runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Needs: Issue Template') }}" + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `| :warning: | Missing Required Fields | + | --- | --- | + | :information_source: | It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a [new issue is created](https://github.com/facebook/react-native/issues/new?template=bug_report.md). Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one. |`, + }) + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['Needs: Author Feedback'] + }) + needs-environment-info: + runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Needs: Environment Info') }}" + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `| :warning: | Missing Environment Information | + | --- | --- | + | :information_source: | Your issue may be missing information about your development environment. You can obtain the missing information by running react-native info in a console. |`, + }) + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['Needs: Author Feedback'] + }) + needs-verify-on-latest-version: + runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Needs: Verify on Latest Version') }}" + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `| :warning: | Using Old Version | + | --- | --- | + | :information_source: | It looks like you are using an older version of React Native. Please [upgrade](https://reactnative.dev/docs/upgrading) to the latest version, and verify if the issue persists. If it does not, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the current release. |`, + }) + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['Needs: Author Feedback'] + }) + needs-repro: + runs-on: ubuntu-latest + if: "${{ contains(github.event.label.name, 'Needs: Repro') }}" + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `| :warning: | Missing Reproducible Example | + | --- | --- | + | :information_source: | It looks like your issue is missing a reproducible example. Please provide a [Snack](https://snack.expo.dev) or a repository that demonstrates the issue you are reporting in a [minimal, complete, and reproducible](https://stackoverflow.com/help/minimal-reproducible-example) manner. |`, + }) + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['Needs: Author Feedback'] + })