Compare commits

..
Author SHA1 Message Date
React Native Bot b5b57731d3 Release 0.75.1
#publish-packages-to-npm&latest
2024-08-15 10:54:32 +00:00
Riccardo Cipolleschi c1cee11932 [LOCAL] Use fetch-depth to 0 to create a release 2024-08-15 11:52:12 +01:00
Riccardo Cipolleschi 077815358d [LOCAL][RN][CI] Make sure to fetch all tags 2024-08-15 11:47:48 +01:00
Riccardo CipolleschiandGitHub 8ab64afd3a [LOCAL][RN][CI] Use the right param to set the 'latest' tag (#46033) 2024-08-15 11:37:41 +01:00
Nicola Corti d94d447777 [LOCAL] Manual cherry-pick of 28597168aa 2024-08-15 10:31:39 +01:00
Nicola Corti 41b188b7e6 [LOCAL] Fix further compilation error introduced by cherry-pick conflicts 2024-08-15 10:29:13 +01:00
Nicola Corti a3187bb5d9 [LOCAL] Fix compilation error introduced by cherry-pick conflicts 2024-08-15 08:53:45 +01:00
Nicola Corti f202e80177 [LOCAL] Bump Hermes version 2024-08-15 08:20:44 +01:00
Nick GerlemanandNicola Corti 8c4f240c9b Gate off % border radii on Android Paper (#45945)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45945

This code is forked on iOS, where we have been, as a policy, avoiding Paper-specific changes. This code is shared between renderers on Android, but it is confusing developer experience to have it work on Android Paper, to then fail on iOS unless it is on new arch.

This change disables support on Android Paper for consistency.

Changelog:
[Android][Removed] - Gate off % border radii on Android Paper

Reviewed By: cortinico

Differential Revision: D60967347

fbshipit-source-id: 1d26bc71aee677aa9a0dc9bb38f781a99c7762a8
2024-08-15 08:16:04 +01:00
Nick GerlemanandNicola Corti b64f5498f6 Gate off % translate on Android Paper (#45946)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45946

This code is forked on iOS, where we have been, as a policy, avoiding Paper-specific changes. This code is shared between renderers on Android, but it is confusing developer experience to have it work on Android Paper, to then fail on iOS unless it is on new arch.

This change disables support on Android Paper for consistency.

Changelog:
[Android][Removed] - Gate off % translate on Android Paper

Reviewed By: joevilches

Differential Revision: D60970266

fbshipit-source-id: 5df73b948464f5093941528b0af2e694827a9460
2024-08-15 08:11:45 +01:00
Nicola Corti efe8a5e85a [LOCAL] Update Podfile.lock
Changelog: [Internal]
2024-08-15 08:09:22 +01:00
React Native Bot 89cdc14c8b Release 0.75.0
#publish-packages-to-npm&latest
2024-08-14 14:54:23 +00:00
Blake FriedmanandRiccardo Cipolleschi 9120cd30f2 Move init deprecation notice 30 Sept → 31 Dec (#45590)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45590

This gives us more wiggle room with the release of 0.76.

Changelog: [General][Changed] Move init deprecation notice 30 Sept → 31 Dec

Reviewed By: cortinico

Differential Revision: D60105868

fbshipit-source-id: d03fcf5d4a97db9b21792eff6f993e2671b276ef
2024-08-14 14:30:23 +01:00
Gabriel DonadelandRiccardo Cipolleschi 34c91036e1 Add shared-testutil folder to NPM files to be published (#45936)
Summary:
React-native 0.75 RC7 gradle sync is currently broken due to the fact that the `shared-testutil` folder is missing from the `react-native/gradle-plugin` npm package

## Changelog:

[INTERNAL] [ADDED] - Add shared-testutil folder to NPM files to be published

Pull Request resolved: https://github.com/facebook/react-native/pull/45936

Test Plan: N/A

Reviewed By: cipolleschi

Differential Revision: D60969631

Pulled By: cortinico

fbshipit-source-id: 850edfe0cf6b0e8174a1df9ea962d207d2ce0112
2024-08-14 14:29:29 +01:00
Nicola CortiandGitHub 82ddf5d532 [LOCAL] Bump Node on CircleCI to 18.18 to fix red signal (#45894) 2024-08-07 14:16:38 +01:00
React Native Bot 7244893b12 Release 0.75.0-rc.7
#publish-packages-to-npm&next
2024-08-06 11:16:54 +00:00
Nicola Corti b0662b3c33 [LOCAL] All librrc_textinput.so to NdkConfiguratorUtils.configureNewArchPackagingOptions 2024-08-06 11:44:06 +01:00
Riccardo Cipolleschi 6250409a62 [LOCAL] Bump Podfile.lock 2024-08-06 10:18:46 +01:00
szymonrybczakandRiccardo Cipolleschi b62bfcd561 feat: update CLI to 14.0.0 (#45540)
Summary:
Update to stable version of `react-native-community/cli`.

[GENERAL] [CHANGED] - Upgrade `react-native-community/cli` to `13.6.9`

Pull Request resolved: https://github.com/facebook/react-native/pull/45540

Test Plan: n/a

Reviewed By: blakef

Differential Revision: D59960021

Pulled By: cortinico

fbshipit-source-id: 9d470699cdd2d20e08e844c92c7982056aec082c
2024-08-05 13:25:56 +01:00
React Native Bot 7e98cdba8a Release 0.75.0-rc.6
#publish-packages-to-npm&next
2024-07-29 16:54:09 +00:00
Nicola Corti 51156fd3b2 [LOCAL] Fix broken build of RNGP due to complex cherry-pick 2024-07-29 15:40:56 +01:00
Nicola CortiandGitHub c8cb3d4a59 [0.75] Fix core autolinking not working on Windows (#45796) 2024-07-29 14:43:00 +01:00
Riccardo CipolleschiandGitHub 011118fe13 [LOCAL][RN] Revert React from 19Rc to 18.3.1 (#45779)
* Revert ReacRevert React from 19 to 18.3.1 due to React 19 not being out as stable

\## Changelog
[General][Changed] - Revert from React 19 RC to React 18.3.1

* Revert from React 19 RC to React 18.3.1

\## Changelog
[General][Changed] - Revert from React 19RC to React 18.3.1

* Fix ruby tests
2024-07-29 14:36:44 +01:00
Gabriel DonadelandRiccardo Cipolleschi 88f2a24b5d RNGP - Filter out null dependencies from getGradleDependenciesToApply (#45749)
Summary:
`getGradleDependenciesToApply` tries to call `implementation:` in all libraries, including the ones that are not supported on Android.

## Changelog:

[INTERNAL] [FIXED] - Filter out platform-specific libraries from the auto-linking gradle plugin

Pull Request resolved: https://github.com/facebook/react-native/pull/45749

Test Plan: CI should be green

Reviewed By: cipolleschi

Differential Revision: D60374769

Pulled By: cortinico

fbshipit-source-id: 33c83e9cc39d81b0e5c497570a936831ebb345f9
2024-07-29 14:25:38 +01:00
Jakub PiaseckiandGitHub ea8ad6457c [LOCAL] Make rrc_textinput on Android a shared library (#45592) 2024-07-29 14:24:49 +01:00
CHEN Xian-anandRiccardo Cipolleschi e39e9c4a60 Not all the targets have a defined symbol_type (#45591)
Summary:
Errors occurred on running `pod install`:

```
[!] An error occurred while processing the post-install hook of the Podfile.

undefined method `symbol_type' for #<Xcodeproj::Project::Object::PBXAggregateTarget:0x000000010f6ea568>

[redact]/node_modules/react-native/scripts/cocoapods/privacy_manifest_utils.rb:53:in `block in get_application_targets'
```

## Changelog:

[iOS] [Fixed] - Fix error on handling privacy manifest

Pull Request resolved: https://github.com/facebook/react-native/pull/45591

Reviewed By: cipolleschi

Differential Revision: D60107607

Pulled By: dmytrorykun

fbshipit-source-id: 316220fe54174b18c9b61775f807d5d05d9f0240
2024-07-29 14:20:57 +01:00
Riccardo Cipolleschi 9fac7bdc43 Revert "Release 0.75.0-rc.6"
Changelog:
[Internal] - Revert release commit
2024-07-29 14:15:02 +01:00
React Native Bot a36476395a Release 0.75.0-rc.6
#publish-packages-to-npm&next
2024-07-22 16:55:20 +00:00
Riccardo Cipolleschi a91b9bff5d [LOCAL][RN][Release] Test Debug APK rather than Release APK 2024-07-22 14:41:11 +01:00
Riccardo CipolleschiandGitHub 9594d36d4a [LOCAL][RN][Release] Add logging to E2E test script (#45532) 2024-07-22 14:32:18 +01:00
szymonrybczakandRiccardo Cipolleschi 5189e457a4 feat: update CLI to 14.0.0 (#45540)
Summary:
Update to stable version of `react-native-community/cli`.

[GENERAL] [CHANGED] - Upgrade `react-native-community/cli` to `13.6.9`

Pull Request resolved: https://github.com/facebook/react-native/pull/45540

Test Plan: n/a

Reviewed By: blakef

Differential Revision: D59960021

Pulled By: cortinico

fbshipit-source-id: 9d470699cdd2d20e08e844c92c7982056aec082c
2024-07-22 14:31:43 +01:00
Gabriel DonadelandRiccardo Cipolleschi 88276c51ad Restore CLI_PATH variable in react-native-xcode script (#45560)
Summary:
When changing the `react-native-xcode.sh` logic to use the helloworld cli on https://github.com/facebook/react-native/pull/44721, the `CLI_PATH` env var was removed along with `BUNDLE_COMMAND`. Both of these values were used by Expo to override the default CLI and use our custom bundling command.

https://github.com/expo/expo/blob/10e302ee13add0e24a08c7ee792c2da50ace95a6/templates/expo-template-bare-minimum/ios/HelloWorld.xcodeproj/project.pbxproj#L215C4-L215C15

This restores the `CLI_PATH` variable and set the default value as `"$REACT_NATIVE_DIR/scripts/bundle.js"`, along with the `BUNDLE_COMMAND` variable. With this Expo and other frameworks can keep the ability to easily replace the internal CLI

## Changelog:

[INTERNAL] [CHANGED] - Restore CLI_PATH variable in react-native-xcode script

Pull Request resolved: https://github.com/facebook/react-native/pull/45560

Test Plan: Project compiles correctly on iOS

Reviewed By: robhogan

Differential Revision: D60035338

Pulled By: blakef

fbshipit-source-id: 26583d11d9f573f7cfa405b68e0cc3304c3601df
2024-07-22 14:28:35 +01:00
Douglas LowderandRiccardo Cipolleschi 72a38aace2 fix: Remove setting of process.exitCode that breaks Jest tests (#45562)
Summary:
In Node 20, the script to run unit tests in CI (`scripts/run-ci-javascript-tests.js`) will fail, even when all the Jest tests pass. This happens because one of the JS modules being tested is setting `process.exitCode` (see https://github.com/jestjs/jest/issues/9324#issuecomment-1808090455).

Changes:

- Modified the affected module to throw an exception when failing, instead of setting the exit code
- Adjusted the unit test for that module

## Changelog:

[General] [Fixed] - Remove setting of process.exitCode that breaks Jest tests

Pull Request resolved: https://github.com/facebook/react-native/pull/45562

Test Plan:
Before this change, running `node scripts/run-ci-javascript-tests.js` would fail with Node 20.
After this change, it succeeds.

Reviewed By: blakef

Differential Revision: D60033582

Pulled By: cipolleschi

fbshipit-source-id: 71b7f4495d414e719a9bd2d892bd1bc3045ddd5d
2024-07-22 14:28:05 +01:00
nik910andRiccardo Cipolleschi d4b3fc9ed8 Adding space to $(inherited) string to avoid merging of inherited and… (#45520)
Summary:
Added space to $(inherited) string to avoid creation of wrong cpp flags in RCTAppDelegate podspec

<img width="1157" alt="Screenshot 2024-07-18 at 8 51 19 PM" src="https://github.com/user-attachments/assets/29d32d08-e81f-4c25-b8ee-5dccc0f620ea">

## Changelog:

[IOS] [FIXED] - Building of iOS project when RCTAppDelegate is used in the project

Pull Request resolved: https://github.com/facebook/react-native/pull/45520

Test Plan: To test this you can simply change in your node modules and run pod install, the build will now work successfully

Reviewed By: cipolleschi

Differential Revision: D59950906

Pulled By: arushikesarwani94

fbshipit-source-id: 0d58620aa0be7ac4fcbcd309f06df0eef7844016
2024-07-22 14:27:38 +01:00
Riccardo Cipolleschi 9ec4af86a7 Fix path to node in .xcode.env.local (#43333)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43333

This change fixes https://github.com/facebook/react-native/issues/43285.
Basically, when using a `yarn` alias to install pods, yarn creates a copy of the `node` and `yarn` executables and the `command -v node` command will return the path to that executable.

## Changelog
[iOS][Fixed] - Do not use temporary node when creating the .xcode.env.local

Reviewed By: dmytrorykun

Differential Revision: D54542774

fbshipit-source-id: 3ab0d0bb441988026feff9d5390dcfd10869a1b5
2024-07-22 14:27:09 +01:00
Nicola CortiandRiccardo Cipolleschi 648520be32 Add react-native.config.js to autolinking lockfiles (#45511)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45511

This adds react-native.config.js to autolinking default lockfiles
so autolinking can account for changes in that file.

Changelog:
[Internal] [Changed] - Add react-native.config.js to autolinking lockfiles

Reviewed By: blakef

Differential Revision: D59907268

fbshipit-source-id: d5893a3f7b4d5d9f6c6c13042aa6866ad16b2ea4
2024-07-22 14:26:50 +01:00
Blake FriedmanandRiccardo Cipolleschi 53e62de9c7 always proxy to @react-native-community/cli (#45464)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45464

Previous work would cause versions >= react-native 0.76 to exit if called through `npx react-native <cmd>`. This was intended to be full deprecated and removed.  The intention was to shift users to calling react-native-community/cli directly.

This change allows commands to be proxied to react-native-community/cli but with no guarantees of success.  It's up to each framework / project to explicitly create that dependency.

This also  provides warnings, which won't go away, suggesting the supported method of calling the community CLI directly.

The outcome is that we're not going to break existing workflows.

closes: #45461

Changelog: [General][Fixed] allow proxying commands from react-native to react-native-community/cli with explicit warning

Reviewed By: cortinico

Differential Revision: D59805357

fbshipit-source-id: 21e23b082a9c709effa050d8e7dd04a40f5ab0e6
2024-07-22 14:26:27 +01:00
Nicola CortiandRiccardo Cipolleschi c75ec15b48 Unbreak RNTester instacrashing on main (#45467)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45467

This unbreaks RNTester instacrashing on main.

Changelog:
[Internal] [Changed] - Unbreak RNTester instacrashing on main

Reviewed By: javache

Differential Revision: D59806826

fbshipit-source-id: 6d5246cd02e2c364068d047b973b2954b459df1e
2024-07-22 14:25:53 +01:00
Blake FriedmanandRiccardo Cipolleschi 4f6f0a19cf publish template on publishing release (#45327)
Summary:
Call the react-native-community/template GHA to trigger a new release when we publish a react-native release. This then waits to confirm that the package is published.

See react-native-community/template#36 for the matching change

Changelog: [General][Added] trigger template publish

Pull Request resolved: https://github.com/facebook/react-native/pull/45327

Test Plan: Not sure on the best way forward here.

Reviewed By: cipolleschi

Differential Revision: D59467829

Pulled By: blakef

fbshipit-source-id: 091269e7ecdae5801ac7c03a1ede54452ae99b24
2024-07-22 14:25:19 +01:00
Blake Friedman 7d0ec89498 Update Podfile.lock
Changelog: [Internal]
2024-07-16 15:12:22 +01:00
React Native Bot 46b269dd46 Release 0.75.0-rc.5
#publish-packages-to-npm&next
2024-07-15 17:06:25 +00:00
Riccardo Cipolleschi 0e56bce6ba [LOCAL] Fix React-perflogger.podspec conflict 2024-07-15 16:24:47 +02:00
Riccardo CipolleschiandBlake Friedman d0c94d6de1 Factor out the CXX language standard in a separate const (#45374)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45374

This change factors out the language standard in a separate constant so we can easily control it from a single place.

There are only 2 exception to this:
1. hermes-engine: the podspec is used in CI and it has no access to the rct_cxx_language_standard variable
2. Yoga: it can be used as a separate pod, outside of React Native, so it makes sense to leave it alone.

This change also fixes a problem where, in some setup, the language was set to C++14

[Internal] - Refactor Cxx language standard in a single constant

Reviewed By: dmytrorykun, blakef

Differential Revision: D59629061

fbshipit-source-id: 41eac64e47c14e239d8ee78bd88ea30af244d695
2024-07-15 14:45:14 +01:00
Riccardo CipolleschiandBlake Friedman 28d171993e Make sure to pass the BridgeProxy to view managers in the interop layer (#45329)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45329

Thanks to [#45232](https://github.com/facebook/react-native/issues/45232) we found a bug in the interop layer, where we were not passing the BridgeProxy in bridgeless mode to the view managers.

This Change should fix that issue.

## Changelog:
[iOS][Fixed] - Make sure to pass the RCTBridgeProxy to  ViewManagers

Reviewed By: dmytrorykun

Differential Revision: D59468292

fbshipit-source-id: 00666be21385a735878eb567c4b8a0986c609c5f
2024-07-15 14:43:48 +01:00
Nick GerlemanandBlake Friedman 7484e72210 Fix "Platform.constants.reactNativeVersion.prerelease" Flow and TypeScript types (#45256)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45256

The actual stamped versions here are all strings.

Android interface for constants is untyped, and we always return a string here. iOS, we will try to parse the string into a double, which will fail for every prerelease version RN has ever published.

Platform on Windows seems to uniquely be doing the right thing.

Changelog:
[General][Fixed] - Fix Platform.constants.reactNativeVersion type

Reviewed By: robhogan, necolas

Differential Revision: D59141948

fbshipit-source-id: 9c758e5eb8796b03197258d87ec06b31018e211c
2024-07-15 14:43:12 +01:00
Wojciech LewickiandBlake Friedman 58bbbff4d7 feat: expose prefabs for newly added targets (#45386)
Summary:
In recent commits, some new targets have been added, and they are not exposed as prefabs, yet are used in e.g. `TextLayoutManager`. They are needed then for `react-native-live-markdown`: https://github.com/Expensify/react-native-live-markdown/pull/428/commits/c1611cd98ed5009fd66c871b9999b55941086af0

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] [ADDED] - expose prefabs for newly added targets

Pull Request resolved: https://github.com/facebook/react-native/pull/45386

Test Plan: It cannot be tested inside the repo, but try to build the `example` app with new arch enabled on `Android` in the `react-native-live-markdown` repo to see that those are needed.

Reviewed By: NickGerleman

Differential Revision: D59638801

Pulled By: cortinico

fbshipit-source-id: 3d09507d72a0c4d3dbb3a2a81b753625230a04a3
2024-07-15 14:37:59 +01:00
Nicola CortiandBlake Friedman c45d450502 Upstream CLI autolinking changes to RNGP (#45314)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45314

Fixes https://github.com/facebook/react-native/issues/45302

I'm ustreaming two changes that happened inside the CLI/Autolinking logic that are
missing inside core autolinking.

Changelog:
[Internal] [Changed] - Upstream CLI autolinking changes to RNGP

Reviewed By: blakef

Differential Revision: D59460504

fbshipit-source-id: a6e7ab6a46fec26620dc965e77b13fdeba84fae3
2024-07-15 14:37:29 +01:00
Miklós FazekasandBlake Friedman e1d97f4621 fix: android autolinkLibrariesFromCommand should handle timeout or non zero exit code (#45333)
Summary:
Fixes: https://github.com/facebook/react-native/issues/45307

## Changelog:

[Android] [Fixed] - if `npx react-native-community/cli config` fails or timeouts proper error is shown and built is aborted, instead of leaving and empty autolinking.json

During build `npx react-native-community/cli config` is generated into autolinking.json. When command fails, we should error and should not leave and empty `autolinking.json`

Pull Request resolved: https://github.com/facebook/react-native/pull/45333

Test Plan:
Output of the reproducer in https://github.com/facebook/react-native/issues/45307 looks like this:

```log
android % ./gradlew assembleDebug
Starting a Gradle Daemon (subsequent builds will be faster)
ERROR: autolinkLibrariesFromCommand: Failed to create /Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/android/build/generated/autolinking/autolinking.json - process npx react-native-community/cli config  exited with error code: 126

FAILURE: Build failed with an exception.

* Where:
Settings file '/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/android/settings.gradle' line: 3

* What went wrong:
A problem occurred evaluating settings 'android'.
> ERROR: autolinkLibrariesFromCommand: Failed to create /Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/android/build/generated/autolinking/autolinking.json - process npx react-native-community/cli config  exited with error code: 126

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 10s
8 actionable tasks: 4 executed, 4 up-to-date
```

Output if you modify the package.json to be invalid looks like this:

```log
android % ./gradlew assembleDebug
ERROR: autolinkLibrariesFromCommand: process npx react-native-community/cli config  exited with error code: 1
JSONError: JSON Error in /Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/package.json:

  35 |     "node": ">=18"
  36 |   },
> 37 |   SOMETHING_NON_JSON
     |   ^
  38 |   "packageManager": "yarn@3.6.4",
  39 |   "resolutions": {
  40 |     "rtn-centered-text": "portal:../RTNCenteredText"

Unexpected token "S" (0x53) in JSON at position 1019 while parsing near "...ode\": \">=18\"\n  },\n  SOMETHING_NON_JSON\n ..."

  35 |     "node": ">=18"
  36 |   },
> 37 |   SOMETHING_NON_JSON
     |   ^
  38 |   "packageManager": "yarn@3.6.4",
  39 |   "resolutions": {
  40 |     "rtn-centered-text": "portal:../RTNCenteredText"

    at parseJson (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/parse-json/index.js:29:21)
    at loadJson (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/loaders.js:48:16)
    at #loadConfiguration (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/ExplorerSync.js:116:36)
    at #loadConfigFileWithImports (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/ExplorerSync.js:87:54)
    at #readConfiguration (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/ExplorerSync.js:84:82)
    at search (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/ExplorerSync.js:50:63)
    at emplace (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/util.js:36:20)
    at ExplorerSync.search (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/ExplorerSync.js:78:42)
    at getUserDefinedOptionsFromMetaConfig (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/index.js:32:37)
    at mergeOptionsBase (/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/node_modules/react-native-community/cli-config/node_modules/cosmiconfig/dist/index.js:60:31)

FAILURE: Build failed with an exception.

* Where:
Settings file '/Users/boga/Work/OSS/RNMBGL/rn-fabric-boolattribute/ReproducerApp/android/settings.gradle' line: 3

* What went wrong:
A problem occurred evaluating settings 'android'.
> ERROR: autolinkLibrariesFromCommand: process npx react-native-community/cli config  exited with error code: 1

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 2s
8 actionable tasks: 4 executed, 4 up-to-date
```

Reviewed By: cipolleschi

Differential Revision: D59582430

Pulled By: cortinico

fbshipit-source-id: bedb9563175cc5c46f5af80cf309769e56b803cc
2024-07-15 14:36:58 +01:00
Blake Friedman f303bcaaa5 fix: ios Helloworld assumes community cli is present (#45221)
Summary:
Use the hard-coded config for Helloworld instead of assuming the community cli is there to generate a config, which we can no longer assume.

Changelog: [Internal]

Pull Request resolved: https://github.com/facebook/react-native/pull/45221

Test Plan:
This works in my local environment:
```
bundle exec pod install
```
and
```
./gradlew generateAutolinkingPackageList
```
Changelog: [Internal]

Reviewed By: javache

Differential Revision: D59162715

Pulled By: blakef

fbshipit-source-id: 95ff2c3929f12ee0ecf468cb80d2df1281eb746e
2024-07-15 14:36:49 +01:00
Miklós FazekasandBlake Friedman 2e06efbf5d Allow library podspec to declare Swift Package Manager dependencies (#44627)
Summary:
React-Native uses Cocapods for native dependency management on iOS. While CocoaPods is flexible and popular, Apple's Swift Package Manager is the new standard. Currently consuming packages available only via Swift Package Manager is not possible. This change implements a single extension so .podspec files can declare Swift Package Manager dependencies via
```ruby
ReactNativePodsUtils.spm_dependency(s,
     url: 'https://github.com/apple/swift-atomics.git',
     requirement: {kind: 'upToNextMajorVersion', minimumVersion: '1.1.0'},
     products: ['Atomics']
   )
```

bypass-github-export-checks

## Changelog:

[IOS] [ADDED] - libraries can now declare Swift Package Manager dependencies in their .podspec with `ReactNativePodsUtils.spm_dependency`

Pull Request resolved: https://github.com/facebook/react-native/pull/44627

Test Plan:
https://github.com/mfazekas/rn-spm-rfc-poc/

Is a simple demo for the feature:

1. Podspec declare dependency with:

   ```ruby
   if const_defined?(:ReactNativePodsUtils) && ReactNativePodsUtils.respond_to?(:spm_dependency)
     ReactNativePodsUtils.spm_dependency(s,
       url: 'https://github.com/apple/swift-atomics.git',
       requirement: {kind: 'upToNextMajorVersion', minimumVersion: '1.1.0'},
       products: ['Atomics']
     )
   else
     raise "Please upgrade React Native to >=0.75.0 to use SPM dependencies."
   end
   ```

2. [`import Atomics`](https://github.com/mfazekas/rn-spm-rfc-poc/blob/e4eb1034f7498dedee4cb673d327c34a6048bda2/ios/MultiplyInSwift.swift#L1C2-L1C15) and [`ManagedAtomic`](https://github.com/mfazekas/rn-spm-rfc-poc/blob/e4eb1034f7498dedee4cb673d327c34a6048bda2/ios/MultiplyInSwift.swift#L7-L13) is used in the code

3.) `spm_dependency` causes the dependency to be added via `post_install` hook in the workspace

<img width="261" alt="image" src="https://github.com/facebook/react-native/assets/52435/ad6aee1c-ac88-4c84-8aa3-50e148c4f5b2">

4.) `spm_dependecy` causes the library to be linked with `Atomics` library

<img width="817" alt="image" src="https://github.com/facebook/react-native/assets/52435/bfc8dfc0-aeb7-4c75-acbd-937eab1cbf80">

Limitations:
1.) only works `USE_FRAMEWORKS=dynamic pod install` otherwise the linker fails [with known Xcode issue - duplicate link issue](https://forums.swift.org/t/objc-flag-causes-duplicate-symbols-with-swift-packages/27926)
2.) .xcworkspace needs to be reopened after `pod install` - this could be worked around by not removing/readding spm dependencies

### See also:

https://github.com/react-native-community/discussions-and-proposals/issues/587#issuecomment-2117025448
https://github.com/react-native-community/discussions-and-proposals/pull/787

Reviewed By: cortinico

Differential Revision: D58947066

Pulled By: cipolleschi

fbshipit-source-id: ae3bf955cd36a02cc78472595fa003cc9e843dd5
2024-07-15 14:36:12 +01:00
IrfanwaniandBlake Friedman 4cec121a7b fix: post install error in iOS after running pod install, undefined method 'path' for nil:NilClass (#45095)
Summary:
After upgrading my project to the latest version of react native i.e, 0.74.2, i was getting an error when running `pod install` an the error was coming from the post install hook. Going deeper into the file tree, i found that some of the things are Nil and react native is trying to use some methods on them, so fixed those issues by using chaining operators to conditionally apply the path method on them.

## Changelog:

[Internal] - fixes the post install issue when running pod install with react native version, 0.74.2

Pull Request resolved: https://github.com/facebook/react-native/pull/45095

Test Plan: Manually tested the fix. Works perfectly fine in both debug and production mode.

Reviewed By: cortinico

Differential Revision: D58863666

Pulled By: cipolleschi

fbshipit-source-id: 64459711dcf926b7544b99b542e9861c1c0f05ca
2024-07-15 14:35:49 +01:00
Rubén NorteandBlake Friedman 95fa0dcdc8 Fix broken CI due to missing dependencies
Summary:
https://github.com/facebook/react-native/pull/45409 broke CI because it didn't set up dependencies correctly. This should fix it.

Changelog: [internal]

Reviewed By: cipolleschi

Differential Revision: D59751194
2024-07-15 14:35:16 +01:00
Rubén NorteandBlake Friedman 58a525aa2f Replace BridgelessJSCallInvoker with RuntimeSchedulerCallInvoker everywhere (#45409)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45409

Changelog: [internal]

This removes `BridgelessJSCallInvoker` in favor of `RuntimeSchedulerCallInvoker`. This change should be transparent when not invoking JS callbacks using priorities, as both of them would just go directly to the scheduler using `scheduleWork`, but when priorities are specified, they'd now be honored in `RuntimeSchedulerCallInvoker`.

I realized this wasn't being used when I saw that `PerformanceObserver` callbacks were always scheduled with the highest priority, instead of with idle priority as specified in code.

Reviewed By: sammy-SC

Differential Revision: D59679512

fbshipit-source-id: 51d36d56ef1ff0b34e5157ed7b5e08de0a3884d2
2024-07-15 14:34:06 +01:00
Rubén NorteandBlake Friedman 2373a0003a Fix incorrect application of idle priority in RuntimeScheduler (#45408)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45408

Changelog: [General][Fixed] Fixed prioritization of idle priority tasks

We recently found out that idle priority tasks were never scheduled with the lowest priority possible. We didn't realize before because idle priority tasks weren't used, but now they are via `requestIdleCallback` and other mechanisms.

The problem was that the timeout for idle priority tasks was `std::chrono:milliseconds::max()`, and we compute the expiration time adding that to the current time. Doing that operation is always guaranteed to overflow, and the resulting expiration time was always in the past, resulting in the task having higher priority than any other tasks with any other priorities.

Instead of using `max()` we can just use a sensible value for idle priorities. In this case, 5 minutes should be more than enough.

Reviewed By: sammy-SC

Differential Revision: D59679513

fbshipit-source-id: 6c0f9e275818737ce804f05615c01f7ea6c126ab
2024-07-15 14:33:38 +01:00
Håkon KnutzenandBlake Friedman d4eb12f48a Fix data races in RCTImageLoader and RCTNetworkTask with shared atomic counters (#45114)
Summary:
In order to fix the data races described in https://github.com/facebook/react-native/issues/44715, I propose a simple solution by leveraging shared counter functions wherein `std::atomic` is the backing for the integer values.

## Changelog:

[iOS] [Fixed] - Implement shared atomic counters and replace static integers in `RCTImageLoader` and `RCTNetworkTask` that were accessed concurrently, which in some cases lead to data races.

Pull Request resolved: https://github.com/facebook/react-native/pull/45114

Test Plan: Added unit tests for the counters in `RCTSharedCounterTests`.

Reviewed By: cipolleschi

Differential Revision: D59155076

Pulled By: javache

fbshipit-source-id: f73afce6a816ad3226ed8c123cb2ccf4183549a0
2024-07-15 14:31:53 +01:00
Nicola CortiandBlake Friedman 593ddc7109 Back out "Kotlinify NativeModule" (#45411)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45411

Original commit changeset: 6e096552750e

Original Phabricator Diff: D55792976

Changelog:
[Android] [Fixed] - Reverted "[react-native] Kotlinify NativeModule"

Reviewed By: fabriziocucci

Differential Revision: D59680321

fbshipit-source-id: f118f436dc4086676d3ed98fa8d8b28033d9cd47
2024-07-15 14:29:40 +01:00
Nicola CortiandBlake Friedman 273df72301 Undo a breaking change with ResourceDrawableIdHelper.instance (#45389)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45389

This undos a breaking change with ResourceDrawableIdHelper for Kotlin consumer.
I've re-added a `getInstance` method so that Kotlin libraries won't break.
The method is added as Deprecated as those libraries need to migrate to `.instance`
accessors as more idiomatic.

Changelog:
[Android] [Fixed] - Undo a breaking change with ResourceDrawableIdHelper.instance

Reviewed By: robhogan

Differential Revision: D59638043

fbshipit-source-id: ae2aab962e9a7676f0bfbae21f699e274502dc6a
2024-07-15 14:29:35 +01:00
Nicola CortiandBlake Friedman b8b9e9ee7d Undo a breaking change with I18nUtil.instance (#45390)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45390

This undos a breaking change with I18nUtil for Kotlin consumer.
I've re-added a `getInstance` method so that Kotlin libraries won't break.
The method is added as Deprecated as those libraries need to migrate to `.instance`
accessors as more idiomatic.

Changelog:
[Android] [Fixed] - Undo a breaking change with I18nUtil.instance

Reviewed By: alanleedev

Differential Revision: D59638044

fbshipit-source-id: 1c93a98676b5b01e89be3b974961c5f3ae919511
2024-07-15 14:29:28 +01:00
Nicola CortiandBlake Friedman 50643a300c Undo breaking change for ReadableMap.entryIterator for Kotlin consumers. (#45388)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45388

This undos a breaking change we're about to ship in 0.75, where Kotlin users
where forced to update this callsite to be `.getEntryIterator`.

This re-introduces a `entryIterator` val so both Kotlin and Java compatibility are retained.

Changelog:
[Android] [Fixed] - Undo breaking change for ReadableMap.entryIterator for Kotlin consumers

Reviewed By: alanleedev

Differential Revision: D59637925

fbshipit-source-id: b674df86e056f17791d9cabe28557529886f1c93
2024-07-15 14:29:22 +01:00
Nicola CortiandBlake Friedman b1b41470e0 Undo breaking change on Dynamic.type and Dynamic.isNull (#45378)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45378

Kotlin consumers of those APIs are forced with this breaking change:

```
# Before thanks to Java property conversion
Dynamic.type
# After
Dynamic.getType()
```
This restores the old more idiomatic API by moving those 2 funcitons to be vals.

Changelog:
[Android] [Fixed] - Undo breaking change on Dynamic.type and Dynamic.isNull

Reviewed By: javache

Differential Revision: D59631783

fbshipit-source-id: 8d720af34e104ee0e4f3120302a4a84fc17a7b1c
2024-07-15 14:28:56 +01:00
Nicola CortiandBlake Friedman 65975fe37b Undo breaking change on getJsCallInvokerHolder (#45376)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45376

This reduces one breaking change users are seeing on `CatalystInstance.getJsCallInvokerHolder`.
I had to specify:

```
Suppress("INAPPLICABLE_JVM_NAME")
get:JvmName("getJSCallInvokerHolder")
```

as the Kotlin compiler is unhappy with me setting a JvmName on a interface property.
More on this here: https://youtrack.jetbrains.com/issue/KT-31420

Changelog:
[Android] [Fixed] - Undo breaking change on `CatalystInstance.getJsCallInvokerHolder`

Reviewed By: javache

Differential Revision: D59631640

fbshipit-source-id: 4d5b3499e4e0e0bec1d380c4b7942ea28ae35465
2024-07-15 14:28:02 +01:00
Riccardo Cipolleschi 09152303d7 [LOCAL] Revert changes to project.pbxproj 2024-07-08 19:57:35 +02:00
Riccardo Cipolleschi af3402c019 [LOCAL] Bump podfile.lock 2024-07-08 19:56:25 +02:00
React Native Bot a2022aff95 Release 0.75.0-rc.4
#publish-packages-to-npm&next
2024-07-08 15:49:29 +00:00
Ruslan LesiutinandGitHub 2617ec5570 upgrade[react-devtools-core]: ^5.3.1 (#45288) 2024-07-08 15:17:02 +02:00
Tomek ZawadzkiandRiccardo Cipolleschi 625d330ed9 Fix dynamic_cast (RTTI) by adding key function to ShadowNodeWrapper again (#45290)
Summary:
This PR restores the virtual destructor for `ShadowNodeWrapper` which was added in https://github.com/facebook/react-native/pull/33500 and unfortunately removed in https://github.com/facebook/react-native/pull/40864.

The virtual destructor here serves as a key function. Without a key function, `obj.hasNativeState<ShadowNodeWrapper>(rt)` **does not** work correctly between shared library boundaries on Android and always returns false.

We need this pretty badly in third-party libraries like react-native-reanimated or react-native-gesture-handler.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] [FIXED] - Fix dynamic_cast (RTTI) for ShadowNodeWrapper when accessed by third-party libraries again

Pull Request resolved: https://github.com/facebook/react-native/pull/45290

Test Plan: This patch fixes an issue in Reanimated's fabric-example app.

Reviewed By: fabriziocucci

Differential Revision: D59375554

Pulled By: javache

fbshipit-source-id: 09f3eda89a67c26d6dacca3428e08d1b7138d350
2024-07-08 15:16:30 +02:00
Jakub PiaseckiandRiccardo Cipolleschi 2d42024d21 Update ignore file to include ReactBuildConfig in the npm package (#45279)
Summary:
Changes `.npmignore` file to only exclude the `ReactAndroid/build` directory instead of all `build` directories under `ReactAndroid` (which included the `ReactAndroid/src/main/java/com/facebook/react/common/build` package). This problem was caused by the newer version of NPM being used.

Closes https://github.com/facebook/react-native/issues/45204

## Changelog:

[ANDROID] [FIXED] - Fixed build from source failing due to a missing file

Pull Request resolved: https://github.com/facebook/react-native/pull/45279

Test Plan:
Run `npm pack` or `npm publish -dry-run`.

Before this change it includes 3774 files in the package and `ReactBuildConfig` isn't included. After this change it includes 3775 files in the package and `ReactBuildConfig` is included.

Reviewed By: javache

Differential Revision: D59371555

Pulled By: cortinico

fbshipit-source-id: f54f1e88e30429d538b9e160e6ce20d994c5d1b8
2024-07-08 15:15:52 +02:00
Wojciech LewickiandRiccardo Cipolleschi 83a2086548 fix: add JvmStatic to all methods used in cpp (#45243)
Summary:
Following-up on https://github.com/facebook/react-native/pull/45230, I added all the needed `JvmStatic` annotations for methods used in cpp code here: https://github.com/facebook/hermes/blob/f5c867514c71b25212eb3039230e0c095518b532/lib/Platform/Unicode/PlatformUnicodeJava.cpp.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID] [FIXED] - Use `JvmStatic` annotations for all methods from `AndroidUnicodeUtils.kt`

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] [FIXED] - Use `JvmStatic` annotations for all methods from `AndroidUnicodeUtils.kt`

Pull Request resolved: https://github.com/facebook/react-native/pull/45243

Test Plan: Try and use those methods to see that they don't crash on `cpp` side.

Reviewed By: cortinico

Differential Revision: D59264093

Pulled By: dmytrorykun

fbshipit-source-id: 07d683ee38ea1c7d9621ad2e37d04f3d484d3200
2024-07-08 15:15:30 +02:00
Riccardo CipolleschiandGitHub 1630b5c743 [RN][Testing] Update testing scripts to work with any version of React native (#45201) 2024-07-03 16:11:08 +01:00
Nicola Corti 7db3ebe2d1 Update Podfile.lock
Changelog: [Internal]
2024-07-02 10:55:27 +01:00
React Native Bot 15b55714eb Release 0.75.0-rc.3
#publish-packages-to-npm&next
2024-07-01 16:54:13 +00:00
Nicola Corti 2ab13798f9 [LOCAL] Bump hermes to hermes-2024-07-01-RNv0.75.0-1edbe36ce92fef2c4d427f5c4e104f2758f4b692 2024-07-01 14:38:19 +01:00
Bartłomiej BłoniarzandNicola Corti 07420ea5a2 Add missing WithRuntimeDecorator methods (#45042)
Summary:
This PR adds missing `WithRuntimeDecorator` methods related to `NativeState`. This pattern is used by reanimated to ensure no concurrent access to the runtime. Without this `override` the `RuntimeDecorator` implementation was used, bypassing our mutex.

Changelog:
[GENERAL] [FIXED] - Add missing `NativeState` methods to the `WithRuntimeDecorator` class.

Pull Request resolved: https://github.com/facebook/react-native/pull/45042

Reviewed By: fbmal7

Differential Revision: D58744051

Pulled By: neildhar

fbshipit-source-id: 3f5c85d0bf7cd6445d0c434ac4ae7ed54df203ba
2024-07-01 14:34:00 +01:00
Alan LeeandNicola Corti 173587f5ec extract ParsedError handling to helper (#44922)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44922

extract ParsedError handling code into `StackTraceHelperTest`.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D58512611

fbshipit-source-id: 959978d80907f2afba96ef249c2fddd351d099ff
2024-07-01 14:32:01 +01:00
Alan LeeandNicola Corti 75584641be add default early JS error handler (#44884)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44884

Removing JavaScript error handler supplied to ReactHostImpl.java which is just a stub and creating a default handler in ReactInstance.java which uses NativeExceptionHandler TurboModule to handle error.

Changelog: [Android][BREAKING]  Removing `ReactJsExceptionHandler` param from ReactHostImpl() constructor and providing a default private implementation

Reviewed By: javache, cortinico

Differential Revision: D58385767

fbshipit-source-id: 46548677df936b7c2f584084a2c9769c27e6a963
2024-07-01 14:31:54 +01:00
Gabriel DonadelandNicola Corti f86bc9512f Fix Android autolink plugin for libraries that are platform specific (#45223)
Summary:
Fixes https://github.com/facebook/react-native/issues/45222

## Changelog:

[ANDROID] [FIXED] - Fix autolink plugin for libraries that are platform-specific

Pull Request resolved: https://github.com/facebook/react-native/pull/45223

Test Plan: And a library that does not have Android native code such as react-native-segmented-control/segmented-control and sync gradle

Reviewed By: rshest

Differential Revision: D59221562

Pulled By: cortinico

fbshipit-source-id: 55739d63ded63e46897d0d770281f937668c1f50
2024-07-01 14:28:13 +01:00
Nicola Corti 3252855e1d Fix crash due to missing @JvmStatic to convertToCase
Summary:
Users are reporting that RN 0.75 is crashing due to us attempting to accessing a static method
on `AndroidUnicodeUtils.convertToCase` which is not static anymore due to Kotlin conversion.

Static access is inside Hermes codebase here:
https://github.com/facebook/hermes/blob/f5c867514c71b25212eb3039230e0c095518b532/lib/Platform/Unicode/PlatformUnicodeJava.cpp#L107-L109

Changelog:
[Android] [Fixed] - Fix crash due to missing JvmStatic to `convertToCase`

Reviewed By: javache

Differential Revision: D59218291

fbshipit-source-id: ac121a8bcd5fd917ee134d257f967c8e3e338ca5
2024-07-01 14:27:55 +01:00
imWildCatandNicola Corti 89073d46bd fix the path of the script phase (#45208)
Summary:
Since 0.75-rc.x, I cannot run pod install because of an linking issue of react native firebase.

https://github.com/reactwg/react-native-releases/issues/341#issuecomment-2194568204

## Changelog:

[IOS][FIXED] Auto linking script of script phase

Pull Request resolved: https://github.com/facebook/react-native/pull/45208

Test Plan: Full demo of this fix: <https://github.com/imWildCat-archived/react-native-075-rc2-regression-ios-linking-script-phase>

Reviewed By: christophpurrer

Differential Revision: D59125585

Pulled By: blakef

fbshipit-source-id: be96d3b207eff67c5e0d777203e7fc0d10103fc0
2024-07-01 14:27:31 +01:00
Dmitry RykunandNicola Corti 6bd418b738 Fix output path for generated artifacts (#45165)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45165

This is a fix for https://github.com/facebook/react-native/issues/45112
This diff changes the codegen so that the output path is computed relative to project root (or `path` if provided) instead of current working directory.

Changelog: [General][Fixed] - Codegen computes output path relative to project root instead of current working directory.

Reviewed By: fkgozali

Differential Revision: D59009821

fbshipit-source-id: 3a138a3508fc239c8600b8c9f242f1c665f8e3c0
2024-07-01 14:27:15 +01:00
Riccardo Cipolleschi 1f10d62700 [LOCAL][iOS] Bump Podfile.lock to RC.2 2024-06-26 14:50:06 +02:00
Riccardo Cipolleschi f938e3214c [LOCAL] Fix type import in testing scripts 2024-06-26 13:06:08 +02:00
React Native Bot 668358c47a Release 0.75.0-rc.2
#publish-packages-to-npm&next
2024-06-26 10:59:42 +00:00
zhongwuzwandNicola Corti 4783de7a40 Fixes js bundle failed (#45155)
Summary:
When I enabled `FORCE_BUNDLING`, it build errors like below. cc blakef
![image](https://github.com/facebook/react-native/assets/5061845/d23f6bad-ed60-4f1f-8111-2361c93e93a4)

## Changelog:

[INTERNAL] [FIXED] - Fixes js bundle failed

Pull Request resolved: https://github.com/facebook/react-native/pull/45155

Test Plan: Enable FORCE_BUNDLING and build success.

Reviewed By: cipolleschi

Differential Revision: D59006962

Pulled By: blakef

fbshipit-source-id: 1142d1ddbae7346b67712fac0237950847211992
2024-06-26 11:57:50 +01:00
Riccardo Cipolleschi 865aaeda58 [LOCAL] Bump RC in testing script 2024-06-26 11:23:35 +02:00
Riccardo CipolleschiandGitHub 2a0c175135 [LOCAL][CI] Fix Helloworld ios jobs (#45158) 2024-06-26 10:22:02 +01:00
Nicola Corti 6a155dd1cf [LOCAL] Bump CLI to 14.0.0-alpha.11 2024-06-26 10:13:27 +01:00
Riccardo Cipolleschi 52db082576 [LOCAL][iOS] Bump Podfile.lock 2024-06-25 19:02:16 +02:00
React Native Bot 9120930288 Release 0.75.0-rc.1
#publish-packages-to-npm&next
2024-06-25 13:58:20 +00:00
Riccardo CipolleschiandGitHub c9f335a568 [LOCAL][Release-Testing] Update the testing script to use the new template (#45144)
* [LOCAL][Release-Testing] Update the testing script to use the new template

* Fix script
2024-06-25 13:55:02 +01:00
Riccardo CipolleschiandGitHub 38b1ddebd5 [LOCAL][RN][CI] Improve stability of the Hermes pipeline (#45142)
* [LOCAL][CI] Require cocoapods to hermes-engine podspec

* Refactor Hermes workspace (#45071)

Summary:
This change is the first step in refactoring GHA so that they can be reused more easily across jobs.
Its goal is also to be more reliable w.r.t. caches.

That this change do:
* moves `prepare_hermes_workspace` to a composite action
	* saves the `prepare_hermes_workspace` caches only on main
	* uploads the destination folder as an artifact so that we can use it later in the run
* makes the `test-all`, `nightly` and `publish-release` workflow use the new composite action
* updates the `setup-hermes-workspace` to download and use the artifact uploaded by `prepare_hermes_workspace`

[Internal] - Factor out the prepare_hermes_workspace action

Pull Request resolved: https://github.com/facebook/react-native/pull/45071

Test Plan: GHA in CI

Reviewed By: cortinico

Differential Revision: D58808087

Pulled By: cipolleschi

fbshipit-source-id: 42c46bcf75fc73b2edfda9be62b5d0fe8a919a5d

* [LOCAL][RN][CI] Improve stability of the Hermes pipeline

* chore: align nighlties and releases to the test-all jobs which is green in GHA
2024-06-25 13:54:03 +01:00
Nicola Corti a300a2c057 [LOCAL] Bump CLI to 14.0.0-alpha.10 2024-06-25 13:52:18 +01:00
Riccardo CipolleschiandGitHub 1c0a4e72b1 [LOCAL][CI] Require cocoapods to hermes-engine podspec (#45134)
* [LOCAL][CI] Require cocoapods to hermes-engine podspec

* Refactor Hermes workspace (#45071)

Summary:
This change is the first step in refactoring GHA so that they can be reused more easily across jobs.
Its goal is also to be more reliable w.r.t. caches.

That this change do:
* moves `prepare_hermes_workspace` to a composite action
	* saves the `prepare_hermes_workspace` caches only on main
	* uploads the destination folder as an artifact so that we can use it later in the run
* makes the `test-all`, `nightly` and `publish-release` workflow use the new composite action
* updates the `setup-hermes-workspace` to download and use the artifact uploaded by `prepare_hermes_workspace`

[Internal] - Factor out the prepare_hermes_workspace action

Pull Request resolved: https://github.com/facebook/react-native/pull/45071

Test Plan: GHA in CI

Reviewed By: cortinico

Differential Revision: D58808087

Pulled By: cipolleschi

fbshipit-source-id: 42c46bcf75fc73b2edfda9be62b5d0fe8a919a5d
2024-06-24 16:36:39 +01:00
Nicola Corti 50503b08f8 Back out "Add Float and Int type support for Android modules" (#45087)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45087

Original commit changeset: 32b3bbdf5fd2

Fixes https://github.com/facebook/react-native/issues/44963
Closes https://github.com/facebook/react-native/pull/45024

Original Phabricator Diff: D52420921

Changelog:
[Internal] [Changed] - Back out "[RN][Codegen]Add Float and Int type support for Android  modules"

Reviewed By: dmytrorykun

Differential Revision: D58820544

fbshipit-source-id: 59cd0e7cc17a681785c57b5ce1a9d50d28a348af
2024-06-24 14:17:44 +01:00
Riccardo CipolleschiandGitHub 453e00a017 [RN][CI] Bump react-native CLI dependency to alpha.9 (#45123) 2024-06-24 13:02:41 +01:00
Riccardo CipolleschiandGitHub fafc71b5cb [LOCAL][RN][Tests] Fix JS tests for release (#45062) 2024-06-19 14:37:48 +01:00
React Native Bot 98b302e219 Release 0.75.0-rc.0
#publish-packages-to-npm&next
2024-06-19 10:03:08 +00:00
Nicola Corti 7aa3396f53 Revert "Release 0.75.0-rc.0"
This reverts commit 534fdc0005.
2024-06-19 11:01:46 +01:00
Nicola Corti fee2156642 [LOCAL] Fix build_android by setting git safe folders 2024-06-19 11:01:35 +01:00
React Native Bot 534fdc0005 Release 0.75.0-rc.0
#publish-packages-to-npm&next
2024-06-19 09:54:40 +00:00
Nicola Corti 609c7c05b1 [LOCAL] Fix handling of GITHUB_REF_NAME 2024-06-19 10:53:18 +01:00
Nicola Corti 5f11ed9e43 Revert "Release 0.75.0-rc.0"
This reverts commit 1d69fe9d23.
2024-06-19 10:51:17 +01:00
React Native Bot 1d69fe9d23 Release 0.75.0-rc.0
#publish-packages-to-npm&next
2024-06-19 09:42:02 +00:00
Nicola Corti 63d1a1e5eb [LOCAL] Add debugging info for GITHUB_REF 2024-06-19 10:39:53 +01:00
Riccardo Cipolleschi 6c1374e065 Revert "Release 0.75.0-rc.0"
This reverts commit abd96c21ec.
2024-06-19 10:37:38 +01:00
React Native Bot abd96c21ec Release 0.75.0-rc.0
#publish-packages-to-npm&next
2024-06-19 09:33:10 +00:00
Riccardo CipolleschiandGitHub 375c88478c [LOCAL][RN][CI] Fix release scripts to use GITHUB_REF and GITHUB_REF_NAME variables (#45057) 2024-06-19 10:32:04 +01:00
Nicola Corti daf9b29d05 Revert "Release 0.75.0-rc.0"
This reverts commit c2ebb30389.
2024-06-18 18:37:46 +01:00
React Native Bot c2ebb30389 Release 0.75.0-rc.0
#publish-packages-to-npm&next
2024-06-18 17:33:11 +00:00
Nicola Corti f4b1dd1fa1 [LOCAL] Configure git user before attempting to publish a release (#45039) 2024-06-18 18:31:53 +01:00
Nicola Corti a0c83803e8 Fix release regex for publish-release workflow (#45043)
Summary:
The existing regex is not workign. I've split it in two and tested it against a private repo.

## Changelog:

[INTERNAL] - Fix release regex for publish-release workflow

Pull Request resolved: https://github.com/facebook/react-native/pull/45043

Test Plan: Tested on privare repo with GHA

Reviewed By: cipolleschi

Differential Revision: D58736292

Pulled By: cortinico

fbshipit-source-id: f07ef32dcb0059922100c555f7894bbf0c7dd8f6
2024-06-18 18:29:09 +01:00
Riccardo Cipolleschi 528097709a [LOCAL][RN][Release] Use github bot token to commit the tag 2024-06-18 18:27:47 +01:00
Riccardo Cipolleschi efa1e5375a Revert "Release 0.75.0-rc.0"
This reverts commit 1481140e68.
2024-06-18 17:14:43 +01:00
Riccardo Cipolleschi d524c151cd [CI][Release] remove publishing jobs from cci 2024-06-18 17:10:41 +01:00
React Native Bot 1481140e68 Release 0.75.0-rc.0
#publish-packages-to-npm&next
2024-06-18 16:01:33 +00:00
Nicola Corti 03591318fb [LOCAL] Fix double quotes for inputs.dry_run 2024-06-18 17:00:34 +01:00
Nicola Corti 56e1c8bfdd [LOCAL] Fix input types for create-release 2024-06-18 16:58:54 +01:00
Nicola CortiandGitHub 1b891357b2 [LOCAL] Configure git user before attempting to publish a release (#45039) 2024-06-18 16:51:54 +01:00
Riccardo CipolleschiandGitHub e36b46f0c9 [LOCAL][CI][Release] Forward inputs to Create Release composite action (#45038) 2024-06-18 16:46:49 +01:00
b236f9bd82 [LOCAL][RN][Release Testing] Update the testing script to run with the community template (#45033)
* [LOCAL][RN][Release Testing] Update the testing script to run with the community template

* fix prettier

---------

Co-authored-by: Nicola Corti <ncor@meta.com>
2024-06-18 16:23:08 +01:00
Nicola CortiandGitHub 44d4190581 [LOCAL] Disable test_js_e2e on the 0.75 release branch (#45022) 2024-06-18 11:16:56 +01:00
Riccardo CipolleschiandGitHub 88c136ed36 [LOCAL][RN][CI] Use bigger machines for Android Helloworld (#45020) 2024-06-18 10:53:46 +01:00
Blake FriedmanandRiccardo Cipolleschi e56d4f9528 remove the template from react-native package (#45008)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45008

As part of RFC0759, we are moving the template into it's own repository.

- [Section in RFC0759](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0759-react-native-frameworks.md#evolving-the-react-native-community-template--cli)
- [Template's new home](https://github.com/react-native-community/template)
- [Versioning discussion](https://github.com/react-native-community/cli/issues/2345)

Changelog: [General][Breaking] removed the template from react-native into react-native-community/template

Reviewed By: cortinico

Differential Revision: D58184276

fbshipit-source-id: 5e52320af55495488587accbe144d11164cea4fd
2024-06-18 10:04:11 +01:00
Blake FriedmanandRiccardo Cipolleschi 20ca94b0d3 test_android_template → test_android_helloworld but disabled until template is removed (#44908)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44908

Changelog: [General] [Changed] - CircleCI test to Helloworld, but disabled for now until we remove the template

Reviewed By: cipolleschi

Differential Revision: D58469912

fbshipit-source-id: 718a774946bd70347697f18bbfc470b2897d2f87
2024-06-18 10:02:48 +01:00
Nicola Corti 37e8fa113e Revert "Make the New Architecture the default (#43135)"
This reverts commit b9f3186ee6.
2024-06-17 14:32:59 +01:00
Nicola Corti 492a0c1292 Bump Hermes version 2024-06-17 14:27:43 +01:00
2422 changed files with 62535 additions and 89209 deletions
+170 -2
View File
@@ -1,4 +1,172 @@
# Circle CI
This directory was home to the Circle CI configuration files.
In July 2024 we moved to GitHub Actions, and week this folder for backward compatibility, as we want to keep on using Circle CI for the release of React Native <= 0.74.
This directory is home to the Circle CI configuration files. Circle is our continuous integration service provider. You can see the overall status of React Native's builds at https://circleci.com/gh/facebook/react-native
You may also see an individual PR's build status by scrolling down to the Checks section in the PR.
## Purposes
We use CircleCI for mainly 3 purposes:
1. Testing changes
2. Release Nightlies
3. Release Stable Versions of React Native
When testing changes, we run all the tests on commits that lands on `main`. For commits in PR, we try to understand which kind of changes the PR is about and we try to selectively run only the relevant tests. so, for example, if a PR only touches iOS files, we are going to run only iOS tests.
A Nighly job runs every day at around 9:00 PM, GMT. They run from `main` and they publish a version of React Native using the current state of the codebase, creating a version number that follows the format: `0.<current-version+1>.0-nightly-<YYYYMMDD>-<short-commit-hash>`.
The nightly job also publish all the monorepo packages, taking care of updating the transitive dependencies of those packages.
Stable versions are released manually by the Release Crew and they run from a stable branch. Stable branches have the shape of `0.<version>-stable`.
## How It Works?
CircleCI execution is now split in two steps:
- Setup
- Testing
The setup step takes care of analyzing the changes in the PR and of deciding which jobs needs to run.
The testing flow is a set of workflows that executes the required tests.
### Setup
The code of the setup workflow lives in the root [`config.yml`](https://github.com/facebook/react-native/blob/main/.circleci/config.yml) file.
It uses the `Continuation orb` from CircleCI to start a CI flow that depends on the changes present in the PR.
If the changes are not coming from a PR (either a simple commit or if the CI is running on main) **we always run all the tests** as a cautionary measure.
The setup job has also to expose all the pipeline parameters that we would need to pass to the actual workflow. Those parameters are **automatically forwarded** to the workflows that are started as a result of the setup.
The setup job uses a JS script to carry on its logic. The [`pipeline_selection.js`](https://github.com/facebook/react-native/blob/main/scripts/circleci/pipeline_selection.js) script can be invoked with two commands:
- `filter-jobs`
- `create-configs`
The **`filter-jobs`** command takes care of creating a JSON representation of the tests we need to run based on the changes in the PR.
The **`create-configs`** command consumes the JSON representation to create a CircleCI configuration that can then executes all the required tests.
#### Creating a Configuration
To create a configuration, the `pipeline-selection` scripts collates together various pieces of `YML` files that lives in the [`Configurations` folder](https://github.com/facebook/react-native/tree/main/.circleci/configurations).
The order in which these files are appended is **important** and it always contains the following.:
1. `top_level.yml`: this file contains some high level directives for CircleCI, like the version, the list of orbs, the cache-keys, and the pipeline parameters that can be used by the workflows.
2. `executors.yml`: this file contains the list of the executors used in our jobs and their configurations.
3. `commands.yml`: this file contains all the commands that can be used by jobs to executes. Commands are reusable functions that are shared by multiple jobs.
4. `jobs.yml`: this file contains the jobs that are used by workflows to carry on some specific tasks. They are composed of sequential commands.
5. `workflows.yml`: this file contains the shared workflows that needs to (or can) be always executed, no matter which kind of changes are pushed to CI. An example of these workflows is `analysis` (which is always executed) or `nightly` (which can be executed if a specific pipeline parameter is passed to the CI).
Then, the `pipeline_selection create-configs` attach some specific test workflows, depending on the changes that are present in the PR. These change-dependent workflows live in the [`test_workflows`](https://github.com/facebook/react-native/tree/main/.circleci/configurations/test_workflows) folder.
These workflows are:
* `testAll.yml` => runs all the possible tests. This workflow is executed on main and on PRs which change set touches both iOS and Android
* `testAndroid.yml` => runs all the build steps and Android tests. This is used on changes that happens on the Android codebase and infra (`ReactAndroid` folder)
* `testIOS.yml` => runs all the build steps and iOS tests. This is used on changes that happens on the iOS codebase and infra (`React` folder)
* `testE2E.yml` => runs the E2E tests. As of today, E2E tests can be triggered if the commit message contains the `#run-e2e-tests` tag.
* `testJS.yml` => For all the changes that do not touch native/platform code, we only run JS tests.
Notice that if there are changes on files that do not represents code (for example `.md` files like this one or the `Changelog`) we don't run any CI.
## Test workflows
The test workflows for native code are composed of 2 parts:
- building React Native
- testing
Building React Native requires us to build several parts of it:
1. We need to build the Hermes JS engine
2. We need to build Android to create prebuilds
3. We need to package everything in an npm package that will mimic a React native release
4. We need to create a local maven repository
### Building Hermes Engine
#### Android
The `build_android` workflows takes care of building the Android version of Hermes and to put it properly in a local maven repository.
See the [Build Android](#build_android) section below.
#### iOS
Hermes is a very complicated item to build for iOS.
It is composed of the Hermes compiler (HermesC) and of the actual engine.
Hermes is shipped as a universal XCFramework. This means that we need to build all the architecture slices and then put them together in the XCFramework archive.
We also need to build 2 configurations: Debug and Release.
In order to be efficient and to save costs, we parallelize the process as much as possible:
1. We prepare the environment for building Hermes.
2. We build HermesC which is required by all the slices.
3. We start 8 jobs to build all the required slices in parallel:
1. `iphone` slice, Debug mode
1. `iphonesimulator` slice, Debug mode
1. `macos` slice, Debug mode
1. `catalyst` slice, Debug mode
1. `iphone` slice, Release mode
1. `iphonesimulator` slice, Release mode
1. `macos` slice, Release mode
1. `catalyst` slice, Release mode
4. We then have 2 jobs to create the Debug and Release tarballs in parallel.
1. The Debug job receives the 4 Debug slices
1. The Release job receives the 4 Release slices
The `Debug` and `Release` tarball are then uploaded as artifacts. Notice that these we use these artifacts to **test the release** of React Native.
While building Hermes, we take also care of building the dSYMs. A dSYM (Debug Symbols) is an archive that contains the Debug Symbols that users can load to de-symbolicate the Hermes Stack traces. These symbols are published when we create a React Native release.
A lot of these build steps are automated by some shell scripts that lives in the [`react-native/packages/react-native/sdks/hermes-engine/utils` folder](https://github.com/facebook/react-native/tree/main/packages/react-native/sdks/hermes-engine/utils).
### Build Android
The android build is all managed by Gradle, so building android should be as easy as calling a [`gradle` command](https://github.com/facebook/react-native/blob/main/.circleci/configurations/jobs.yml#L268-L274).
The relevant part here is that the build android generates a `maven-local` repository that is passed to the [`build_npm_package`](https://github.com/facebook/react-native/blob/main/.circleci/configurations/jobs.yml#L1182) and that we use to test the releases.
### Build NPM package
This job is the responsible to create an NPM package that is suitable to be released or tested in CI.
If we are in a release flow (for example the Nightly workflow), it also proceed with the publication.
The job can be invoked with different parameters:
- `dry-run` => it does not publish anything, but prepare the artifacts to be used for testing
- `nightly` => it creates the artifacts and publish a nightly version of React Native.
- `release` => it creates the artifacts and publish a stable version of React Native.
The build NPM package takes all the artifacts produced in the previous steps (iOS' Hermes, iOS' Hermes dSYMs, Android's `maven-local`) and creates an npm package packing all the code.
If in a release mode, it also proceed publishing the NPM package to NPM, and the artifacts to Maven central, which we use to distribute all the artifacts.
This job also uploads the `maven-local` repository and a zipped version of the npm package to CircleCI's artifacts. We use these artifacts to **test the release** of React Native.
## Testing React Native
React Native tests runs in two different scenarios:
- RNTester
- A New App
### RNTester
RNTester is our internal testing app. It is a fully working React Native app that lives in the [`react-native/packages/rn-tester` folder](https://github.com/facebook/react-native/tree/main/packages/rn-tester) of the repository.
RNTester is an app which contains code that exercise most part of the React Native frameworks.
It also has the feature of building React Native **from source**. For that reason, it does not have to wait for the NPM package to be ready, but RNTester's tests can start as soon as the `build_android` step and the step that builds Hermes for iOS are done.
Notice the Tests on RNTester for iOS consumes the Hermes engine that is built in the previous steps.
For Android, these tests creates an APK that is uploaded as an artifact in CircleCI. We use these artifacts to **test the releases** of React Native..
### A New App
The React Native repo contains a template app in the [`react-native/packages/react-native/template` folder]() that is used to spin up a new application that is preconfigured with React Native.
We have several tests that we run starting from the template, testing various configurations:
- Debug/Release
- JSC/Hermes (two different JS engine we support)
- New/Old Architecture (two different Architectures for React Native)
We want to test all the React Native changes against the template, but we can't publish a React native version on each change that is merged. Therefore, to run tests on the template we use a NPM registry proxy called [Verdaccio](https://verdaccio.org/).
When running a Template test our CI follows roughly these steps:
1. Prepare the executor
2. Start a Verdaccio server
3. Publish on Verdaccio all the monorepo [packages](https://github.com/facebook/react-native/tree/main/packages) on which React Native depends on.
4. Publish on Verdaccio the react-native NPM package that has been created in the NPM step
5. Spin up a new React native apps from the template, downloading react-native from Verdaccio.
In this way, we are sure that we can test all the changes that happen in React Native on a new React Native app.
+108 -7
View File
@@ -1,13 +1,114 @@
version: 2.1
workflows:
version: 2
stub:
jobs:
- circleci-stub
# this allows you to use CircleCI's dynamic configuration feature
setup: true
orbs:
continuation: circleci/continuation@1.0.0
parameters:
# Real pipelines parameters
run_release_workflow:
default: false
type: boolean
run_nightly_workflow:
default: false
type: boolean
release_version:
default: ""
type: string
release_monorepo_packages_version:
default: ""
type: string
release_tag:
default: ""
type: string
release_dry_run:
default: false
type: boolean
jobs:
circleci-stub:
choose_ci_jobs:
docker:
- image: debian:bullseye
resource_class: small
steps:
- run: echo "There is nothing here, just an empty job. Everything has been moved to GitHub Action"
- run:
name: Install Yarn
command: |
apt update
apt install -y wget git curl jq
apt-get update
apt-get install -y ca-certificates curl gnupg
mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=18
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
apt-get update
apt install -y nodejs
npm install --global yarn
- checkout
- run:
name: Yarn Install
command: yarn install
- when:
condition:
or:
- equal: [ main, << pipeline.git.branch >> ]
- matches:
pattern: /0\.[0-9]+[\.[0-9]+]?-stable/
value: << pipeline.git.branch >>
steps:
- run:
name: "[Main or Stable] Create input for config to test everything"
command: |
mkdir -p /tmp/circleci/
echo '{ "run_all": true }' > /tmp/circleci/pipeline_config.json
- when:
condition:
not:
or:
- equal: [ main, << pipeline.git.branch >> ]
- matches:
pattern: /0\.[0-9]+[\.[0-9]+]?-stable/
value: << pipeline.git.branch >>
steps:
- run:
name: "[PR Branch] Filter jobs"
command: |
if [[ -z "$CIRCLE_PULL_REQUEST" ]]; then
echo "Not in a PR. Can't filter properly outside a PR. Please open a PR so that we can run the proper CI tests."
echo "For safety, we run all the tests!"
mkdir -p /tmp/circleci/
echo '{ "run_all": true }' > /tmp/circleci/pipeline_config.json
else
PR_NUMBER="${CIRCLE_PULL_REQUEST##*/}"
node ./scripts/circleci/pipeline_selection.js filter-jobs
fi
- run:
name: Create config
description: Generates a configuration on the fly, depending on the files that have been modified
command: |
node ./scripts/circleci/pipeline_selection.js create-configs
- store_artifacts:
path: .circleci/generated_config.yml
destination: generated_config.yml
- continuation/continue:
configuration_path: .circleci/generated_config.yml
# our single workflow, that triggers the setup job defined above
workflows:
always-run:
jobs:
- choose_ci_jobs:
filters:
tags:
only: /.*/
+580
View File
@@ -0,0 +1,580 @@
# -------------------------
# COMMANDS
# -------------------------
commands:
# Checkout with cache, on machines that are using Docker the cache is ignored
checkout_code_with_cache:
parameters:
checkout_base_cache_key:
default: *checkout_cache_key
type: string
steps:
- restore_cache:
key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
- checkout
- save_cache:
key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
paths:
- ".git"
setup_ruby:
parameters:
ruby_version:
default: "2.6.10"
type: string
steps:
- restore_cache:
key: *gems_cache_key
- run:
name: Set Required Ruby
command: echo << parameters.ruby_version >> > /tmp/required_ruby
- restore_cache:
key: *rbenv_cache_key
- run:
name: Install the proper Ruby and run Bundle install
command: |
# Check if rbenv is installed. CircleCI is migrating to rbenv so we may not need to always install it.
if [[ -z "$(command -v rbenv)" ]]; then
brew install rbenv ruby-build
# Load and init rbenv
(rbenv init 2> /dev/null) || true
echo '' >> ~/.bash_profile
echo 'eval "$(rbenv init - bash)"' >> ~/.bash_profile
source ~/.bash_profile
else
echo "rbenv found; Skipping installation"
fi
# Install the right version of ruby
if [[ -z "$(rbenv versions | grep << parameters.ruby_version >>)" ]]; then
# ensure that `ruby-build` can see all the available versions of Ruby
# some PRs received machines in a weird state, this should make the pipelines
# more robust.
brew update && brew upgrade ruby-build
rbenv install << parameters.ruby_version >>
fi
# Set ruby dependencies
rbenv global << parameters.ruby_version >>
if [[ << parameters.ruby_version >> == "2.6.10" ]]; then
# RubyGems 3.0.3.1 breaks Bundler
gem update --system 3.2.3
rbenv rehash
gem install bundler -v 2.4.22
else
rbenv rehash
gem install bundler
fi
bundle check || bundle install --path vendor/bundle --clean
- save_cache:
key: *rbenv_cache_key
paths:
- ~/.rbenv
- save_cache:
key: *gems_cache_key
paths:
- vendor/bundle
run_yarn:
parameters:
yarn_base_cache_key:
default: *yarn_cache_key
type: string
steps:
- restore_cache:
keys:
- << parameters.yarn_base_cache_key >>-{{ arch }}-{{ checksum "yarn.lock" }}
- << parameters.yarn_base_cache_key >>-{{ arch }}
- << parameters.yarn_base_cache_key >>
- run:
name: "Yarn: Install Dependencies"
command: |
# Skip yarn install on metro bump commits as the package is not yet
# available on npm
if [[ $(echo "$GIT_COMMIT_DESC" | grep -c "Bump metro@") -eq 0 ]]; then
yarn install --non-interactive --cache-folder ~/.cache/yarn
fi
- save_cache:
paths:
- ~/.cache/yarn
key: << parameters.yarn_base_cache_key >>-{{ arch }}-{{ checksum "yarn.lock" }}
build_packages:
steps:
- run:
name: Build packages
command: yarn build
brew_install:
parameters:
package:
description: Homebrew package to install
type: string
steps:
- run:
name: "Brew: Install << parameters.package >>"
command: brew install << parameters.package >>
with_rntester_pods_cache_span:
parameters:
steps:
type: steps
steps:
- run:
name: Setup CocoaPods cache
# Copy packages/rn-tester/Podfile.lock since it can be changed by pod install
command: cp packages/rn-tester/Podfile.lock packages/rn-tester/Podfile.lock.bak
- restore_cache:
keys:
# The committed lockfile is generated using static libraries and USE_HERMES=1 so it could load an outdated cache if a change
# only affects the frameworks or hermes config. To help prevent this also cache based on the content of Podfile.
- *pods_cache_key
- steps: << parameters.steps >>
- save_cache:
paths:
- packages/rn-tester/Pods
key: *pods_cache_key
with_gradle_cache:
parameters:
steps:
type: steps
steps:
- restore_cache:
keys:
- *gradle_cache_key
- v3-gradle-{{ .Environment.CIRCLE_JOB }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-
- v3-gradle-{{ .Environment.CIRCLE_JOB }}-
- v3-gradle-
- steps: << parameters.steps >>
- save_cache:
paths:
- ~/.gradle/caches
- ~/.gradle/wrapper
- packages/react-native/ReactAndroid/build/downloads
- packages/react-native/ReactAndroid/build/third-party-ndk
key: *gradle_cache_key
run_e2e:
parameters:
platform:
description: Target platform
type: enum
enum: ["android", "ios", "js"]
default: "js"
retries:
description: How many times the job should try to run these tests
type: integer
default: 3
steps:
- run:
name: "Run Tests: << parameters.platform >> End-to-End Tests"
command: node ./scripts/e2e/run-ci-e2e-tests.js --<< parameters.platform >> --retries << parameters.retries >>
report_bundle_size:
parameters:
platform:
description: Target platform
type: enum
enum: ["android", "ios"]
steps:
- run:
name: Report size of RNTester.app (analysis-bot)
command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" scripts/circleci/report-bundle-size.sh << parameters.platform >> || true
setup_hermes_version:
steps:
- run:
name: Set up Hermes workspace and caching
command: |
mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes"
if [ -f "$HERMES_VERSION_FILE" ]; then
echo "Hermes Version file found! Using this version for the build:"
cat $HERMES_VERSION_FILE > /tmp/hermes/hermesversion
else
echo "Hermes Version file not found!!!"
echo "Using the last commit from main for the build:"
HERMES_TAG_SHA=$(git ls-remote https://github.com/facebook/hermes main | cut -f 1 | tr -d '[:space:]')
echo $HERMES_TAG_SHA > /tmp/hermes/hermesversion
fi
cat /tmp/hermes/hermesversion
get_react_native_version:
steps:
- run:
name: Get React Native version
command: |
VERSION=$(cat packages/react-native/package.json | jq -r '.version')
# Save the react native version we are building in a file so we can use that file as part of the cache key.
echo "$VERSION" > /tmp/react-native-version
echo "React Native Version is $(cat /tmp/react-native-version)"
HERMES_VERSION="$(cat /tmp/hermes/hermesversion)"
echo "Hermes commit is $HERMES_VERSION"
get_react_native_version_windows:
steps:
- run:
name: Get React Native version on Windows
command: |
$VERSION=cat packages/react-native/package.json | jq -r '.version'
# Save the react native version we are building in a file so we can use that file as part of the cache key.
echo "$VERSION" > /tmp/react-native-version
echo "React Native Version is $(cat /tmp/react-native-version)"
$HERMES_VERSION=cat C:\Users\circleci\project\tmp\hermes\hermesversion
echo "Hermes commit is $HERMES_VERSION"
with_hermes_tarball_cache_span:
parameters:
steps:
type: steps
set_tarball_path:
type: boolean
default: False
flavor:
default: "Debug"
description: The Hermes build type. Must be one of "Debug", "Release".
type: enum
enum: ["Debug", "Release"]
hermes_tarball_artifacts_dir:
type: string
default: *hermes_tarball_artifacts_dir
steps:
- get_react_native_version
- when:
condition:
equal: [ << parameters.flavor >>, "Debug"]
steps:
- restore_cache:
keys:
- *hermes_tarball_debug_cache_key
- when:
condition:
equal: [ << parameters.flavor >>, "Release"]
steps:
- restore_cache:
keys:
- *hermes_tarball_release_cache_key
- when:
condition: << parameters.set_tarball_path >>
steps:
- run:
name: Set HERMES_ENGINE_TARBALL_PATH envvar if Hermes tarball is present
command: |
HERMES_TARBALL_ARTIFACTS_DIR=<< parameters.hermes_tarball_artifacts_dir >>
if [ ! -d $HERMES_TARBALL_ARTIFACTS_DIR ]; then
echo "Hermes tarball artifacts dir not present ($HERMES_TARBALL_ARTIFACTS_DIR). Build Hermes from source."
exit 0
fi
if [ ! -d ~/react-native ]; then
echo "No React Native checkout found. Run `checkout` first."
exit 0
fi
TARBALL_FILENAME=$(node ~/react-native/packages/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>")
TARBALL_PATH=$HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME
echo "Looking for $TARBALL_FILENAME in $HERMES_TARBALL_ARTIFACTS_DIR"
echo "$TARBALL_PATH"
if [ ! -f $TARBALL_PATH ]; then
echo "Hermes tarball not present ($TARBALL_PATH). Build Hermes from source."
exit 0
fi
echo "Found Hermes tarball at $TARBALL_PATH"
echo "export HERMES_ENGINE_TARBALL_PATH=$TARBALL_PATH" >> $BASH_ENV
- run:
name: Print Hermes version
command: |
HERMES_TARBALL_ARTIFACTS_DIR=<< parameters.hermes_tarball_artifacts_dir >>
TARBALL_FILENAME=$(node ~/react-native/packages/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>")
TARBALL_PATH=$HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME
if [[ -e $TARBALL_PATH ]]; then
tar -xf $TARBALL_PATH
echo 'print(HermesInternal?.getRuntimeProperties?.()["OSS Release Version"])' > test.js
./destroot/bin/hermes test.js
rm test.js
rm -rf destroot
else
echo 'No Hermes tarball found.'
fi
- steps: << parameters.steps >>
- when:
condition:
equal: [ << parameters.flavor >>, "Debug"]
steps:
- save_cache:
key: *hermes_tarball_debug_cache_key
paths: *hermes_tarball_cache_paths
- when:
condition:
equal: [ << parameters.flavor >>, "Release"]
steps:
- save_cache:
key: *hermes_tarball_release_cache_key
paths: *hermes_tarball_cache_paths
store_hermes_apple_artifacts:
description: Stores the tarball and the osx binaries
parameters:
flavor:
default: "Debug"
description: The Hermes build type. Must be one of "Debug", "Release".
type: enum
enum: ["Debug", "Release"]
steps:
- when:
condition:
equal: [ << parameters.flavor >>, "Debug"]
steps:
- store_artifacts:
path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-debug.tar.gz
- when:
condition:
equal: [ << parameters.flavor >>, "Release"]
steps:
- store_artifacts:
path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-release.tar.gz
- store_artifacts:
path: /tmp/hermes/osx-bin/<< parameters.flavor >>/hermesc
- store_artifacts:
path: /tmp/hermes/dSYM/<< parameters.flavor >>/hermes.framework.dSYM
stop_job_if_apple_artifacts_are_there:
description: Stops the current job if there are already the required artifacts
parameters:
flavor:
default: "All"
description: The flavor of artifacts to check. Must be one of "Debug", "Release" or "All"
type: enum
enum: ["Debug", "Release", "All"]
steps:
- when:
condition:
equal: [ << parameters.flavor >>, "All"]
steps:
- run:
name: "Export files to be checked"
command: |
echo "/tmp/hermes/Release_tarball_present" > /tmp/hermes_files
echo "/tmp/hermes/Debug_tarball_present" >> /tmp/hermes_files
echo "/tmp/hermes/Release_osx_bin" >> /tmp/hermes_files
echo "/tmp/hermes/Debug_osx_bin" >> /tmp/hermes_files
echo "/tmp/hermes/Release_dSYM" >> /tmp/hermes_files
echo "/tmp/hermes/Debug_dSYM" >> /tmp/hermes_files
- when:
condition:
not:
equal: [ << parameters.flavor >>, "All"]
steps:
- run:
name: "Export files to be checked"
command: |
echo "/tmp/hermes/<< parameters.flavor >>_tarball_present" > /tmp/hermes_files
echo "/tmp/hermes/<< parameters.flavor >>_osx_bin" >> /tmp/hermes_files
echo "/tmp/hermes/<< parameters.flavor >>_dSYM" >> /tmp/hermes_files
- run:
name: Stop if files are present
command: |
files=($(cat /tmp/hermes_files))
# Initialize a flag indicating all files exist
all_files_exist=true
for file in "${files[@]}"; do
if [[ ! -f "$file" ]]; then
all_files_exist=false
echo "$file does not exist."
else
echo "$file exist."
fi
done
if [[ "$all_files_exist" == true ]]; then
echo "Tarball, osx-bin and dSYM are present. Halting this job"
circleci-agent step halt
fi
check_if_tarball_is_present:
description: "Checks if the tarball of a specific Flavor is present and adds a marker file"
parameters:
flavor:
default: "Debug"
description: The flavor of artifacts to check. Must be one of "Debug" or "Release"
type: enum
enum: ["Debug", "Release"]
steps:
- run:
name: Check if << parameters.flavor >> tarball is there
command: |
FLAVOR=debug
if [[ << parameters.flavor >> == "Release" ]]; then
FLAVOR=release
fi
if [[ -f "/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" ]]; then
echo "[HERMES TARBALL] Found the << parameters.flavor >> tarball"
touch /tmp/hermes/<< parameters.flavor >>_tarball_present
fi
check_if_osx_bin_is_present:
description: "Checks if the osx bin of a specific Flavor is present and adds a marker file"
parameters:
flavor:
default: "Debug"
description: The flavor of artifacts to check. Must be one of "Debug" or "Release"
type: enum
enum: ["Debug", "Release"]
steps:
- run:
name: Check if macosx binary is there
command: |
if [[ -d /tmp/hermes/osx-bin/<< parameters.flavor >> ]]; then
echo "[HERMES MACOSX BIN] Found the osx bin << parameters.flavor >>"
touch /tmp/hermes/<< parameters.flavor >>_osx_bin
fi
check_if_dsym_are_present:
description: "Checks if the dSYM a specific Flavor are present and adds a marker file"
parameters:
flavor:
default: "Debug"
description: The flavor of artifacts to check. Must be one of "Debug" or "Release"
type: enum
enum: ["Debug", "Release"]
steps:
- run:
name: Check if dSYM are there
command: |
if [[ -d /tmp/hermes/dSYM/<< parameters.flavor >> ]]; then
echo "[HERMES dSYM] Found the dSYM << parameters.flavor >>"
touch /tmp/hermes/<< parameters.flavor >>_dSYM
fi
setup_hermes_workspace:
description: "Setup Hermes Workspace"
steps:
- run:
name: Set up workspace
command: |
mkdir -p $HERMES_OSXBIN_ARTIFACTS_DIR ./packages/react-native/sdks/hermes
cp -r $HERMES_WS_DIR/hermes/* ./packages/react-native/sdks/hermes/.
cp -r ./packages/react-native/sdks/hermes-engine/utils ./packages/react-native/sdks/hermes/.
with_xcodebuild_cache:
description: "Add caching to iOS jobs to speed up builds"
parameters:
steps:
type: steps
podfile_lock_path:
type: string
default: packages/rn-tester/Podfile.lock
pods_build_folder:
type: string
default: packages/rn-tester/Pods
podfile_lock_cache_key:
type: string
default: *rntester_podfile_lock_cache_key
cocoapods_cache_key:
type: string
default: *cocoapods_cache_key
steps:
- run:
name: Prepare Xcodebuild cache
command: |
WEEK=$(date +"%U")
YEAR=$(date +"%Y")
echo "$WEEK-$YEAR" > /tmp/week_year
- restore_cache:
key: << parameters.podfile_lock_cache_key >>
- restore_cache:
key: << parameters.cocoapods_cache_key >>
- steps: << parameters.steps >>
- save_cache:
key: << parameters.podfile_lock_cache_key >>
paths:
- << parameters.podfile_lock_path >>
- save_cache:
key: << parameters.cocoapods_cache_key >>
paths:
- << parameters.pods_build_folder >>
store_artifacts_if_needed:
description: "This step stores the artifacts only if we are on main or on a stable branch"
parameters:
path:
type: string
destination:
type: string
default: << parameters.path >>
when:
type: enum
enum: ['always', 'on_fail', 'on_success']
default: 'always'
steps:
- when:
condition:
or:
- equal: [ main, << pipeline.git.branch >> ]
- matches:
pattern: /0\.[0-9]+[\.[0-9]+]?-stable/
value: << pipeline.git.branch >>
steps:
- store_artifacts:
when: << parameters.when >>
path: << parameters.path >>
destination: << parameters.destination >>
prepare_ios_tests:
description: This command runs a set of commands to prepare iOS for running unit tests
steps:
- brew_install:
package: xcbeautify
- run:
name: Run Ruby Tests
command: |
cd packages/react-native/scripts
sh run_ruby_tests.sh
- run:
name: Boot iPhone Simulator
command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true
- run:
name: Configure Environment Variables
command: |
echo 'export PATH=/usr/local/opt/node@18/bin:$PATH' >> $BASH_ENV
source $BASH_ENV
- run:
name: "Brew: Tap wix/brew"
command: brew tap wix/brew
- brew_install:
package: applesimutils watchman
- run:
name: Configure Watchman
command: echo "{}" > .watchmanconfig
run_ios_tests:
description: This command run iOS tests and collects results
steps:
- run:
name: "Run Tests: iOS Unit and Integration Tests"
command: yarn test-ios
- run:
name: Zip Derived data folder
when: always
command: |
echo "zipping tests results"
cd /Users/distiller/Library/Developer/Xcode
XCRESULT_PATH=$(find . -name '*.xcresult')
tar -zcvf xcresults.tar.gz $XCRESULT_PATH
- store_artifacts_if_needed:
path: /Users/distiller/Library/Developer/Xcode/xcresults.tar.gz
- report_bundle_size:
platform: ios
- store_test_results:
path: ./reports/junit
+38
View File
@@ -0,0 +1,38 @@
# -------------------------
# EXECUTORS
# -------------------------
executors:
nodelts:
<<: *defaults
docker:
- image: *nodelts_image
resource_class: "large"
nodeprevlts:
<<: *defaults
docker:
- image: *nodeprevlts_image
resource_class: "large"
# Executor with Node & Java used to inspect and lint
node-browsers-small:
<<: *defaults
docker:
- image: *nodelts_browser_image
resource_class: "small"
node-browsers-medium:
<<: *defaults
docker:
- image: *nodelts_browser_image
resource_class: "medium"
reactnativeandroid-xlarge:
<<: *android-defaults
resource_class: "xlarge"
reactnativeandroid-large:
<<: *android-defaults
resource_class: "large"
reactnativeios:
<<: *defaults
macos:
xcode: *xcode_version
resource_class: macos.m1.medium.gen1
environment:
- RCT_BUILD_HERMES_FROM_SOURCE: true
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,99 @@
tests:
when:
and:
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
jobs:
- prepare_release:
name: "prepare_release (dry run test)"
version: "0.0.0"
monorepo_packages_version: "0.0.0"
tag: test
dry_run: true
- prepare_hermes_workspace
- build_android:
release_type: "dry-run"
- build_hermesc_linux:
requires:
- prepare_hermes_workspace
- build_hermesc_apple:
requires:
- prepare_hermes_workspace
- build_apple_slices_hermes:
requires:
- build_hermesc_apple
matrix:
parameters:
flavor: ["Debug", "Release"]
slice: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"]
- build_hermes_macos:
requires:
- build_apple_slices_hermes
matrix:
parameters:
flavor: ["Debug", "Release"]
- build_hermesc_windows:
requires:
- prepare_hermes_workspace
- build_npm_package:
# Build a release package on every untagged commit, but do not publish to npm.
release_type: "dry-run"
requires:
- build_android
- build_hermesc_linux
- build_hermes_macos
- build_hermesc_windows
- test_android:
requires:
- build_android
## Disabled to land removing react-native/template. Re-enable once switched over
## to Helloworld.
# - test_android_template:
# requires:
# - build_npm_package
# matrix:
# parameters:
# architecture: ["NewArch", "OldArch"]
# jsengine: ["Hermes", "JSC"]
# flavor: ["Debug", "Release"]
- test_ios_helloworld:
requires:
- build_hermes_macos
name: "Test Template with Ruby 3.2.2"
ruby_version: "3.2.2"
architecture: "NewArch"
flavor: "Debug"
jsengine: "Hermes"
use_frameworks: "StaticLibraries"
- test_ios_helloworld:
requires:
- build_hermes_macos
matrix:
parameters:
flavor: ["Debug", "Release"]
jsengine: ["Hermes", "JSC"]
use_frameworks: ["StaticLibraries", "DynamicFrameworks"]
exclude:
# This config is tested with Ruby 3.2.2. Let's not double test it.
- flavor: "Debug"
jsengine: "Hermes"
use_frameworks: "StaticLibraries"
- test_ios_rntester:
requires:
- build_hermes_macos
use_frameworks: "DynamicFrameworks"
architecture: "NewArch"
ruby_version: "3.2.2"
matrix:
parameters:
jsengine: ["Hermes", "JSC"]
- test_ios_rntester:
run_unit_tests: true
use_frameworks: "StaticLibraries"
ruby_version: "2.6.10"
requires:
- build_hermes_macos
matrix:
parameters:
jsengine: ["Hermes", "JSC"]
architecture: ["NewArch", "OldArch"]
@@ -0,0 +1,58 @@
tests_android:
when:
and:
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
jobs:
- prepare_release:
name: "prepare_release (dry run test)"
version: "0.0.0"
monorepo_packages_version: "0.0.0"
tag: test
dry_run: true
- prepare_hermes_workspace
- build_android:
release_type: "dry-run"
- build_hermesc_linux:
requires:
- prepare_hermes_workspace
- build_hermesc_apple:
requires:
- prepare_hermes_workspace
- build_apple_slices_hermes:
requires:
- build_hermesc_apple
matrix:
parameters:
flavor: ["Debug", "Release"]
slice: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"]
- build_hermes_macos:
requires:
- build_apple_slices_hermes
matrix:
parameters:
flavor: ["Debug", "Release"]
- build_hermesc_windows:
requires:
- prepare_hermes_workspace
- build_npm_package:
# Build a release package on every untagged commit, but do not publish to npm.
release_type: "dry-run"
requires:
- build_android
- build_hermesc_linux
- build_hermes_macos
- build_hermesc_windows
## Disabled to land removing react-native/template. Re-enable once switched over
## to Helloworld.
# - test_android:
# requires:
# - build_android
# - test_android_template:
# requires:
# - build_npm_package
# matrix:
# parameters:
# architecture: ["NewArch", "OldArch"]
# jsengine: ["Hermes", "JSC"]
# flavor: ["Debug", "Release"]
@@ -0,0 +1,9 @@
tests_e2e:
when:
and:
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
jobs:
- test_e2e_ios:
ruby_version: "2.7.8"
- test_e2e_android
@@ -0,0 +1,86 @@
test_ios:
when:
and:
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
jobs:
- prepare_release:
name: "prepare_release (dry run test)"
version: "0.0.0"
monorepo_packages_version: "0.0.0"
tag: test
dry_run: true
- prepare_hermes_workspace
- build_android:
release_type: "dry-run"
- build_hermesc_linux:
requires:
- prepare_hermes_workspace
- build_hermesc_apple:
requires:
- prepare_hermes_workspace
- build_apple_slices_hermes:
requires:
- build_hermesc_apple
matrix:
parameters:
flavor: ["Debug", "Release"]
slice: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"]
- build_hermes_macos:
requires:
- build_apple_slices_hermes
matrix:
parameters:
flavor: ["Debug", "Release"]
- build_hermesc_windows:
requires:
- prepare_hermes_workspace
- build_npm_package:
# Build a release package on every untagged commit, but do not publish to npm.
release_type: "dry-run"
requires:
- build_android
- build_hermesc_linux
- build_hermes_macos
- build_hermesc_windows
- test_ios_helloworld:
requires:
- build_hermes_macos
name: "Test Template with Ruby 3.2.2"
ruby_version: "3.2.2"
architecture: "NewArch"
flavor: "Debug"
jsengine: "Hermes"
use_frameworks: "StaticLibraries"
- test_ios_helloworld:
requires:
- build_hermes_macos
matrix:
parameters:
flavor: ["Debug", "Release"]
jsengine: ["Hermes", "JSC"]
use_frameworks: ["StaticLibraries", "DynamicFrameworks"]
exclude:
# This config is tested with Ruby 3.2.2. Let's not double test it.
- flavor: "Debug"
jsengine: "Hermes"
use_frameworks: "StaticLibraries"
- test_ios_rntester:
requires:
- build_hermes_macos
use_frameworks: "DynamicFrameworks"
ruby_version: "3.2.2"
architecture: "NewArch"
matrix:
parameters:
jsengine: ["Hermes", "JSC"]
- test_ios_rntester:
run_unit_tests: true
use_frameworks: "StaticLibraries"
ruby_version: "2.6.10"
requires:
- build_hermes_macos
matrix:
parameters:
jsengine: ["Hermes", "JSC"]
architecture: ["NewArch", "OldArch"]
@@ -0,0 +1,11 @@
tests_js:
when:
and:
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
jobs:
- test_js:
run_disabled_tests: false
- test_js:
name: test_js_prev_lts
executor: nodeprevlts
+149
View File
@@ -0,0 +1,149 @@
version: 2.1
# -------------------------
# ORBS
# -------------------------
orbs:
win: circleci/windows@2.4.0
android: circleci/android@2.3.0
# -------------------------
# REFERENCES
# -------------------------
references:
defaults: &defaults
working_directory: ~/react-native
environment:
- GIT_COMMIT_DESC: git log --format=oneline -n 1 $CIRCLE_SHA1
# The public github tokens are publicly visible by design
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: &github_analysisbot_token_a "312d354b5c36f082cfe9"
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: &github_analysisbot_token_b "07973d757026bdd9f196"
# Homebrew currently breaks while updating:
# https://discuss.circleci.com/t/brew-install-fails-while-updating/32992
- HOMEBREW_NO_AUTO_UPDATE: 1
android-defaults: &android-defaults
working_directory: ~/react-native
docker:
- image: reactnativecommunity/react-native-android:v13.0
environment:
- TERM: "dumb"
- GRADLE_OPTS: '-Dorg.gradle.daemon=false'
# By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs.
- ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a"
# Repeated here, as the environment key in this executor will overwrite the one in defaults
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: *github_analysisbot_token_a
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: *github_analysisbot_token_b
hermes_workspace_root: &hermes_workspace_root
/tmp/hermes
hermes_tarball_artifacts_dir: &hermes_tarball_artifacts_dir
/tmp/hermes/hermes-runtime-darwin
hermes_osxbin_artifacts_dir: &hermes_osxbin_artifacts_dir
/tmp/hermes/osx-bin
attach_hermes_workspace: &attach_hermes_workspace
attach_workspace:
at: *hermes_workspace_root
xcodebuild_derived_data_path: &xcodebuild_derived_data_path
~/Library/Developer/Xcode/DerivedData/
main_or_stable_only: &main_or_stable_only
filters:
branches:
only:
- main
- /0\.[0-9]+[\.[0-9]+]?-stable/
# -------------------------
# Dependency Anchors
# -------------------------
dependency_versions:
xcode_version: &xcode_version "15.2"
nodelts_image: &nodelts_image "cimg/node:20.2.0"
nodeprevlts_image: &nodeprevlts_image "cimg/node:18.18.2"
nodelts_browser_image: &nodelts_browser_image "cimg/node:20.2.0-browsers"
# -------------------------
# Cache Key Anchors
# -------------------------
# Anchors for the cache keys
cache_keys:
checkout_cache_key: &checkout_cache_key v1-checkout
gems_cache_key: &gems_cache_key v2-gems-{{ arch }}-{{ checksum "Gemfile.lock" }}
gradle_cache_key: &gradle_cache_key v3-gradle-{{ .Environment.CIRCLE_JOB }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "packages/react-native/ReactAndroid/gradle.properties" }}
yarn_cache_key: &yarn_cache_key v6-yarn-cache-{{ .Environment.CIRCLE_JOB }}
rbenv_cache_key: &rbenv_cache_key v1-rbenv-{{ arch }}-{{ checksum "/tmp/required_ruby" }}
hermes_workspace_cache_key: &hermes_workspace_cache_key v5-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }}
hermes_workspace_debug_cache_key: &hermes_workspace_debug_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }}
hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }}
hermes_linux_cache_key: &hermes_linux_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-linux-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_windows_cache_key: &hermes_windows_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-windows-{{ checksum "/Users/circleci/project/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
# Hermes iOS
hermesc_apple_cache_key: &hermesc_apple_cache_key v4-hermesc-apple-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_apple_slices_cache_key: &hermes_apple_slices_cache_key v8-hermes-apple-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }}
hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v6-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }}
hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v5-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }}
hermes_macosx_bin_release_cache_key: &hermes_macosx_bin_release_cache_key v5-hermes-release-macosx-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_macosx_bin_debug_cache_key: &hermes_macosx_bin_debug_cache_key v3-hermes-debug-macosx-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_dsym_debug_cache_key: &hermes_dsym_debug_cache_key v3-hermes-debug-dsym-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_dsym_release_cache_key: &hermes_dsym_release_cache_key v3-hermes-release-dsym-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
# Cocoapods - RNTester
pods_cache_key: &pods_cache_key v12-pods-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }}
cocoapods_cache_key: &cocoapods_cache_key v12-cocoapods-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock" }}-{{ checksum "packages/rn-tester/Podfile" }}-{{ checksum "/tmp/hermes/hermesversion" }}
rntester_podfile_lock_cache_key: &rntester_podfile_lock_cache_key v11-podfilelock-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile" }}-{{ checksum "/tmp/week_year" }}-{{ checksum "/tmp/hermes/hermesversion" }}
# Cocoapods - HelloWorld
helloworld_cocoapods_cache_key: &helloworld_cocoapods_cache_key v2-cocoapods-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/helloworld/ios/Podfile.lock" }}-{{ checksum "packages/helloworld/ios/Podfile" }}-{{ checksum "/tmp/hermes/hermesversion" }}
helloworld_podfile_lock_cache_key: &helloworld_podfile_lock_cache_key v2-podfilelock-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/helloworld/ios/Podfile" }}-{{ checksum "/tmp/week_year" }}-{{ checksum "/tmp/hermes/hermesversion" }}
cache_paths:
hermes_workspace_macos_cache_paths: &hermes_workspace_macos_cache_paths
- ~/react-native/packages/react-native/sdks/hermes/build_macosx
- ~/react-native/packages/react-native/sdks/hermes/destroot
hermes_tarball_cache_paths: &hermes_tarball_cache_paths
- *hermes_tarball_artifacts_dir
# -------------------------
# Filters
# -------------------------
# CircleCI filters are OR-ed, with all branches triggering by default and tags excluded by default
# CircleCI env-vars are only set with the branch OR tag that triggered the job, not both.
# In this case, CIRCLE_BRANCH is unset, but CIRCLE_TAG is set.
only_release_tags: &only_release_tags
# Both of the following conditions must be included!
# Ignore any commit on any branch by default.
branches:
ignore: /.*/
# Only act on version tags.
tags:
only: /v[0-9]+(\.[0-9]+)*(\-rc(\.[0-9]+)?)?/
# -------------------------
# PIPELINE PARAMETERS
# -------------------------
parameters:
run_release_workflow:
default: false
type: boolean
run_nightly_workflow:
default: false
type: boolean
release_version:
default: ""
type: string
release_monorepo_packages_version:
default: ""
type: string
release_tag:
default: ""
type: string
release_dry_run:
default: false
type: boolean
+28
View File
@@ -0,0 +1,28 @@
# -------------------------
# WORKFLOWS
#
# When creating a new workflow, make sure to include condition:
#
# when:
# and:
# - equal: [ false, << pipeline.parameters.run_release_workflow >> ]
# - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
#
# It's setup this way so we can trigger a release via a POST
# See limitations: https://support.circleci.com/hc/en-us/articles/360050351292-How-to-trigger-a-workflow-via-CircleCI-API-v2
# -------------------------
workflows:
version: 2
analysis:
when:
and:
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
jobs:
# Run lints on every commit
- analyze_code
# Run code checks on PRs
- analyze_pr
+7 -1
View File
@@ -30,11 +30,17 @@ module.exports = {
// These rules are not required with hermes-eslint
'ft-flow/define-flow-type': 0,
'ft-flow/use-flow-type': 0,
'lint/sort-imports': 1,
// flow handles this check for us, so it's not required
'no-undef': 0,
},
},
{
files: ['*.js', '*.js.flow'],
excludedFiles: ['packages/react-native/template/**/*'],
rules: {
'lint/sort-imports': 1,
},
},
{
files: ['package.json'],
parser: 'jsonc-eslint-parser',
+4 -9
View File
@@ -1,5 +1,6 @@
[ignore]
; Ignore build cache folder
; Ignore templates for 'react-native init'
<PROJECT_ROOT>/packages/react-native/template/.*
<PROJECT_ROOT>/packages/react-native/sdks/.*
; Ignore the codegen e2e tests
@@ -26,9 +27,6 @@
; helloworld
<PROJECT_ROOT>/packages/helloworld/ios/Pods/
; Ignore rn-tester Pods
<PROJECT_ROOT>/packages/rn-tester/Pods/
[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
@@ -44,7 +42,6 @@ packages/react-native/flow/
[options]
enums=true
as_const=true
casting_syntax=both
emoji=true
@@ -65,7 +62,7 @@ munge_underscores=true
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/packages/react-native/index.js'
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/packages/react-native/\1'
module.name_mapper='^@react-native/dev-middleware$' -> '<PROJECT_ROOT>/packages/dev-middleware'
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\|xml\)$' -> '<PROJECT_ROOT>/packages/react-native/Libraries/Image/RelativeImageStub'
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/packages/react-native/Libraries/Image/RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
@@ -73,8 +70,6 @@ suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_type=$FlowFixMeEmpty
ban_spread_key_props=true
[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
@@ -96,4 +91,4 @@ untyped-import
untyped-type-import
[version]
^0.255.0
^0.238.0
+1 -1
View File
@@ -1,4 +1,4 @@
name: 🐛 React Native - Bug Report
name: 🐛 Bug Report
description: Report a reproducible bug or regression in React Native.
labels: ["Needs: Triage :mag:"]
body:
@@ -1,76 +0,0 @@
name: 🔍 Debugger - Bug Report
description: Report a bug with React Native DevTools and the New Debugger
labels: ["Needs: Triage :mag:", "Debugger"]
body:
- type: markdown
attributes:
value: "## Reporting a bug for React Native DevTools"
- type: markdown
attributes:
value: |
Thank you for taking the time to report an issue for React Native DevTools, our new Debugger for React Native.
Before you continue:
* If you're using **Expo** and you're noticing a bug, [report it here](https://github.com/expo/expo/issues).
* If you've found a problem with our **documentation**, [report it here](https://github.com/facebook/react-native-website/issues/).
* If you're having an issue with **Metro** (the bundler), [report it here](https://github.com/facebook/metro/issues/).
* If you're using an external library, report the issue to the **library first**.
* Please [search for similar issues](https://github.com/facebook/react-native/issues) in our issue tracker.
Make sure that your issue is tested against the [**latest stable**](https://github.com/facebook/react-native/releases/) of React Native.
- type: textarea
id: description
attributes:
label: Description
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: The list of steps that reproduces the issue.
placeholder: |
1. Install the application with `yarn android`
2. Press `j` to open the debugger
3. Do something...
validations:
required: true
- type: input
id: version
attributes:
label: React Native Version
description: The version of react-native that this issue reproduces on. Bear in mind that only issues on [supported versions](https://github.com/reactwg/react-native-releases#which-versions-are-currently-supported) will be looked into.
placeholder: "0.76.0"
validations:
required: true
- type: textarea
id: react-native-info
attributes:
label: Output of `npx react-native info`
description: Run `npx react-native info` in your terminal, copy and paste the results here.
placeholder: |
Paste the output of `npx react-native info` here. The output looks like:
...
System:
OS: macOS 14.1.1
CPU: (10) arm64 Apple M1 Max
Memory: 417.81 MB / 64.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node: ...
version: 18.14.0
...
render: text
validations:
required: true
- type: textarea
id: extra
attributes:
label: Screenshots and Videos
description: |
Please provide screenshot or a video of your bug if relevant.
Issues with videos and screenshots are more likely to **get prioritized**.
-109
View File
@@ -1,109 +0,0 @@
name: build-android
description: This action builds android
inputs:
release-type:
required: true
description: The type of release we are building. It could be nightly, release or dry-run
run-e2e-tests:
default: 'false'
description: If we need to build to run E2E tests. If yes, we need to build also x86.
runs:
using: composite
steps:
- name: Setup git safe folders
shell: bash
run: git config --global --add safe.directory '*'
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Install node dependencies
uses: ./.github/actions/yarn-install-with-cache
- name: Set React Native Version
shell: bash
run: node ./scripts/releases/set-rn-artifacts-version.js --build-type ${{ inputs.release-type }}
- name: Setup gradle
uses: ./.github/actions/setup-gradle
with:
cache-read-only: "false"
- name: Restore Android ccache
uses: actions/cache/restore@v4
with:
path: /github/home/.cache/ccache
key: v1-ccache-android-${{ github.job }}-${{ github.ref }}
restore-keys: |
v1-ccache-android-${{ github.job }}-
v1-ccache-android-
- name: Show ccache stats
shell: bash
run: ccache -s -v
- name: Build and publish all the Android Artifacts to /tmp/maven-local
shell: bash
run: |
if [[ "${{ inputs.release-type }}" == "dry-run" ]]; then
# dry-run: we only build ARM64 to save time/resources. For release/nightlies the default is to build all archs.
if [[ "${{ inputs.run-e2e-tests }}" == 'true' ]]; then
export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a,x86" # x86 is required for E2E testing
else
export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a"
fi
TASKS="publishAllToMavenTempLocal build"
elif [[ "${{ inputs.release-type }}" == "nightly" ]]; then
# nightly: we set isSnapshot to true so artifacts are sent to the right repository on Maven Central.
export ORG_GRADLE_PROJECT_isSnapshot="true"
TASKS="publishAllToMavenTempLocal publishAndroidToSonatype build"
else
# release: we want to build all archs (default)
TASKS="publishAllToMavenTempLocal publishAndroidToSonatype build"
fi
./gradlew $TASKS -PenableWarningsAsErrors=true
- name: Save Android ccache
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }}
uses: actions/cache/save@v4
with:
path: /github/home/.cache/ccache
key: v1-ccache-android-${{ github.job }}-${{ github.ref }}
- name: Show ccache stats
shell: bash
run: ccache -s -v
- name: Upload Maven Artifacts
uses: actions/upload-artifact@v4.3.4
with:
name: maven-local
path: /tmp/maven-local
- name: Upload test results
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.4
with:
name: build-android-results
compression-level: 1
path: |
packages/react-native-gradle-plugin/react-native-gradle-plugin/build/reports
packages/react-native-gradle-plugin/settings-plugin/build/reports
packages/react-native/ReactAndroid/build/reports
- name: Upload RNTester APK - hermes-debug
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.4
with:
name: rntester-hermes-debug
path: packages/rn-tester/android/app/build/outputs/apk/hermes/debug/
compression-level: 0
- name: Upload RNTester APK - hermes-release
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.4
with:
name: rntester-hermes-release
path: packages/rn-tester/android/app/build/outputs/apk/hermes/release/
compression-level: 0
- name: Upload RNTester APK - jsc-debug
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.4
with:
name: rntester-jsc-debug
path: packages/rn-tester/android/app/build/outputs/apk/jsc/debug/
compression-level: 0
- name: Upload RNTester APK - jsc-release
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.4
with:
name: rntester-jsc-release
path: packages/rn-tester/android/app/build/outputs/apk/jsc/release/
compression-level: 0
@@ -1,103 +0,0 @@
name: build-apple-slices-hermes
description: This action builds hermesc for Apple platforms
inputs:
hermes-version:
required: true
description: The version of Hermes
react-native-version:
required: true
description: The version of Hermes
slice:
required: true
description: The slice of hermes you want to build. It could be iphone, iphonesimulator, macos, catalyst, appletvos, appletvsimulator, xros, or xrossimulator
flavor:
required: true
description: The flavor we want to build. It can be Debug or Release
runs:
using: composite
steps:
- name: Setup xcode
uses: ./.github/actions/setup-xcode
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Restore HermesC Artifact
uses: actions/download-artifact@v4
with:
name: hermesc-apple
path: ./packages/react-native/sdks/hermes/build_host_hermesc
- name: Restore Slice From Cache
id: restore-slice-cache
uses: actions/cache/restore@v4
with:
path: ./packages/react-native/sdks/hermes/build_${{ inputs.slice }}_${{ inputs.flavor }}
key: v6-hermes-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ inputs.slice }}-${{ inputs.flavor }}
- name: Build the Hermes ${{ inputs.slice }} frameworks
shell: bash
run: |
cd ./packages/react-native/sdks/hermes || exit 1
SLICE=${{ inputs.slice }}
FLAVOR=${{ inputs.flavor }}
FINAL_PATH=build_"$SLICE"_"$FLAVOR"
echo "Final path for this slice is: $FINAL_PATH"
if [[ -d "$FINAL_PATH" ]]; then
echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH".
exit 0
fi
if [[ "$ARTIFACTS_EXIST" ]]; then
echo "[HERMES] Skipping! Artifacts exists already."
exit 0
fi
export RELEASE_VERSION=${{ inputs.react-native-version }}
# HermesC is used to build hermes, so it has to be executable
chmod +x ./build_host_hermesc/bin/hermesc
if [[ "$SLICE" == "macosx" ]]; then
echo "[HERMES] Building Hermes for MacOS"
chmod +x ./utils/build-mac-framework.sh
BUILD_TYPE="${{ inputs.flavor }}" ./utils/build-mac-framework.sh
else
echo "[HERMES] Building Hermes for iOS: $SLICE"
chmod +x ./utils/build-ios-framework.sh
BUILD_TYPE="${{ inputs.flavor }}" ./utils/build-ios-framework.sh "$SLICE"
fi
echo "Moving from build_$SLICE to $FINAL_PATH"
mv build_"$SLICE" "$FINAL_PATH"
# check whether everything is there
if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then
echo "Successfully built hermes.framework for $SLICE in $FLAVOR"
else
echo "Failed to built hermes.framework for $SLICE in $FLAVOR"
exit 1
fi
if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then
echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR"
else
echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR"
echo "Please try again"
exit 1
fi
- name: Compress slices to preserve Symlinks
shell: bash
run: |
cd ./packages/react-native/sdks/hermes
tar -czv -f build_${{ matrix.slice }}_${{ matrix.flavor }}.tar.gz build_${{ matrix.slice }}_${{ matrix.flavor }}
- name: Upload Artifact for Slice (${{ inputs.slice }}, ${{ inputs.flavor }}}
uses: actions/upload-artifact@v4.3.4
with:
name: slice-${{ inputs.slice }}-${{ inputs.flavor }}
path: ./packages/react-native/sdks/hermes/build_${{ inputs.slice }}_${{ inputs.flavor }}.tar.gz
- name: Save slice cache
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
uses: actions/cache/save@v4
with:
path: ./packages/react-native/sdks/hermes/build_${{ inputs.slice }}_${{ inputs.flavor }}
key: v6-hermes-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ inputs.SLICE }}-${{ inputs.FLAVOR }}
@@ -1,227 +0,0 @@
name: build-hermes-macos
description: This action builds hermesc for Apple platforms
inputs:
hermes-version:
required: true
description: The version of Hermes
react-native-version:
required: true
description: The version of React Native
flavor:
required: true
description: The flavor we want to build. It can be Debug or Release
runs:
using: composite
steps:
- name: Setup xcode
uses: ./.github/actions/setup-xcode
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Restore Cached Artifacts
uses: actions/cache/restore@v4
with:
key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}
path: |
/tmp/hermes/osx-bin/${{ inputs.flavor }}
/tmp/hermes/dSYM/${{ inputs.flavor }}
/tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ inputs.flavor }}.tar.gz
- name: Check if the required artifacts already exist
id: check_if_apple_artifacts_are_there
shell: bash
run: |
FLAVOR="${{ inputs.flavor }}"
echo "Flavor is $FLAVOR"
OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR"
DSYM="/tmp/hermes/dSYM/$FLAVOR"
HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz"
if [[ -d "$OSX_BIN" ]] && \
[[ -d "$DSYM" ]] && \
[[ -f "$HERMES" ]]; then
echo "Artifacts are there!"
echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV
echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT
fi
- name: Yarn- Install Dependencies
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: ./.github/actions/yarn-install-with-cache
- name: Slice cache macosx
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-macosx-${{ inputs.flavor }}
- name: Slice cache iphoneos
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-iphoneos-${{ inputs.flavor }}
- name: Slice cache iphonesimulator
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-iphonesimulator-${{ inputs.flavor }}
- name: Slice cache appletvos
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-appletvos-${{ inputs.flavor }}
- name: Slice cache appletvsimulator
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-appletvsimulator-${{ inputs.flavor }}
- name: Slice cache catalyst
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-catalyst-${{ inputs.flavor }}
- name: Slice cache xros
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-xros-${{ inputs.flavor }}
- name: Slice cache xrsimulator
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4
with:
path: ./packages/react-native/sdks/hermes/
name: slice-xrsimulator-${{ inputs.flavor }}
- name: Unzip slices
shell: bash
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
cd ./packages/react-native/sdks/hermes
ls -l .
tar -xzv -f build_catalyst_${{ matrix.flavor }}.tar.gz
tar -xzv -f build_iphoneos_${{ matrix.flavor }}.tar.gz
tar -xzv -f build_iphonesimulator_${{ matrix.flavor }}.tar.gz
tar -xzv -f build_appletvos_${{ matrix.flavor }}.tar.gz
tar -xzv -f build_appletvsimulator_${{ matrix.flavor }}.tar.gz
tar -xzv -f build_macosx_${{ matrix.flavor }}.tar.gz
tar -xzv -f build_xros_${{ matrix.flavor }}.tar.gz
tar -xzv -f build_xrsimulator_${{ matrix.flavor }}.tar.gz
- name: Move back build folders
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
shell: bash
run: |
ls -l ./packages/react-native/sdks/hermes
cd ./packages/react-native/sdks/hermes || exit 1
mv build_macosx_${{ inputs.flavor }} build_macosx
mv build_iphoneos_${{ inputs.flavor }} build_iphoneos
mv build_iphonesimulator_${{ inputs.flavor }} build_iphonesimulator
mv build_appletvos_${{ inputs.flavor }} build_appletvos
mv build_appletvsimulator_${{ inputs.flavor }} build_appletvsimulator
mv build_catalyst_${{ inputs.flavor }} build_catalyst
mv build_xros_${{ inputs.flavor }} build_xros
mv build_xrsimulator_${{ inputs.flavor }} build_xrsimulator
- name: Prepare destroot folder
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
shell: bash
run: |
cd ./packages/react-native/sdks/hermes || exit 1
chmod +x ./utils/build-apple-framework.sh
. ./utils/build-apple-framework.sh
prepare_dest_root_for_ci
- name: Create fat framework for iOS
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
shell: bash
run: |
cd ./packages/react-native/sdks/hermes || exit 1
echo "[HERMES] Creating the universal framework"
chmod +x ./utils/build-ios-framework.sh
./utils/build-ios-framework.sh build_framework
chmod +x ./destroot/bin/hermesc
- name: Package the Hermes Apple frameworks
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
shell: bash
run: |
BUILD_TYPE="${{ inputs.flavor }}"
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX)
TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \
--inputDir ./packages/react-native/sdks/hermes \
--buildType "$BUILD_TYPE" \
--outputDir $TARBALL_OUTPUT_DIR)
echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH"
mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR
cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/.
mkdir -p /tmp/hermes/osx-bin/${{ inputs.flavor }}
cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/${{ inputs.flavor }}
ls -lR /tmp/hermes/osx-bin/
- name: Create dSYM archive
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
shell: bash
run: |
FLAVOR=${{ inputs.flavor }}
WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR"
mkdir -p "$WORKING_DIR/macosx"
mkdir -p "$WORKING_DIR/catalyst"
mkdir -p "$WORKING_DIR/iphoneos"
mkdir -p "$WORKING_DIR/iphonesimulator"
mkdir -p "$WORKING_DIR/appletvos"
mkdir -p "$WORKING_DIR/appletvsimulator"
mkdir -p "$WORKING_DIR/xros"
mkdir -p "$WORKING_DIR/xrsimulator"
cd ./packages/react-native/sdks/hermes || exit 1
DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM
cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/"
cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/"
cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/"
cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/"
cp -r build_appletvos/$DSYM_FILE_PATH "$WORKING_DIR/appletvos/"
cp -r build_appletvsimulator/$DSYM_FILE_PATH "$WORKING_DIR/appletvsimulator/"
cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/"
cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/"
DEST_DIR="/tmp/hermes/dSYM/$FLAVOR"
tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" .
mkdir -p "$DEST_DIR"
mv "hermes.framework.dSYM" "$DEST_DIR"
- name: Upload hermes dSYM artifacts
uses: actions/upload-artifact@v4.3.4
with:
name: hermes-dSYM-${{ inputs.flavor }}
path: /tmp/hermes/dSYM/${{ inputs.flavor }}
- name: Upload hermes Runtime artifacts
uses: actions/upload-artifact@v4.3.4
with:
name: hermes-darwin-bin-${{ inputs.flavor }}
path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ inputs.flavor }}.tar.gz
- name: Upload hermes osx artifacts
uses: actions/upload-artifact@v4.3.4
with:
name: hermes-osx-bin-${{ inputs.flavor }}
path: /tmp/hermes/osx-bin/${{ inputs.flavor }}
- name: Upload Hermes Artifacts
uses: actions/cache/save@v4
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
with:
key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}
path: |
/tmp/hermes/osx-bin/${{ inputs.flavor }}
/tmp/hermes/dSYM/${{ inputs.flavor }}
/tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ inputs.flavor }}.tar.gz
@@ -1,37 +0,0 @@
name: build-hermesc-apple
description: This action builds hermesc for Apple platforms
inputs:
hermes-version:
required: true
description: The version of Hermes
react-native-version:
required: true
description: The version of React Native
runs:
using: composite
steps:
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Hermes apple cache
uses: actions/cache/restore@v4
with:
path: ./packages/react-native/sdks/hermes/build_host_hermesc
key: v2-hermesc-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
- name: Build HermesC Apple
shell: bash
run: |
cd ./packages/react-native/sdks/hermes || exit 1
. ./utils/build-apple-framework.sh
build_host_hermesc_if_needed
- name: Upload HermesC Artifact
uses: actions/upload-artifact@v4.3.4
with:
name: hermesc-apple
path: ./packages/react-native/sdks/hermes/build_host_hermesc
- name: Cache hermesc apple
uses: actions/cache/save@v4
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
with:
path: ./packages/react-native/sdks/hermes/build_host_hermesc
key: v2-hermesc-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
enableCrossOsArchive: true
@@ -1,49 +0,0 @@
name: build-hermesc-linux
description: This action builds hermesc for linux platforms
inputs:
hermes-version:
required: True
description: The version of Hermes
react-native-version:
required: True
description: The version of React Native
runs:
using: composite
steps:
- name: Install dependencies
shell: bash
run: |
sudo apt update
sudo apt install -y git openssh-client cmake build-essential \
libreadline-dev libicu-dev jq zip python3
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Linux cache
uses: actions/cache@v4
with:
key: v1-hermes-${{ github.job }}-linux-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
path: |
/tmp/hermes/linux64-bin/
/tmp/hermes/hermes/destroot/
- name: Set up workspace
shell: bash
run: |
mkdir -p /tmp/hermes/linux64-bin
- name: Build HermesC for Linux
shell: bash
run: |
if [ -f /tmp/hermes/linux64-bin/hermesc ]; then
echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.'
else
cd /tmp/hermes
cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive"
cmake --build build --target hermesc -j 4
cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/.
fi
- name: Upload linux artifacts
uses: actions/upload-artifact@v4.3.4
with:
name: hermes-linux-bin
path: /tmp/hermes/linux64-bin
@@ -1,86 +0,0 @@
name: build-hermesc-windows
description: This action builds hermesc for Windows platforms
inputs:
hermes-version:
required: True
description: The version of Hermes
react-native-version:
required: True
description: The version of React Native
runs:
using: composite
steps:
- name: Download Previous Artifacts
uses: actions/download-artifact@v4
with:
name: hermes-workspace
path: 'D:\tmp\hermes'
- name: Set up workspace
shell: powershell
run: |
mkdir -p D:\tmp\hermes\osx-bin
mkdir -p .\packages\react-native\sdks\hermes
cp -r -Force D:\tmp\hermes\hermes\* .\packages\react-native\sdks\hermes\.
cp -r -Force .\packages\react-native\sdks\hermes-engine\utils\* .\packages\react-native\sdks\hermes\.
- name: Windows cache
uses: actions/cache@v4
with:
key: v2-hermes-${{ github.job }}-windows-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
path: |
D:\tmp\hermes\win64-bin\
D:\tmp\hermes\hermes\icu\
D:\tmp\hermes\hermes\deps\
D:\tmp\hermes\hermes\build_release\
- name: setup-msbuild
uses: microsoft/setup-msbuild@v1.3.2
- name: Set up workspace
shell: powershell
run: |
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\icu
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\deps
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\win64-bin
- name: Build HermesC for Windows
shell: powershell
run: |
if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) {
choco install --no-progress cmake --version 3.14.7 --allow-downgrade
if (-not $?) { throw "Failed to install CMake" }
cd $Env:HERMES_WS_DIR\icu
# If Invoke-WebRequest shows a progress bar, it will fail with
# Win32 internal error "Access is denied" 0x5 occurred [...]
$progressPreference = 'silentlyContinue'
Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip"
Expand-Archive -Path "icu.zip" -DestinationPath "."
cd $Env:HERMES_WS_DIR
Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps"
# Include MSVC++ 2015 redistributables
Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps"
$Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR"
$Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu"
cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF
if (-not $?) { throw "Failed to configure Hermes" }
echo "Running windows build..."
cd build_release
cmake --build . --target hermesc --config Release
if (-not $?) { throw "Failed to build Hermes" }
echo "Copying hermesc.exe to win64-bin"
cd $Env:HERMES_WS_DIR
Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin"
# Include Windows runtime dependencies
Copy-Item -Path "deps\*" -Destination "win64-bin"
}
else {
Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild."
}
- name: Upload windows artifacts
uses: actions/upload-artifact@v4.3.4
with:
name: hermes-win64-bin
path: D:\tmp\hermes\win64-bin\
@@ -1,148 +0,0 @@
name: build-npm-package
description: This action builds the NPM package and uploads it to Maven
inputs:
release-type:
required: true
description: The type of release we are building. It could be nightly, release or dry-run
hermes-ws-dir:
required: 'true'
description: The workspace for hermes
gha-npm-token:
required: false
description: The GHA npm token, required only to publish to npm
default: ''
runs:
using: composite
steps:
- name: Setup git safe folders
shell: bash
run: git config --global --add safe.directory '*'
- name: Create /tmp/hermes/osx-bin directory
shell: bash
run: mkdir -p /tmp/hermes/osx-bin
- name: Download osx-bin release artifacts
uses: actions/download-artifact@v4
with:
name: hermes-osx-bin-Release
path: /tmp/hermes/osx-bin/Release
- name: Download osx-bin debug artifacts
uses: actions/download-artifact@v4
with:
name: hermes-osx-bin-Debug
path: /tmp/hermes/osx-bin/Debug
- name: Download darwin-bin release artifacts
uses: actions/download-artifact@v4
with:
name: hermes-darwin-bin-Release
path: /tmp/hermes/hermes-runtime-darwin
- name: Download darwin-bin debug artifacts
uses: actions/download-artifact@v4
with:
name: hermes-darwin-bin-Debug
path: /tmp/hermes/hermes-runtime-darwin
- name: Download hermes dSYM debug artifacts
uses: actions/download-artifact@v4
with:
name: hermes-dSYM-Debug
path: /tmp/hermes/dSYM/Debug
- name: Download hermes dSYM release vartifacts
uses: actions/download-artifact@v4
with:
name: hermes-dSYM-Release
path: /tmp/hermes/dSYM/Release
- name: Download windows-bin artifacts
uses: actions/download-artifact@v4
with:
name: hermes-win64-bin
path: /tmp/hermes/win64-bin
- name: Download linux-bin artifacts
uses: actions/download-artifact@v4
with:
name: hermes-linux-bin
path: /tmp/hermes/linux64-bin
- name: Show /tmp/hermes directory
shell: bash
run: ls -lR /tmp/hermes
- name: Copy Hermes binaries
shell: bash
run: |
mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin
# When build_hermes_macos runs as a matrix, it outputs
if [[ -d ${{ inputs.hermes-ws-dir }}/osx-bin/Release ]]; then
cp -r ${{ inputs.hermes-ws-dir }}/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/.
elif [[ -d ${{ inputs.hermes-ws-dir }}/osx-bin/Debug ]]; then
cp -r ${{ inputs.hermes-ws-dir }}/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/.
else
ls ${{ inputs.hermes-ws-dir }}/osx-bin || echo "hermesc macOS artifacts directory missing."
echo "Could not locate macOS hermesc binary."; exit 1;
fi
# Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them.
if [[ -f "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then
mv "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Debug.tar.gz"
fi
if [[ -f "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then
mv "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-release.tar.gz" "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Release.tar.gz"
fi
cp -r ${{ inputs.hermes-ws-dir }}/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/.
cp -r ${{ inputs.hermes-ws-dir }}/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/.
# Make sure the hermesc files are actually executable.
chmod -R +x packages/react-native/sdks/hermesc/*
mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/
cp ${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz
cp ${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz
cp ${{ inputs.hermes-ws-dir }}/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz
cp ${{ inputs.hermes-ws-dir }}/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Setup gradle
uses: ./.github/actions/setup-gradle
- name: Install dependencies
uses: ./.github/actions/yarn-install-with-cache
- name: Build packages
shell: bash
run: yarn build
# Continue with publish steps
- name: Set npm credentials
if: ${{ inputs.release-type == 'release' ||
inputs.release-type == 'nightly' }}
shell: bash
run: echo "//registry.npmjs.org/:_authToken=${{ inputs.gha-npm-token }}" > ~/.npmrc
- name: Publish NPM
shell: bash
run: |
echo "GRADLE_OPTS = $GRADLE_OPTS"
# We can't have a separate step because each command is executed in a separate shell
# so variables exported in a command are not visible in another.
if [[ "${{ inputs.release-type }}" == "dry-run" ]]; then
export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a"
else
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
fi
node ./scripts/releases-ci/publish-npm.js -t ${{ inputs.release-type }}
- name: Upload npm logs
uses: actions/upload-artifact@v4.3.4
with:
name: npm-logs
path: ~/.npm/_logs
- name: Build release package as a job artifact
if: ${{ inputs.release-type == 'dry-run' }}
shell: bash
run: |
mkdir -p build
FILENAME=$(cd packages/react-native; npm pack | tail -1)
mv "packages/react-native/$FILENAME" build/
echo "$FILENAME" > build/react-native-package-version
- name: Upload release package
uses: actions/upload-artifact@v4.3.4
if: ${{ inputs.release-type == 'dry-run' }}
with:
name: react-native-package
path: build
+88
View File
@@ -0,0 +1,88 @@
name: cache_setup
description: "Cache setup"
inputs:
hermes-version:
description: "Hermes version"
required: true
react-native-version:
description: "React Native version"
required: true
outputs:
cache-hit-hermes-tarball-release:
description: "Whether the hermes tarball release cache was hit"
value: ${{ steps.cache_hermes_tarball_release.outputs.cache-hit }}
cache-hit-hermes-tarball-debug:
description: "Whether the hermes tarball debug cache was hit"
value: ${{ steps.cache_hermes_tarball_debug.outputs.cache-hit }}
cache-hit-macos-bin-release:
description: "Whether the macos bin release cache was hit"
value: ${{ steps.cache_macos_bin_release.outputs.cache-hit }}
cache-hit-macos-bin-debug:
description: "Whether the macos bin debug cache was hit"
value: ${{ steps.cache_macos_bin_debug.outputs.cache-hit }}
cache-hit-dsym-release:
description: "Whether the dsym release cache was hit"
value: ${{ steps.cache_dsym_release.outputs.cache-hit }}
cache-hit-dsym-debug:
description: "Whether the dsym debug cache was hit"
value: ${{ steps.cache_dsym_debug.outputs.cache-hit }}
runs:
using: composite
steps:
- name: Cache hermes tarball release
id: cache_hermes_tarball_release
uses: actions/cache@v4.0.0
with:
path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-Release.tar.gz
key: v4-hermes-tarball-release-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}
enableCrossOsArchive: true
- name: Cache hermes tarball debug
id: cache_hermes_tarball_debug
uses: actions/cache@v4.0.0
with:
path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-Debug.tar.gz
key: v4-hermes-tarball-debug-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}
enableCrossOsArchive: true
- name: Cache macos bin release
id: cache_macos_bin_release
uses: actions/cache@v4.0.0
with:
path: /tmp/hermes/osx-bin/Release
key: v2-hermes-release-macosx-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
enableCrossOsArchive: true
- name: Cache macos bin debug
id: cache_macos_bin_debug
uses: actions/cache@v4.0.0
with:
path: /tmp/hermes/osx-bin/Debug
key: v2-hermes-debug-macosx-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
enableCrossOsArchive: true
- name: Cache dsym release
id: cache_dsym_release
uses: actions/cache@v4.0.0
with:
path: /tmp/hermes/dSYM/Release
key: v2-hermes-release-dsym-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
enableCrossOsArchive: true
- name: Cache dsym debug
id: cache_dsym_debug
uses: actions/cache@v4.0.0
with:
path: /tmp/hermes/dSYM/Debug
key: v2-hermes-debug-dsym-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
enableCrossOsArchive: true
- name: HermesC Apple
id: hermesc_apple
uses: actions/cache@v4.0.0
with:
path: /tmp/hermes/hermesc-apple
key: v2-hermesc-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
enableCrossOsArchive: true
- name: Cache hermes workspace
uses: actions/cache@v4.0.0
with:
path: |
/tmp/hermes/download/
/tmp/hermes/hermes/
key: v1-hermes-${{ inputs.hermes-version }}
enableCrossOsArchive: true
+9 -8
View File
@@ -4,18 +4,19 @@ inputs:
version:
description: "The version of React Native we want to release. For example 0.75.0-rc.0"
required: true
is-latest-on-npm:
is_latest_on_npm:
description: "Whether we want to tag this release as latest on NPM"
required: true
default: "false"
dry-run:
dry_run:
description: "Whether the job should be executed in dry-run mode or not"
default: "true"
default: "false"
runs:
using: composite
steps:
- name: Yarn install
uses: ./.github/actions/yarn-install-with-cache
shell: bash
run: yarn install --non-interactive
- name: Configure Git
shell: bash
run: |
@@ -26,19 +27,19 @@ runs:
run: |
node scripts/releases/create-release-commit.js \
--reactNativeVersion "${{ inputs.version }}" \
--tagAsLatestRelease "${{ inputs.is-latest-on-npm }}" \
--dryRun "${{ inputs.dry-run }}"
--tagAsLatestRelease "${{ inputs.is_latest_on_npm }}" \
--dryRun "${{ inputs.dry_run }}"
GIT_PAGER=cat git show HEAD
- name: Update "latest" tag if needed
shell: bash
if: ${{ inputs.is-latest-on-npm == 'true' }}
if: ${{ inputs.is_latest_on_npm == 'true' }}
run: |
git tag -d "latest"
git push origin :latest
git tag -a "latest" -m "latest"
- name: Pushing release commit
shell: bash
if: ${{ inputs.dry-run == 'false' }}
if: ${{ inputs.dry_run == 'false' }}
run: |
CURR_BRANCH="$(git branch --show-current)"
git push origin "$CURR_BRANCH" --follow-tags
-44
View File
@@ -1,44 +0,0 @@
name: lint
description: Runs all the linters in the codebase
inputs:
node-version:
description: "The node.js version to use"
required: false
default: "18"
github-token:
description: "The GitHub token used by pull-bot"
required: true
runs:
using: composite
steps:
- name: Setup node.js
uses: ./.github/actions/setup-node
with:
node-version: ${{ inputs.node-version }}
- name: Yarn install
shell: bash
run: yarn install --non-interactive --frozen-lockfile
- name: Run linters against modified files (analysis-bot)
shell: bash
run: yarn lint-ci
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
GITHUB_PR_NUMBER: ${{ github.event.number }}
- name: Lint code
shell: bash
run: ./scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ./reports/junit/eslint/results.xml
- name: Lint java
shell: bash
run: ./scripts/circleci/exec_swallow_error.sh yarn lint-java --check
- name: Run flowcheck
shell: bash
run: yarn flow-check
- name: Run typescript check
shell: bash
run: yarn test-typescript
- name: Check license
shell: bash
run: ./scripts/circleci/check_license.sh
- name: Check formatting
shell: bash
run: yarn run format-check
@@ -1,84 +0,0 @@
name: Maestro E2E Android
description: Runs E2E Tests on iOS using Maestro
inputs:
app-path:
required: true
description: The path to the .apk file
app-id:
required: true
description: The id of the app to test
jsengine:
required: true
description: The js engine we are using
maestro-flow:
required: true
description: the folder that contains the maestro tests
install-java:
required: false
default: 'true'
description: whether this action has to install java 17 or not
flavor:
required: true
description: the flavor we want to run - either debug or release
default: release
working-directory:
required: false
default: "."
description: The directory from which metro should be started
runs:
using: composite
steps:
- name: Installing Maestro
shell: bash
run: export MAESTRO_VERSION=1.36.0; curl -Ls "https://get.maestro.mobile.dev" | bash
- name: Set up JDK 17
if: ${{ inputs.install-java == 'true' }}
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'zulu'
- name: Enable KVM group perms
shell: bash
run: |
# ubuntu machines have hardware acceleration available and when we try to create an emulator, the script pauses asking for user input
# These lines set the rules to reply automatically to that question and unblock the creation of the emulator.
# source: https://github.com/ReactiveCircus/android-emulator-runner?tab=readme-ov-file#running-hardware-accelerated-emulators-on-linux-runners
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Build Codegen
shell: bash
if: ${{ inputs.flavor == 'debug' }}
run: ./packages/react-native-codegen/scripts/oss/build.sh
- name: Run e2e tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 24
arch: x86
ram-size: '4096M'
disk-size: '10G'
disable-animations: false
avd-name: e2e_emulator
script: node .github/workflow-scripts/maestro-android.js ${{ inputs.app-path }} ${{ inputs.app-id }} ${{ inputs.maestro-flow }} ${{ inputs.flavor }} ${{ inputs.working-directory }}
- name: Normalize APP_ID
id: normalize-app-id
shell: bash
if: always()
run: |
NORM_APP_ID=$(echo "${{ inputs.app-id }}" | tr '.' '-')
echo "app-id=$NORM_APP_ID" >> $GITHUB_OUTPUT
- name: Store tests result
uses: actions/upload-artifact@v3
if: always()
with:
name: e2e_android_${{ steps.normalize-app-id.outputs.app-id }}_report_${{ inputs.jsengine }}_${{ inputs.flavor }}
path: |
report.xml
screen.mp4
- name: Store Logs
if: failure() && steps.run-tests.outcome == 'failure'
uses: actions/upload-artifact@v4.3.4
with:
name: maestro-logs-android-${{ steps.normalize-app-id.outputs.app-id }}-${{ inputs.jsengine }}-${{ inputs.flavor }}
path: /tmp/MaestroLogs
-121
View File
@@ -1,121 +0,0 @@
name: Maestro E2E iOS
description: Runs E2E Tests on iOS using Maestro
inputs:
app-path:
required: true
description: The path to the .app file
app-id:
required: true
description: The id of the app to test
jsengine:
required: true
description: The js engine we are using
maestro-flow:
required: true
description: the folder that contains the maestro tests
flavor:
required: true
description: Whether we are building for Debug or Release
default: Release
working-directory:
required: false
default: "."
description: The directory from which metro should be started
runs:
using: composite
steps:
- name: Installing Maestro
shell: bash
run: export MAESTRO_VERSION=1.36.0; curl -Ls "https://get.maestro.mobile.dev" | bash
- name: Installing Maestro dependencies
shell: bash
run: |
brew tap facebook/fb
brew install facebook/fb/idb-companion jq
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'zulu'
- name: Start Metro in Debug
shell: bash
if: ${{ inputs.flavor == 'Debug' }}
run: |
cd ${{ inputs.working-directory }}
yarn start &
sleep 5 # to give metro time to load
- name: Run tests
id: run-tests
shell: bash
run: |
# Avoid exit from the job if one of the command returns an error.
# Maestro can fail in case of flakyness, we have some retry logic.
set +e
echo "Launching iOS Simulator: iPhone 15 Pro"
xcrun simctl boot "iPhone 15 Pro"
echo "Installing app on Simulator"
xcrun simctl install booted "${{ inputs.app-path }}"
echo "Retrieving device UDID"
UDID=$(xcrun simctl list devices booted -j | jq -r '[.devices[]] | add | first | .udid')
echo "UDID is $UDID"
echo "Bring simulator in foreground"
open -a simulator
echo "Launch the app"
xcrun simctl launch $UDID ${{ inputs.app-id }}
if [[ ${{ inputs.flavor }} == 'Debug' ]]; then
# To give the app time to warm the metro's cache
sleep 20
fi
echo "Running tests with Maestro"
export MAESTRO_DRIVER_STARTUP_TIMEOUT=1500000 # 25 min. CI is extremely slow
# Add retries for flakyness
MAX_ATTEMPTS=5
CURR_ATTEMPT=0
RESULT=1
while [[ $CURR_ATTEMPT -lt $MAX_ATTEMPTS ]] && [[ $RESULT -ne 0 ]]; do
CURR_ATTEMPT=$((CURR_ATTEMPT+1))
echo "Attempt number $CURR_ATTEMPT"
echo "Start video record using pid: video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid"
xcrun simctl io booted recordVideo video_record_$CURR_ATTEMPT.mov & echo $! > video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid
echo '$HOME/.maestro/bin/maestro --udid=$UDID test ${{ inputs.maestro-flow }} --format junit -e APP_ID=${{ inputs.app-id }}'
$HOME/.maestro/bin/maestro --udid=$UDID test ${{ inputs.maestro-flow }} --format junit -e APP_ID=${{ inputs.app-id }} --debug-output /tmp/MaestroLogs
RESULT=$?
# Stop video
kill -SIGINT $(cat video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid)
done
exit $RESULT
- name: Store video record
if: always()
uses: actions/upload-artifact@v4.3.4
with:
name: e2e_ios_${{ inputs.app-id }}_report_${{ inputs.jsengine }}_${{ inputs.flavor }}
path: |
video_record_1.mov
video_record_2.mov
video_record_3.mov
video_record_4.mov
video_record_5.mov
report.xml
- name: Store Logs
if: failure() && steps.run-tests.outcome == 'failure'
uses: actions/upload-artifact@v4.3.4
with:
name: maestro-logs-${{ inputs.app-id }}-${{ inputs.jsengine }}-${{ inputs.flavor }}
path: /tmp/MaestroLogs
@@ -1,12 +1,15 @@
name: prepare-hermes-workspace
description: This action prepares the hermes workspace with the right hermes and react-native versions.
inputs:
hermes-ws-dir:
HERMES_WS_DIR:
required: true
description: The hermes dir we need to use to setup the workspace
hermes-version-file:
HERMES_VERSION_FILE:
required: true
description: the path to the file that will contain the hermes version
BUILD_FROM_SOURCE:
description: Whether we need to build from source or not
default: true
outputs:
hermes-version:
description: the version of Hermes tied to this run
@@ -26,9 +29,9 @@ runs:
run: |
mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes"
if [ -f "${{ inputs.hermes-version-file }}" ]; then
if [ -f "$HERMES_VERSION_FILE" ]; then
echo "Hermes Version file found! Using this version for the build:"
echo "VERSION=$(cat ${{ inputs.hermes-version-file }})" >> "$GITHUB_OUTPUT"
echo "VERSION=$(cat $HERMES_VERSION_FILE)" >> "$GITHUB_OUTPUT"
else
echo "Hermes Version file not found!!!"
echo "Using the last commit from main for the build:"
@@ -48,7 +51,7 @@ runs:
- name: Cache hermes workspace
id: restore-hermes
uses: actions/cache/restore@v4
uses: actions/cache/restore@v4.0.0
with:
path: |
/tmp/hermes/download/
@@ -69,20 +72,21 @@ runs:
- name: Yarn- Install Dependencies
if: ${{ steps.meaningful-cache.outputs.HERMES_CACHED != 'true' }}
uses: ./.github/actions/yarn-install-with-cache
shell: bash
run: yarn install --non-interactive
- name: Download Hermes tarball
if: ${{ steps.meaningful-cache.outputs.HERMES_CACHED != 'true' }}
shell: bash
run: |
node packages/react-native/scripts/hermes/prepare-hermes-for-build ${{ github.event.pull_request.html_url }}
cp packages/react-native/sdks/download/* ${{ inputs.hermes-ws-dir }}/download/.
cp -r packages/react-native/sdks/hermes/* ${{ inputs.hermes-ws-dir }}/hermes/.
cp packages/react-native/sdks/download/* $HERMES_WS_DIR/download/.
cp -r packages/react-native/sdks/hermes/* $HERMES_WS_DIR/hermes/.
echo ${{ steps.hermes-version.outputs.version }}
- name: Upload Hermes artifact
uses: actions/upload-artifact@v4.3.4
uses: actions/upload-artifact@v4
with:
name: hermes-workspace
path: |
@@ -90,7 +94,7 @@ runs:
/tmp/hermes/hermes/
- name: Cache hermes workspace
uses: actions/cache/save@v4
uses: actions/cache/save@v4.0.0
if: ${{ github.ref == 'refs/heads/main' }} # To avoid that the cache explode.
with:
path: |
@@ -1,8 +1,11 @@
name: prepare-ios-tests
name: prepare_ios_tests
description: Prepare iOS Tests
runs:
using: composite
steps:
- name: brew install xcbeautify
run: brew install xcbeautify
shell: bash
- name: Run Ruby Tests
shell: bash
run: |
@@ -0,0 +1,12 @@
name: report_bundle_size
description: Report bundle size
inputs:
platform:
description: Platform. Either ios or android
default: ios
runs:
using: composite
steps:
- name: Report size of RNTester.app (analysis-bot)
shell: bash
run: GITHUB_TOKEN=${{ secrets.PUBLIC_ANALYSISBOT_GITHUB_TOKEN }} scripts/circleci/report-bundle-size.sh ${{ inputs.platform }} || true
+17
View File
@@ -0,0 +1,17 @@
name: run_e2e
description: "Run End-to-End Tests"
inputs:
platform:
description: "Platform to run tests on"
required: true
default: "js"
retries:
description: "Number of times to retry failed tests"
required: true
default: "3"
runs:
using: composite
steps:
- name: "Run Tests: ${{ inputs.platform }} End-to-End Tests"
run: node ./scripts/e2e/run-ci-e2e-tests.js --${{ inputs.platform }} --retries ${{ inputs.retries }}
shell: bash
+1 -12
View File
@@ -1,20 +1,9 @@
name: Setup gradle
description: "Set up your GitHub Actions workflow with a specific version of gradle"
inputs:
cache-read-only:
description: "Whether the Gradle Cache should be in read-only mode so this job won't be allowed to write to it"
default: "true"
runs:
using: "composite"
steps:
- name: Setup gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v3
with:
gradle-version: wrapper
# We want the Gradle cache to be written only on main/-stable branches run, and only for jobs with `cache-read-only` == false (i.e. `build_android`).
cache-read-only: ${{ (github.ref != 'refs/heads/main' && !contains(github.ref, '-stable')) || inputs.cache-read-only == 'true' }}
# Similarly, for those jobs we want to start with a clean cache so it doesn't grow without limits (this is the negation of the previous condition).
cache-write-only: ${{ (github.ref == 'refs/heads/main' || contains(github.ref, '-stable')) && inputs.cache-read-only != 'true' }}
# Temporarily disabling to try resolve a cache cleanup failure
# gradle-home-cache-cleanup: true
add-job-summary-as-pr-comment: on-failure
+6 -1
View File
@@ -5,10 +5,15 @@ inputs:
description: 'The node.js version to use'
required: false
default: '18'
cache:
description: 'The package manager to use for caching dependencies'
required: false
default: 'yarn'
runs:
using: "composite"
steps:
- name: Setup node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v4.0.0
with:
node-version: ${{ inputs.node-version }}
cache: ${{ inputs.cache }}
@@ -1,4 +1,4 @@
name: setup-xcode-build-cache
name: setup_xcode_build_cache
description: Add caching to iOS jobs to speed up builds
inputs:
hermes-version:
@@ -17,12 +17,12 @@ runs:
YEAR=$(date +"%Y")
echo "$WEEK-$YEAR" > /tmp/week_year
- name: Cache podfile lock
uses: actions/cache@v4
uses: actions/cache@v4.0.0
with:
path: packages/rn-tester/Podfile.lock
key: v11-podfilelock-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile') }}-${{ hashfiles('/tmp/week_year') }}-${{ inputs.hermes-version }}
key: v9-podfilelock-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile') }}-{{ hashfiles('/tmp/week_year') }}-${{ inputs.hermes-version}}
- name: Cache cocoapods
uses: actions/cache@v4
uses: actions/cache@v4.0.0
with:
path: packages/rn-tester/Pods
key: v13-cocoapods-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile.lock') }}-${{ hashfiles('packages/rn-tester/Podfile') }}-${{ inputs.hermes-version}}
key: v11-cocoapods-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile.lock') }}-{{ hashfiles('packages/rn-tester/Podfile') }}-${{ inputs.hermes-version}}
-26
View File
@@ -1,26 +0,0 @@
name: test-js
description: Runs all the JS tests in the codebase
inputs:
node-version:
description: "The node.js version to use"
required: false
default: "18"
runs:
using: composite
steps:
- name: Setup node.js
uses: ./.github/actions/setup-node
with:
node-version: ${{ inputs.node-version }}
- name: Yarn install
uses: ./.github/actions/yarn-install-with-cache
- name: Run Tests - JavaScript Tests
shell: bash
run: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2
- name: Upload test results
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.4
with:
name: test-js-results
compression-level: 1
path: ./reports/junit
@@ -1,46 +0,0 @@
name: test-library-on-nightly
description: Tests a library on a nightly
inputs:
library-npm-package:
description: The library npm package to add
required: true
platform:
description: whether we want to build for iOS or Android
required: true
runs:
using: composite
steps:
- name: Create new app
shell: bash
run: |
cd /tmp
npx @react-native-community/cli init RNApp --skip-install --version nightly
- name: Add library
shell: bash
run: |
cd /tmp/RNApp
yarn add ${{ inputs.library-npm-package }}
- name: Build iOS
shell: bash
if: ${{ inputs.platform == 'ios' }}
run: |
cd /tmp/RNApp/ios
bundle install
bundle exec pod install
xcodebuild build \
-workspace RNApp.xcworkspace \
-scheme RNApp \
-sdk iphonesimulator
- name: Setup Java for Android
if: ${{ inputs.platform == 'android' }}
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'zulu'
- name: Build Android
shell: bash
if: ${{ inputs.platform == 'android' }}
run: |
cd /tmp/RNApp/android
./gradlew assembleDebug
@@ -1,21 +1,37 @@
name: test-ios-helloworld
name: test_ios_helloworld
description: Test iOS Hello World
inputs:
jsengine:
description: Which JavaScript engine to use. Must be one of "Hermes", "JSC".
type: choice
default: Hermes
options:
- JSC
- Hermes
use-frameworks:
description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks"
default: StaticLibraries
description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks"
type: choice
default: StaticLibraries
options:
- StaticLibraries
- DynamicFrameworks
architecture:
description: The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup. Must be one of "OldArch" or "NewArch"
description: The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup
type: choice
default: OldArch
options:
- OldArch
- NewArch
ruby-version:
description: The version of ruby that must be used
default: 2.6.10
flavor:
description: The flavor of the build. Must be one of "Debug", "Release".
type: choice
default: Debug
options:
- Debug
- Release
hermes-version:
description: The version of hermes
required: true
@@ -41,7 +57,8 @@ runs:
shell: bash
run: ls -lR "$HERMES_WS_DIR"
- name: Run yarn
uses: ./.github/actions/yarn-install-with-cache
shell: bash
run: yarn install --non-interactive
- name: Setup ruby
uses: ruby/setup-ruby@v1.170.0
with:
@@ -1,12 +1,12 @@
name: test-ios-rntester
name: test_ios_rntester
description: Test iOS RNTester
inputs:
jsengine:
description: Which JavaScript engine to use. Must be one of "Hermes", "JSC".
default: Hermes
use-frameworks:
description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks"
default: StaticLibraries
description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks"
default: StaticLibraries
architecture:
description: The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup
default: NewArch
@@ -15,7 +15,7 @@ inputs:
default: 2.6.10
run-unit-tests:
description: whether unit tests should run or not.
default: "false"
default: false
hermes-tarball-artifacts-dir:
description: The directory where the hermes tarball artifacts are stored
default: /tmp/hermes/hermes-runtime-darwin
@@ -28,11 +28,6 @@ inputs:
react-native-version:
description: The version of react-native
required: true
run-e2e-tests:
description: Whether we want to run E2E tests or not
required: false
default: false
runs:
using: composite
steps:
@@ -41,7 +36,8 @@ runs:
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Run yarn
uses: ./.github/actions/yarn-install-with-cache
shell: bash
run: yarn install --non-interactive
- name: Download Hermes
uses: actions/download-artifact@v4
with:
@@ -52,8 +48,8 @@ runs:
with:
ruby-version: ${{ inputs.ruby-version }}
- name: Prepare IOS Tests
if: ${{ inputs.run-unit-tests == 'true' }}
uses: ./.github/actions/prepare-ios-tests
if: ${{ inputs.run-unit-tests == true }}
uses: ./.github/actions/prepare_ios_tests
- name: Set HERMES_ENGINE_TARBALL_PATH envvar if Hermes tarball is present
shell: bash
run: |
@@ -93,7 +89,7 @@ runs:
echo 'No Hermes tarball found.'
fi
- name: Setup xcode build cache
uses: ./.github/actions/setup-xcode-build-cache
uses: ./.github/actions/setup_xcode_build_cache
with:
hermes-version: ${{ inputs.hermes-version }}
- name: Install CocoaPods dependencies
@@ -118,34 +114,19 @@ runs:
bundle install
bundle exec pod install
- name: Build RNTester
if: ${{ inputs.run-unit-tests != 'true' && inputs.run-e2e-tests == 'false' }}
if: ${{ inputs.run-unit-tests != true }}
shell: bash
run: |
xcodebuild build \
-workspace packages/rn-tester/RNTesterPods.xcworkspace \
-scheme RNTester \
-sdk iphonesimulator
- name: Build RNTester (E2E Tests)
shell: bash
if: ${{ inputs.run-e2e-tests == 'true' }}
run: |
xcodebuild \
-scheme "RNTester" \
-workspace packages/rn-tester/RNTesterPods.xcworkspace \
-configuration "${{ inputs.flavor }}" \
-sdk "iphonesimulator" \
-destination "generic/platform=iOS Simulator" \
-derivedDataPath "/tmp/RNTesterBuild"
echo "Print path to *.app file"
find "/tmp/RNTesterBuild" -type d -name "*.app"
- name: "Run Tests: iOS Unit and Integration Tests"
if: ${{ inputs.run-unit-tests == 'true' }}
if: ${{ inputs.run-unit-tests == true }}
shell: bash
run: yarn test-ios
- name: Zip Derived data folder
if: ${{ inputs.run-unit-tests == 'true' }}
if: ${{ inputs.run-unit-tests == true }}
shell: bash
run: |
echo "zipping tests results"
@@ -153,14 +134,19 @@ runs:
XCRESULT_PATH=$(find . -name '*.xcresult')
tar -zcvf xcresults.tar.gz $XCRESULT_PATH
- name: Upload artifact
uses: actions/upload-artifact@v4.3.4
if: ${{ inputs.run-unit-tests == 'true' }}
uses: actions/upload-artifact@v2.2.4
if: ${{ inputs.run-unit-tests == true }}
with:
name: xcresults
path: /Users/distiller/Library/Developer/Xcode/xcresults.tar.gz
- name: Report bundle size
if: ${{ inputs.run-unit-tests == true }}
uses: ./.github/actions/report_bundle_size
with:
platform: ios
- name: Store test results
if: ${{ inputs.run-unit-tests == 'true' }}
uses: actions/upload-artifact@v4.3.4
if: ${{ inputs.run-unit-tests == true }}
uses: actions/upload-artifact@v2.2.4
with:
name: test-results
path: ./reports/junit
@@ -1,28 +0,0 @@
name: yarn-install-with-cache
inputs:
update-cache:
description: Update the cache, only do this if you are update-node-modules-cache.yml
default: "false"
description: Only update node_modules if on main
runs:
using: composite
steps:
- name: Load node_modules from cache
# Restore for all branches, but save for 'main'.
uses: actions/cache/restore@v4
with:
path: node_modules/
key: node-modules-${{ hashFiles('package.json') }}
- name: Install dependencies
shell: bash
run: yarn install --non-interactive
- name: Save node_modules to the cache
if: github.ref == 'refs/heads/main' && inputs.update-cache == 'true'
uses: actions/cache/save@v4
with:
path: node_modules/
# We're assuming that variations on branches will slightly vary from main,
# so it's always important to run yarn install --non-interactive after this
# cache is restored.
key: node-modules-v1-${{ hashFiles('package.json') }}
enableCrossOsArchive: true
@@ -1,158 +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
*/
const {
publishTemplate,
verifyPublishedTemplate,
} = require('../publishTemplate');
const mockRun = jest.fn();
const mockSleep = jest.fn();
const mockGetNpmPackageInfo = jest.fn();
const silence = () => {};
jest.mock('../utils.js', () => ({
log: silence,
run: mockRun,
sleep: mockSleep,
getNpmPackageInfo: mockGetNpmPackageInfo,
}));
const getMockGithub = () => ({
rest: {
actions: {
createWorkflowDispatch: jest.fn(),
},
},
});
describe('#publishTemplate', () => {
beforeEach(jest.clearAllMocks);
it('checks commits for magic #publish-package-to-npm&latest string and sets latest', async () => {
mockRun.mockReturnValueOnce(`
The commit message
#publish-packages-to-npm&latest`);
const github = getMockGithub();
await publishTemplate(github, '0.76.0', true);
expect(github.rest.actions.createWorkflowDispatch).toHaveBeenCalledWith({
owner: 'react-native-community',
repo: 'template',
workflow_id: 'release.yaml',
ref: '0.76-stable',
inputs: {
dry_run: true,
is_latest_on_npm: true,
version: '0.76.0',
},
});
});
it('pubished as is_latest_on_npm = false if missing magic string', async () => {
mockRun.mockReturnValueOnce(`
The commit message without magic
`);
const github = getMockGithub();
await publishTemplate(github, '0.76.0', false);
expect(github.rest.actions.createWorkflowDispatch).toHaveBeenCalledWith({
owner: 'react-native-community',
repo: 'template',
workflow_id: 'release.yaml',
ref: '0.76-stable',
inputs: {
dry_run: false,
is_latest_on_npm: false,
version: '0.76.0',
},
});
});
});
describe('#verifyPublishedTemplate', () => {
beforeEach(jest.clearAllMocks);
it("waits on npm updating for version and not 'latest'", async () => {
const NOT_LATEST = false;
mockGetNpmPackageInfo
// template@<version>
.mockReturnValueOnce(Promise.reject('mock http/404'))
.mockReturnValueOnce(Promise.resolve());
mockSleep.mockReturnValueOnce(Promise.resolve()).mockImplementation(() => {
throw new Error('Should not be called again!');
});
const version = '0.77.0';
await verifyPublishedTemplate(version, NOT_LATEST);
expect(mockGetNpmPackageInfo).toHaveBeenLastCalledWith(
'@react-native-community/template',
version,
);
});
it('waits on npm updating version and latest tag', async () => {
const IS_LATEST = true;
const version = '0.77.0';
mockGetNpmPackageInfo
// template@latest → unknown tag
.mockReturnValueOnce(Promise.reject('mock http/404'))
// template@latest != version → old tag
.mockReturnValueOnce(Promise.resolve({version: '0.76.5'}))
// template@latest == version → correct tag
.mockReturnValueOnce(Promise.resolve({version}));
mockSleep
.mockReturnValueOnce(Promise.resolve())
.mockReturnValueOnce(Promise.resolve())
.mockImplementation(() => {
throw new Error('Should not be called again!');
});
await verifyPublishedTemplate(version, IS_LATEST);
expect(mockGetNpmPackageInfo).toHaveBeenCalledWith(
'@react-native-community/template',
'latest',
);
});
describe('timeouts', () => {
let mockProcess;
beforeEach(() => {
mockProcess = jest.spyOn(process, 'exit').mockImplementation(code => {
throw new Error(`process.exit(${code}) called!`);
});
});
afterEach(() => mockProcess.mockRestore());
it('will timeout if npm does not update package version after a set number of retries', async () => {
const RETRIES = 2;
mockGetNpmPackageInfo.mockReturnValue(Promise.reject('mock http/404'));
mockSleep.mockReturnValue(Promise.resolve());
await expect(() =>
verifyPublishedTemplate('0.77.0', true, RETRIES),
).rejects.toThrowError('process.exit(1) called!');
expect(mockGetNpmPackageInfo).toHaveBeenCalledTimes(RETRIES);
});
it('will timeout if npm does not update latest tag after a set number of retries', async () => {
const RETRIES = 7;
const IS_LATEST = true;
mockGetNpmPackageInfo.mockReturnValue(
Promise.resolve({version: '0.76.5'}),
);
mockSleep.mockReturnValue(Promise.resolve());
await expect(async () => {
await verifyPublishedTemplate('0.77.0', IS_LATEST, RETRIES);
}).rejects.toThrowError('process.exit(1) called!');
expect(mockGetNpmPackageInfo).toHaveBeenCalledTimes(RETRIES);
});
});
});
+41 -29
View File
@@ -48,84 +48,96 @@ module.exports = async (github, context, labelWithContext) => {
switch (labelWithContext.label) {
case 'Type: Invalid':
await addComment(
`> [!CAUTION]\n` +
`> **Invalid issue**: This issue is not valid, either is not a bug in React Native, it doesn't match any of the issue template, or we can't help further with this.`,
`| :warning: | Issue is Invalid |\n` +
`| --- | --- |\n` +
`| :information_source: | This issue doesn't match any of the expected types for this repository - closing. |`,
);
await closeIssue();
return;
case 'Type: Question':
await addComment(
`> [!NOTE]\n` +
`> **Not a bug report**: This issue looks like a question. 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 closeIssue();
return;
case 'Resolution: For Stack Overflow':
await addComment(
`> [!NOTE]\n` +
`> **Not a bug report**: This issue looks like a question. 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/).`,
`| :warning: | Issue is a Question |\n` +
`| --- | --- |\n` +
`| :information_source: | 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 closeIssue();
return;
case 'Type: Docs':
await addComment(
`> [!NOTE]\n` +
`> **Docs issue**: This issue looks like an issue related to our docs. Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository.`,
`| :warning: | Documentation Issue |\n` +
`| --- | --- |\n` +
`| :information_source: | Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository. |`,
);
await closeIssue();
return;
case 'Resolution: For Stack Overflow':
await addComment(
`| :warning: | Issue is a Question |\n` +
`| --- | --- |\n` +
`| :information_source: | 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 closeIssue();
return;
case 'Type: Expo':
await addComment(
`> [!NOTE]\n` +
`> **Expo related**: It looks like your issue is related to Expo and not React Native core. Please open your issue in [Expo's repository](https://github.com/expo/expo/issues/new). If you are able to create a repro that showcases that this issue is also happening in React Native vanilla, we will be happy to re-open.`,
`| :warning: | Issue is Related to Expo |\n` +
`| --- | --- |\n` +
`| :information_source: | It looks like your issue is related to Expo and not React Native core. Please open your issue in [Expo's repository](https://github.com/expo/expo/issues/new). If you are able to create a repro that showcases that this issue is also happening in React Native vanilla, we will be happy to re-open. |`,
);
await closeIssue();
return;
case 'Needs: Issue Template':
await addComment(
`> [!WARNING]\n` +
`> **Missing issue template**: 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?assignees=&labels=Needs%3A+Triage+%3Amag%3A&projects=&template=bug_report.yml). 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.`,
`| :warning: | Missing Required Fields |\n` +
`| --- | --- |\n` +
`| :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 requestAuthorFeedback();
return;
case 'Needs: Environment Info':
await addComment(
`> [!WARNING]\n` +
`> **Missing info**: It looks like your issue may be missing information about your development environment. You can obtain the missing information by running <code>react-native info</code> in a console.`,
`| :warning: | Missing Environment Information |\n` +
`| --- | --- |\n` +
`| :information_source: | Your issue may be missing information about your development environment. You can obtain the missing information by running <code>react-native info</code> in a console. |`,
);
await requestAuthorFeedback();
return;
case 'Newer Patch Available':
await addComment(
`> [!TIP]\n` +
`> **Newer version available**: You are on a supported minor version, but it looks like there's a newer patch available - ${labelWithContext.newestPatch}. Please [upgrade](https://reactnative.dev/docs/upgrading) to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, 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 most recent releases.`,
`| :warning: | Newer Version of React Native is Available! |\n` +
`| --- | --- |\n` +
`| :information_source: | You are on a supported minor version, but it looks like there's a newer patch available - ${labelWithContext.newestPatch}. Please [upgrade](https://reactnative.dev/docs/upgrading) to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, 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 most recent releases. |`,
);
return;
case 'Needs: Version Info':
await addComment(
`> [!WARNING]\n` +
`> **Could not parse version**: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.`,
`| :warning: | Add or Reformat Version Info |\n` +
`| --- | --- |\n` +
`| :information_source: | We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.70.2 |`,
);
await requestAuthorFeedback();
return;
case 'Needs: Repro':
await addComment(
`> [!WARNING]\n` +
`> **Missing reproducer**: We could not detect a reproducible example in your issue report. Please provide either: <br/><ul><li>If your bug is UI related: a [Snack](https://snack.expo.dev)</li><li> If your bug is build/upgrade related: a project using our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)</li><li>Otherwise send us a Pull Request with the [RNTesterPlayground.js](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Playground/RNTesterPlayground.js) edited to reproduce your bug.</li></ul>`,
`| :warning: | Missing Reproducible Example |\n` +
`| --- | --- |\n` +
`| :information_source: | We could not detect a reproducible example in your issue report. Please provide either: <br /><ul><li>If your bug is UI related: a [Snack](https://snack.expo.dev)</li><li> If your bug is build/update related: use our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)</li></ul> |`,
);
await requestAuthorFeedback();
return;
case 'Type: Unsupported Version':
await addComment(
`> [!WARNING]\n` +
`> **Unsupported version**: It looks like your issue or the example you provided uses an [unsupported version of React Native](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).<br/><br/>Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`,
`| :warning: | Unsupported Version of React Native |\n` +
`| --- | --- |\n` +
`| :information_source: | It looks like your issue or the example you provided uses an [unsupported version of React Native](https://github.com/reactwg/react-native-releases/blob/main/README.md#releases-support-policy).<br/><br/>Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support. |`,
);
await requestAuthorFeedback();
return;
case 'Type: Too Old Version':
await addComment(
`> [!CAUTION]\n` +
`> **Too old version**: It looks like your issue or the example you provided uses a [**Too Old Version of React Native**](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).<br/><br/>Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`,
`| :warning: | Too Old Version of React Native |\n` +
`| --- | --- |\n` +
`| :information_source: | It looks like your issue or the example you provided uses a [**Too Old Version of React Native**](https://github.com/reactwg/react-native-releases/blob/main/README.md#releases-support-policy).<br/><br/>Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support. |`,
);
await closeIssue();
return;
+25 -1
View File
@@ -9,6 +9,11 @@
const NEEDS_REPRO_LABEL = 'Needs: Repro';
const NEEDS_AUTHOR_FEEDBACK_LABEL = 'Needs: Author Feedback';
const NEEDS_REPRO_HEADER = 'Missing Reproducible Example';
const NEEDS_REPRO_MESSAGE =
`| :warning: | Missing Reproducible Example |\n` +
`| --- | --- |\n` +
`| :information_source: | We could not detect a reproducible example in your issue report. Please provide either: <br /><ul><li>If your bug is UI related: a [Snack](https://snack.expo.dev)</li><li> If your bug is build/update related: use our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate). A reproducer needs to be in a GitHub repository under your username.</li></ul> |`;
const SKIP_ISSUES_OLDER_THAN = '2023-07-01T00:00:00Z';
module.exports = async (github, context) => {
@@ -20,6 +25,7 @@ module.exports = async (github, context) => {
const issue = await github.rest.issues.get(issueData);
const comments = await github.rest.issues.listComments(issueData);
const author = issue.data.user.login;
const issueDate = issue.data.created_at;
@@ -37,6 +43,10 @@ module.exports = async (github, context) => {
return;
}
const botComment = comments.data.find(comment =>
comment.body.includes(NEEDS_REPRO_HEADER),
);
const entities = [issue.data, ...comments.data];
// Look for Snack or a GH repo associated with the user that added an issue or comment
@@ -64,11 +74,25 @@ module.exports = async (github, context) => {
throw error;
}
}
if (!botComment) return;
await github.rest.issues.deleteComment({
...issueData,
comment_id: botComment.id,
});
} else {
await github.rest.issues.addLabels({
...issueData,
labels: [NEEDS_REPRO_LABEL, NEEDS_AUTHOR_FEEDBACK_LABEL],
});
if (botComment) return;
await github.rest.issues.createComment({
...issueData,
body: NEEDS_REPRO_MESSAGE,
});
}
};
@@ -77,7 +101,7 @@ function containsPattern(body, pattern) {
return body.search(regexp) !== -1;
}
// Prevents the bot from responding when maintainer has changed the 'Needs: Repro' label
// Prevents the bot from responding when maintainer has changed Needs: Repro the label
async function hasMaintainerChangedLabel(github, issueData, author) {
const timeline = await github.rest.issues.listEventsForTimeline(issueData);
-108
View File
@@ -1,108 +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
*/
const childProcess = require('child_process');
const usage = `
=== Usage ===
node maestro-android.js <path to app> <app_id> <maestro_flow> <flavor> <working_directory>
@param {string} appPath - Path to the app APK
@param {string} appId - App ID that needs to be launched
@param {string} maestroFlow - Path to the maestro flow to be executed
@param {string} flavor - Flavor of the app to be launched. Can be 'release' or 'debug'
@param {string} workingDirectory - Working directory from where to run Metro
==============
`;
const args = process.argv.slice(2);
if (args.length !== 5) {
throw new Error(`Invalid number of arguments.\n${usage}`);
}
const APP_PATH = args[0];
const APP_ID = args[1];
const MAESTRO_FLOW = args[2];
const IS_DEBUG = args[3] === 'debug';
const WORKING_DIRECTORY = args[4];
async function main() {
console.info('\n==============================');
console.info('Running tests for Android with the following parameters:');
console.info(`APP_PATH: ${APP_PATH}`);
console.info(`APP_ID: ${APP_ID}`);
console.info(`MAESTRO_FLOW: ${MAESTRO_FLOW}`);
console.info(`IS_DEBUG: ${IS_DEBUG}`);
console.info(`WORKING_DIRECTORY: ${WORKING_DIRECTORY}`);
console.info('==============================\n');
console.info('Install app');
childProcess.execSync(`adb install ${APP_PATH}`, {stdio: 'ignore'});
let metroProcess = null;
if (IS_DEBUG) {
console.info('Start Metro');
childProcess.execSync(`cd ${WORKING_DIRECTORY}`, {stdio: 'ignore'});
metroProcess = childProcess.spawn('yarn', ['start', '&'], {
cwd: WORKING_DIRECTORY,
stdio: 'ignore',
detached: true,
});
console.info(`- Metro PID: ${metroProcess.pid}`);
}
console.info('Wait For Metro to Start');
await sleep(5000);
console.info('Start the app');
childProcess.execSync(`adb shell monkey -p ${APP_ID} 1`, {stdio: 'ignore'});
console.info('Start recording to /sdcard/screen.mp4');
childProcess
.exec('adb shell screenrecord /sdcard/screen.mp4', {
stdio: 'ignore',
detached: true,
})
.unref();
console.info(`Start testing ${MAESTRO_FLOW}`);
let error = null;
try {
childProcess.execSync(
`MAESTRO_DRIVER_STARTUP_TIMEOUT=120000 $HOME/.maestro/bin/maestro test ${MAESTRO_FLOW} --format junit -e APP_ID=${APP_ID} --debug-output /tmp/MaestroLogs`,
{stdio: 'inherit'},
);
} catch (err) {
error = err;
} finally {
console.info('Stop recording');
childProcess.execSync('adb pull /sdcard/screen.mp4', {stdio: 'ignore'});
if (IS_DEBUG && metroProcess != null) {
const pid = metroProcess.pid;
console.info(`Kill Metro. PID: ${pid}`);
process.kill(-pid);
console.info(`Metro Killed`);
process.exit();
}
}
if (error) {
throw error;
}
}
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
main();
-103
View File
@@ -1,103 +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
*/
const {run, sleep, getNpmPackageInfo, log} = require('./utils.js');
const TAG_AS_LATEST_REGEX = /#publish-packages-to-npm&latest/;
/**
* Should this commit be `latest` on npm?
*/
function isLatest() {
const commitMessage = run('git log -n1 --pretty=%B');
return TAG_AS_LATEST_REGEX.test(commitMessage);
}
module.exports.isLatest = isLatest;
/**
* Create a Github Action to publish the community template matching the released version
* of React Native.
*/
module.exports.publishTemplate = async (github, version, dryRun = true) => {
log(`📤 Get the ${TEMPLATE_NPM_PKG} repo to publish ${version}`);
const is_latest_on_npm = isLatest();
const majorMinor = /^v?(\d+\.\d+)/.exec(version);
if (!majorMinor) {
log(`🔥 can't capture MAJOR.MINOR from '${version}', giving up.`);
process.exit(1);
}
// MAJOR.MINOR-stable
const ref = `${majorMinor[1]}-stable`;
await github.rest.actions.createWorkflowDispatch({
owner: 'react-native-community',
repo: 'template',
workflow_id: 'release.yaml',
ref,
inputs: {
dry_run: dryRun,
is_latest_on_npm,
// 0.75.0-rc.0, note no 'v' prefix
version: version.replace(/^v/, ''),
},
});
};
const SLEEP_S = 10;
const MAX_RETRIES = 3 * 6; // 3 minutes
const TEMPLATE_NPM_PKG = '@react-native-community/template';
/**
* Will verify that @latest and the @<version> have been published.
*
* NOTE: This will infinitely query each step until successful, make sure the
* calling job has a timeout.
*/
module.exports.verifyPublishedTemplate = async (
version,
latest = false,
retries = MAX_RETRIES,
) => {
log(`🔍 Is ${TEMPLATE_NPM_PKG}@${version} on npm?`);
let count = retries;
while (count-- > 0) {
try {
const json = await getNpmPackageInfo(
TEMPLATE_NPM_PKG,
latest ? 'latest' : version,
);
log(`🎉 Found ${TEMPLATE_NPM_PKG}@${version} on npm`);
if (!latest) {
return;
}
if (json.version === version) {
log(`🎉 ${TEMPLATE_NPM_PKG}@latest → ${version} on npm`);
return;
}
log(
`🐌 ${TEMPLATE_NPM_PKG}@latest → ${pkg.version} on npm and not ${version} as expected, retrying...`,
);
} catch (e) {
log(`Nope, fetch failed: ${e.message}`);
}
await sleep(SLEEP_S);
}
let msg = `🚨 Timed out when trying to verify ${TEMPLATE_NPM_PKG}@${version} on npm`;
if (latest) {
msg += ' and latest tag points to this version.';
}
log(msg);
process.exit(1);
};
-29
View File
@@ -1,29 +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
*/
const {execSync} = require('child_process');
function run(cmd) {
return execSync(cmd, 'utf8').toString().trim();
}
module.exports.run = run;
async function sleep(seconds) {
return new Promise(resolve => setTimeout(resolve, seconds * 1000));
}
module.exports.sleep = sleep;
async function getNpmPackageInfo(pkg, versionOrTag) {
return fetch(`https://registry.npmjs.org/${pkg}/${versionOrTag}`).then(resp =>
resp.json(),
);
}
module.exports.getNpmPackageInfo = getNpmPackageInfo;
module.exports.log = (...args) => console.log(...args);
@@ -10,6 +10,11 @@
module.exports = async (github, context) => {
const issue = context.payload.issue;
// Ignore issues using upgrade template (they use a special label)
if (issue.labels.find(label => label.name === 'Type: Upgrade Issue')) {
return;
}
const issueVersionUnparsed =
getReactNativeVersionFromIssueBodyIfExists(issue);
const issueVersion = parseVersionFromString(issueVersionUnparsed);
+1 -1
View File
@@ -24,4 +24,4 @@ jobs:
- name: Automatic Rebase
uses: cirrus-actions/rebase@1.8
env:
GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-20
View File
@@ -1,20 +0,0 @@
name: Keep Github Actions Cache < 10GB
on:
workflow_dispatch:
schedule:
# Run every 2hrs during weekdays
- cron: "0 0/2 * * 1-5"
jobs:
cache-cleaner:
if: github.repository == 'facebook/react-native'
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18
uses: actions/setup-node@v4
- name: Trim the cache
run: node scripts/clean-gha-cache.js
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const checkForReproducer = require('./.github/workflow-scripts/checkForReproducer.js')
await checkForReproducer(github, context)
-32
View File
@@ -1,32 +0,0 @@
# This jobs runs every day 2 hours after the nightly job and its purpose is to report
# a failure in case the nightly failed to be published. We are going to hook this to an internal automation.
name: Check Nigthlies
on:
workflow_dispatch:
# nightly build @ 4:15 AM UTC
schedule:
- cron: '15 4 * * *'
jobs:
check-nightly:
runs-on: ubuntu-latest
if: github.repository == 'facebook/react-native'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check nightly
run: |
TODAY=$(date "+%Y%m%d")
echo "Checking nightly for $TODAY"
NIGHTLY="$(npm view react-native | grep $TODAY)"
if [[ -z $NIGHTLY ]]; then
echo 'Nightly job failed.'
exit 1
else
echo 'Nightly Worked, All Good!'
fi
test-libraries:
uses: ./.github/workflows/test-libraries-on-nightlies.yml
needs: check-nightly
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
if(!context.payload.commits || !context.payload.commits.length) return;
const sha = context.payload.commits[0].id;
@@ -48,7 +48,7 @@ jobs:
issue_number: closedPrNumber,
owner: context.repo.owner,
repo: context.repo.repo,
body: `This pull request was successfully merged by ${authorName} in **${sha}**\n\n<sup>[When will my fix make it into a release?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#when-will-my-fix-make-it-into-a-release) | [How to file a pick request?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#how-to-open-a-pick-request)</sup>`
body: `This pull request was successfully merged by ${authorName} in **${sha}**.\n\n<sup>[When will my fix make it into a release?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#when-will-my-fix-make-it-into-a-release) | [How to file a pick request?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#how-to-open-a-pick-request)</sup>`
});
// If the PR has already been processed (labeled as Merged), skip it
+10 -10
View File
@@ -4,29 +4,29 @@ on:
workflow_dispatch:
inputs:
version:
description: "The version of React Native we want to release. For example 0.75.0-rc.0"
description: 'The version of React Native we want to release. For example 0.75.0-rc.0'
required: true
type: string
is-latest-on-npm:
description: "Whether we want to tag this release as latest on NPM"
is_latest_on_npm:
description: 'Whether we want to tag this release as latest on NPM'
required: true
type: boolean
default: false
dry-run:
description: "Whether the job should be executed in dry-run mode or not"
dry_run:
description: 'Whether the job should be executed in dry-run mode or not'
type: boolean
default: true
default: false
jobs:
create_release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.1.1
with:
token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
fetch-depth: 0
fetch-tags: 'true'
fetch-depth: 0
- name: Check if on stable branch
id: check_stable_branch
run: |
@@ -52,5 +52,5 @@ jobs:
uses: ./.github/actions/create-release
with:
version: ${{ inputs.version }}
is-latest-on-npm: ${{ inputs.is-latest-on-npm }}
dry-run: ${{ inputs.dry-run }}
is_latest_on_npm: ${{ inputs.is_latest_on_npm }}
dry_run: ${{ inputs.dry_run }}
+1 -1
View File
@@ -25,4 +25,4 @@ jobs:
run: yarn danger ci --use-github-checks --failOnErrors
working-directory: packages/react-native-bots
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,13 @@
name: "Validate Gradle Wrapper"
on:
push:
pull_request:
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v3
+577 -63
View File
@@ -1,10 +1,11 @@
name: Nightly
on:
workflow_dispatch:
# nightly build @ 2:15 AM UTC
schedule:
- cron: "15 2 * * *"
workflow_dispatch:
# nightly build @ 2:15 AM UTC
schedule:
- cron: '15 2 * * *'
jobs:
set_release_type:
@@ -26,32 +27,54 @@ jobs:
env:
HERMES_WS_DIR: /tmp/hermes
HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion
BUILD_FROM_SOURCE: true
outputs:
react-native-version: ${{ steps.prepare-hermes-workspace.outputs.react-native-version }}
hermes-version: ${{ steps.prepare-hermes-workspace.outputs.hermes-version }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.1.1
- name: Prepare Hermes Workspace
id: prepare-hermes-workspace
uses: ./.github/actions/prepare-hermes-workspace
with:
hermes-ws-dir: ${{ env.HERMES_WS_DIR }}
hermes-version-file: ${{ env.HERMES_VERSION_FILE }}
HERMES_WS_DIR: ${{ env.HERMES_WS_DIR }}
HERMES_VERSION_FILE: ${{ env.HERMES_VERSION_FILE }}
BUILD_FROM_SOURCE: ${{ env.BUILD_FROM_SOURCE }}
build_hermesc_apple:
runs-on: macos-13
needs: prepare_hermes_workspace
env:
HERMES_WS_DIR: /tmp/hermes
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build HermesC Apple
uses: ./.github/actions/build-hermesc-apple
uses: actions/checkout@v4.1.1
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Hermes apple cache
uses: actions/cache/restore@v4.0.0
with:
hermes-version: ${{ needs.prepare_hermes_workspace.output.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.output.react-native-version }}
path: ./packages/react-native/sdks/hermes/build_host_hermesc
key: v2-hermesc-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
- name: Build HermesC Apple
run: |
cd ./packages/react-native/sdks/hermes || exit 1
. ./utils/build-apple-framework.sh
build_host_hermesc_if_needed
- name: Upload HermesC Artifact
uses: actions/upload-artifact@v4.3.1
with:
name: hermesc-apple
path: ./packages/react-native/sdks/hermes/build_host_hermesc
- name: Cache hermesc apple
uses: actions/cache/save@v4.0.0
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
with:
path: ./packages/react-native/sdks/hermes/build_host_hermesc
key: v2-hermesc-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
enableCrossOsArchive: true
build_apple_slices_hermes:
runs-on: macos-14
@@ -60,24 +83,97 @@ jobs:
HERMES_WS_DIR: /tmp/hermes
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
HERMES_OSXBIN_ARTIFACTS_DIR: /tmp/hermes/osx-bin
IOS_DEPLOYMENT_TARGET: "15.1"
IOS_DEPLOYMENT_TARGET: "13.4"
XROS_DEPLOYMENT_TARGET: "1.0"
MAC_DEPLOYMENT_TARGET: "10.15"
continue-on-error: true
strategy:
fail-fast: false
matrix:
flavor: [Debug, Release]
slice: [macosx, iphoneos, iphonesimulator, appletvos, appletvsimulator, catalyst, xros, xrsimulator]
slice: [macosx, iphoneos, iphonesimulator, catalyst, xros, xrsimulator]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Slice
uses: ./.github/actions/build-apple-slices-hermes
uses: actions/checkout@v4.1.1
- name: Setup xcode
uses: ./.github/actions/setup-xcode
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Restore HermesC Artifact
uses: actions/download-artifact@v4.1.3
with:
flavor: ${{ matrix.flavor }}
slice: ${{ matrix.slice}}
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
name: hermesc-apple
path: ./packages/react-native/sdks/hermes/build_host_hermesc
- name: Restore Slice From Cache
id: restore-slice-cache
uses: actions/cache/restore@v4.0.0
with:
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ matrix.slice }}-${{ matrix.flavor }}
- name: Build the Hermes ${{ matrix.slice }} frameworks
run: |
cd ./packages/react-native/sdks/hermes || exit 1
SLICE=${{ matrix.slice }}
FLAVOR=${{ matrix.flavor }}
FINAL_PATH=build_"$SLICE"_"$FLAVOR"
echo "Final path for this slice is: $FINAL_PATH"
if [[ -d "$FINAL_PATH" ]]; then
echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH".
exit 0
fi
if [[ "$ARTIFACTS_EXIST" ]]; then
echo "[HERMES] Skipping! Artifacts exists already."
exit 0
fi
export RELEASE_VERSION=${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
# HermesC is used to build hermes, so it has to be executable
chmod +x ./build_host_hermesc/bin/hermesc
if [[ "$SLICE" == "macosx" ]]; then
echo "[HERMES] Building Hermes for MacOS"
chmod +x ./utils/build-mac-framework.sh
BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-mac-framework.sh
else
echo "[HERMES] Building Hermes for iOS: $SLICE"
chmod +x ./utils/build-ios-framework.sh
BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-ios-framework.sh "$SLICE"
fi
echo "Moving from build_$SLICE to $FINAL_PATH"
mv build_"$SLICE" "$FINAL_PATH"
# check whether everything is there
if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then
echo "Successfully built hermes.framework for $SLICE in $FLAVOR"
else
echo "Failed to built hermes.framework for $SLICE in $FLAVOR"
exit 1
fi
if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then
echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR"
else
echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR"
echo "Please try again"
exit 1
fi
- name: Upload Artifact for Slice (${{ matrix.slice }}, ${{ matrix.flavor }}}
uses: actions/upload-artifact@v4.3.1
with:
name: slice-${{ matrix.slice }}-${{ matrix.flavor }}
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
- name: Save slice cache
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
uses: actions/cache/save@v4.0.0
with:
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ matrix.slice }}-${{ matrix.flavor }}
build_hermes_macos:
runs-on: macos-13
@@ -92,13 +188,181 @@ jobs:
flavor: [Debug, Release]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Hermes MacOS
uses: ./.github/actions/build-hermes-macos
uses: actions/checkout@v4.1.1
- name: Setup xcode
uses: ./.github/actions/setup-xcode
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Restore Cached Artifacts
uses: actions/cache/restore@v4.0.0
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
flavor: ${{ matrix.flavor }}
key: v2-hermes-osx-bin-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
/tmp/hermes/osx-bin/${{ matrix.flavor }}
/tmp/hermes/dSYM/${{ matrix.flavor }}
/tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ matrix.flavor }}.tar.gz
- name: Check if the required artifacts already exist
id: check_if_apple_artifacts_are_there
run: |
FLAVOR="${{ matrix.flavor }}"
echo "Flavor is $FLAVOR"
OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR"
DSYM="/tmp/hermes/dSYM/$FLAVOR"
HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz"
if [[ -d "$OSX_BIN" ]] && \
[[ -d "$DSYM" ]] && \
[[ -f "$HERMES" ]]; then
echo "Artifacts are there!"
echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV
echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT
fi
- name: Yarn- Install Dependencies
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: yarn install --non-interactive
- name: Slice cache macosx
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_macosx_${{ matrix.flavor }}
name: slice-macosx-${{ matrix.flavor }}
- name: Slice cache iphoneos
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_iphoneos_${{ matrix.flavor }}
name: slice-iphoneos-${{ matrix.flavor }}
- name: Slice cache iphonesimulator
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_iphonesimulator_${{ matrix.flavor }}
name: slice-iphonesimulator-${{ matrix.flavor }}
- name: Slice cache catalyst
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_catalyst_${{ matrix.flavor }}
name: slice-catalyst-${{ matrix.flavor }}
- name: Slice cache xros
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_xros_${{ matrix.flavor }}
name: slice-xros-${{ matrix.flavor }}
- name: Slice cache xrsimulator
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_xrsimulator_${{ matrix.flavor }}
name: slice-xrsimulator-${{ matrix.flavor }}
- name: Move back build folders
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
ls -l ./packages/react-native/sdks/hermes
cd ./packages/react-native/sdks/hermes || exit 1
mv build_macosx_${{ matrix.flavor }} build_macosx
mv build_iphoneos_${{ matrix.flavor }} build_iphoneos
mv build_iphonesimulator_${{ matrix.flavor }} build_iphonesimulator
mv build_catalyst_${{ matrix.flavor }} build_catalyst
mv build_xros_${{ matrix.flavor }} build_xros
mv build_xrsimulator_${{ matrix.flavor }} build_xrsimulator
- name: Prepare destroot folder
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
cd ./packages/react-native/sdks/hermes || exit 1
chmod +x ./utils/build-apple-framework.sh
. ./utils/build-apple-framework.sh
prepare_dest_root_for_ci
- name: Create fat framework for iOS
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
cd ./packages/react-native/sdks/hermes || exit 1
echo "[HERMES] Creating the universal framework"
chmod +x ./utils/build-ios-framework.sh
./utils/build-ios-framework.sh build_framework
chmod +x ./destroot/bin/hermesc
- name: Package the Hermes Apple frameworks
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
BUILD_TYPE="${{ matrix.flavor }}"
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX)
TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \
--inputDir ./packages/react-native/sdks/hermes \
--buildType "$BUILD_TYPE" \
--outputDir $TARBALL_OUTPUT_DIR)
echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH"
mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR
cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/.
mkdir -p /tmp/hermes/osx-bin/${{ matrix.flavor }}
cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/${{ matrix.flavor }}
ls -lR /tmp/hermes/osx-bin/
- name: Create dSYM archive
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
FLAVOR=${{ matrix.flavor }}
WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR"
mkdir -p "$WORKING_DIR/macosx"
mkdir -p "$WORKING_DIR/catalyst"
mkdir -p "$WORKING_DIR/iphoneos"
mkdir -p "$WORKING_DIR/iphonesimulator"
mkdir -p "$WORKING_DIR/xros"
mkdir -p "$WORKING_DIR/xrsimulator"
cd ./packages/react-native/sdks/hermes || exit 1
DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM
cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/"
cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/"
cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/"
cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/"
cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/"
cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/"
DEST_DIR="/tmp/hermes/dSYM/$FLAVOR"
tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" .
mkdir -p "$DEST_DIR"
mv "hermes.framework.dSYM" "$DEST_DIR"
- name: Upload hermes dSYM artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: hermes-dSYM-${{ matrix.flavor }}
path: /tmp/hermes/dSYM/${{ matrix.flavor }}
- name: Upload hermes Runtime artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: hermes-darwin-bin-${{ matrix.flavor }}
path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ matrix.flavor }}.tar.gz
- name: Upload hermes osx artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: hermes-osx-bin-${{ matrix.flavor }}
path: /tmp/hermes/osx-bin/${{ matrix.flavor }}
- name: Upload Hermes Artifacts
uses: actions/cache/save@v4.0.0
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
with:
key: v2-hermes-artifacts-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
/tmp/hermes/osx-bin/${{ matrix.flavor }}
/tmp/hermes/dSYM/${{ matrix.flavor }}
/tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ matrix.flavor }}.tar.gz
build_hermesc_linux:
runs-on: ubuntu-latest
@@ -108,12 +372,41 @@ jobs:
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build HermesC Linux
uses: ./.github/actions/build-hermesc-linux
uses: actions/checkout@v4.1.1
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y git openssh-client cmake build-essential \
libreadline-dev libicu-dev jq zip python3
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Linux cache
uses: actions/cache@v4.0.0
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
key: v1-hermes-${{ github.job }}-linux-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
/tmp/hermes/linux64-bin/
/tmp/hermes/hermes/destroot/
- name: Set up workspace
run: |
mkdir -p /tmp/hermes/linux64-bin
- name: Build HermesC for Linux
run: |
if [ -f /tmp/hermes/linux64-bin/hermesc ]; then
echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.'
else
cd /tmp/hermes
cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive"
cmake --build build --target hermesc -j 4
cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/.
fi
- name: Upload linux artifacts
uses: actions/upload-artifact@v4.3.0
with:
name: hermes-linux-bin
path: /tmp/hermes/linux64-bin
build_hermesc_windows:
runs-on: windows-2019
@@ -127,12 +420,81 @@ jobs:
CMAKE_DIR: 'C:\Program Files\CMake\bin'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build HermesC Windows
uses: ./.github/actions/build-hermesc-windows
uses: actions/checkout@v4.1.1
- name: Download Previous Artifacts
uses: actions/download-artifact@v4
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
name: hermes-workspace
path: 'D:\tmp\hermes'
- name: Set up workspace
run: |
mkdir -p D:\tmp\hermes\osx-bin
mkdir -p .\packages\react-native\sdks\hermes
cp -r -Force D:\tmp\hermes\hermes\* .\packages\react-native\sdks\hermes\.
cp -r -Force .\packages\react-native\sdks\hermes-engine\utils\* .\packages\react-native\sdks\hermes\.
- name: Windows cache
uses: actions/cache@v4.0.0
with:
key: v2-hermes-${{ github.job }}-windows-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
D:\tmp\hermes\win64-bin\
D:\tmp\hermes\hermes\icu\
D:\tmp\hermes\hermes\deps\
D:\tmp\hermes\hermes\build_release\
- name: setup-msbuild
uses: microsoft/setup-msbuild@v1.3.2
- name: Set up workspace
run: |
#New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\icu
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\deps
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\win64-bin
#New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\hermes
#New-Item -ItemType SymbolicLink -ErrorAction SilentlyContinue -Target tmp\hermes\hermes -Path $Env:HERMES_WS_DIR -Name hermes
- name: Build HermesC for Windows
run: |
if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) {
choco install --no-progress cmake --version 3.14.7
if (-not $?) { throw "Failed to install CMake" }
cd $Env:HERMES_WS_DIR\icu
# If Invoke-WebRequest shows a progress bar, it will fail with
# Win32 internal error "Access is denied" 0x5 occurred [...]
$progressPreference = 'silentlyContinue'
Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip"
Expand-Archive -Path "icu.zip" -DestinationPath "."
cd $Env:HERMES_WS_DIR
Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps"
# Include MSVC++ 2015 redistributables
Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps"
$Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR"
$Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu"
cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF
if (-not $?) { throw "Failed to configure Hermes" }
echo "Running windows build..."
cd build_release
cmake --build . --target hermesc --config Release
if (-not $?) { throw "Failed to build Hermes" }
echo "Copying hermesc.exe to win64-bin"
cd $Env:HERMES_WS_DIR
Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin"
# Include Windows runtime dependencies
Copy-Item -Path "deps\*" -Destination "win64-bin"
}
else {
Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild."
}
- name: Upload windows artifacts
uses: actions/upload-artifact@v4.3.0
with:
name: hermes-win64-bin
path: D:\tmp\hermes\win64-bin\
build_android:
runs-on: 8-core-ubuntu
@@ -142,49 +504,201 @@ jobs:
env:
TERM: "dumb"
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Android
uses: ./.github/actions/build-android
uses: actions/checkout@v4.1.1
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Install dependencies
run: yarn install --non-interactive
- name: Set React Native Version
run: node ./scripts/releases/set-rn-version.js --build-type ${{ needs.set_release_type.outputs.RELEASE_TYPE }}
- name: Setup gradle
uses: ./.github/actions/setup-gradle
- name: Build and publish all the Android Artifacts to /tmp/maven-local
run: |
# By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs.
if [[ "${{ needs.set_release_type.outputs.RELEASE_TYPE }}" == "dry-run" ]]; then
export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a"
else
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
fi
./gradlew publishAllToMavenTempLocal build -PenableWarningsAsErrors=true
shell: bash
- name: Upload test results
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.0
with:
release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }}
name: build-android-results
compression-level: 1
path: |
packages/react-native-gradle-plugin/react-native-gradle-plugin/build/reports
packages/react-native-gradle-plugin/settings-plugin/build/reports
packages/react-native/ReactAndroid/build/reports
- name: Upload RNTester APK
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.0
with:
name: rntester-apk
path: packages/rn-tester/android/app/build/outputs/apk/
compression-level: 0
build_npm_package:
runs-on: 8-core-ubuntu
needs:
[
set_release_type,
prepare_hermes_workspace,
build_hermes_macos,
build_hermesc_linux,
build_hermesc_windows,
build_android,
]
needs: [set_release_type, prepare_hermes_workspace, build_hermes_macos, build_hermesc_linux, build_hermesc_windows,build_android]
container:
image: reactnativecommunity/react-native-android:latest
env:
TERM: "dumb"
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
GRADLE_OPTS: '-Dorg.gradle.daemon=false'
# By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs.
ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a"
# Repeated here, as the environment key in this executor will overwrite the one in defaults
PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }}
PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }}
HERMES_WS_DIR: /tmp/hermes
env:
HERMES_WS_DIR: /tmp/hermes
GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }}
ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED }}
ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }}
REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build and Publish NPM PAckage
uses: ./.github/actions/build-npm-package
uses: actions/checkout@v4.1.1
- name: Create /tmp/hermes/osx-bin directory
run: mkdir -p /tmp/hermes/osx-bin
- name: Download osx-bin release artifacts
uses: actions/download-artifact@v4.1.3
with:
hermes-ws-dir: ${{ env.HERMES_WS_DIR }}
release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }}
gha-npm-token: ${{ env.GHA_NPM_TOKEN }}
name: hermes-osx-bin-Release
path: /tmp/hermes/osx-bin/Release
- name: Download osx-bin debug artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-osx-bin-Debug
path: /tmp/hermes/osx-bin/Debug
- name: Download darwin-bin release artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-darwin-bin-Release
path: /tmp/hermes/hermes-runtime-darwin
- name: Download darwin-bin debug artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-darwin-bin-Debug
path: /tmp/hermes/hermes-runtime-darwin
- name: Download hermes dSYM debug artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-dSYM-Debug
path: /tmp/hermes/dSYM/Debug
- name: Download hermes dSYM release vartifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-dSYM-Release
path: /tmp/hermes/dSYM/Release
- name: Download windows-bin artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-win64-bin
path: /tmp/hermes/win64-bin
- name: Download linux-bin artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-linux-bin
path: /tmp/hermes/linux64-bin
- name: Cache setup
id: cache_setup
uses: ./.github/actions/cache_setup
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
- name: Show /tmp/hermes directory
run: ls -lR /tmp/hermes
- name: Copy Hermes binaries
shell: bash
run: |
mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin
# When build_hermes_macos runs as a matrix, it outputs
if [[ -d $HERMES_WS_DIR/osx-bin/Release ]]; then
cp -r $HERMES_WS_DIR/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/.
elif [[ -d $HERMES_WS_DIR/osx-bin/Debug ]]; then
cp -r $HERMES_WS_DIR/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/.
else
ls $HERMES_WS_DIR/osx-bin || echo "hermesc macOS artifacts directory missing."
echo "Could not locate macOS hermesc binary."; exit 1;
fi
# Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them.
if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then
mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz"
fi
if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then
mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz"
fi
cp -r $HERMES_WS_DIR/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/.
cp -r $HERMES_WS_DIR/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/.
# Make sure the hermesc files are actually executable.
chmod -R +x packages/react-native/sdks/hermesc/*
mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz
cp $HERMES_WS_DIR/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz
cp $HERMES_WS_DIR/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Install dependencies
run: yarn install --non-interactive
- name: Build packages
run: yarn build
# Continue with publish steps
- name: Set npm credentials
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.GHA_NPM_TOKEN }}" > ~/.npmrc
- name: Publish NPM
run: |
git config --global --add safe.directory /__w/react-native/react-native
echo "GRADLE_OPTS = $GRADLE_OPTS"
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
node ./scripts/releases-ci/publish-npm.js -t nightly
- name: Zip Maven Artifacts from /tmp/maven-local
working-directory: /tmp
run: zip -r maven-local.zip maven-local
- name: Upload Maven Artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: maven-local
path: /tmp/maven-local.zip
- name: Upload npm logs
uses: actions/upload-artifact@v4.3.1
with:
name: npm-logs
path: ~/.npm/_logs
- name: Build release package as a job artifact
if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run'
run: |
mkdir -p build
FILENAME=$(cd packages/react-native; npm pack | tail -1)
mv packages/react-native/$FILENAME build/
echo $FILENAME > build/react-native-package-version
- name: Upload release package
uses: actions/upload-artifact@v4.3.1
if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run'
with:
name: react-native-package
path: build
- name: Update rn-diff-purge to generate upgrade-support diff
if: needs.set_release_type.outputs.RELEASE_TYPE == 'release'
run: |
curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \
-d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}"
-3
View File
@@ -21,7 +21,6 @@ jobs:
- name: Verify RN version
uses: actions/github-script@v6
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
script: |
const verifyVersion = require('./.github/workflow-scripts/verifyVersion.js')
const labelWithContext = await verifyVersion(github, context);
@@ -41,7 +40,6 @@ jobs:
- name: Add descriptive label
uses: actions/github-script@v6
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
script: |
const addDescriptiveLabel = require('./.github/workflow-scripts/addDescriptiveLabels.js')
await addDescriptiveLabel(github, context);
@@ -54,7 +52,6 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
script: |
const actOnLabel = require('./.github/workflow-scripts/actOnLabel.js')
await actOnLabel(github, context, {label: context.payload.label.name})
@@ -13,11 +13,11 @@ jobs:
GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.1.1
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Run Yarn Install
uses: ./.github/actions/yarn-install-with-cache
run: yarn install
- name: Build packages
run: yarn build
- name: Set NPM auth token
+610 -79
View File
@@ -2,8 +2,8 @@ name: Publish Release
on:
push:
tags:
- "v0.*.*" # This should match v0.X.Y
- "v0.*.*-rc.*" # This should match v0.X.Y-RC.0
- "v0.*.*" # This should match v0.X.Y
- "v0.*.*-rc.*" # This should match v0.X.Y-RC.0
jobs:
set_release_type:
runs-on: ubuntu-latest
@@ -24,32 +24,55 @@ jobs:
env:
HERMES_WS_DIR: /tmp/hermes
HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion
BUILD_FROM_SOURCE: true
outputs:
react-native-version: ${{ steps.prepare-hermes-workspace.outputs.react-native-version }}
hermes-version: ${{ steps.prepare-hermes-workspace.outputs.hermes-version }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.1.1
- name: Prepare Hermes Workspace
id: prepare-hermes-workspace
uses: ./.github/actions/prepare-hermes-workspace
with:
hermes-ws-dir: ${{ env.HERMES_WS_DIR }}
hermes-version-file: ${{ env.HERMES_VERSION_FILE }}
HERMES_WS_DIR: ${{ env.HERMES_WS_DIR }}
HERMES_VERSION_FILE: ${{ env.HERMES_VERSION_FILE }}
BUILD_FROM_SOURCE: ${{ env.BUILD_FROM_SOURCE }}
build_hermesc_apple:
runs-on: macos-13
needs: prepare_hermes_workspace
env:
HERMES_WS_DIR: /tmp/hermes
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build HermesC Apple
uses: ./.github/actions/build-hermesc-apple
uses: actions/checkout@v4.1.1
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Hermes apple cache
uses: actions/cache/restore@v4.0.0
with:
hermes-version: ${{ needs.prepare_hermes_workspace.output.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.output.react-native-version }}
path: ./packages/react-native/sdks/hermes/build_host_hermesc
key: v2-hermesc-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
- name: Build HermesC Apple
run: |
cd ./packages/react-native/sdks/hermes || exit 1
. ./utils/build-apple-framework.sh
build_host_hermesc_if_needed
- name: Upload HermesC Artifact
uses: actions/upload-artifact@v4.3.1
with:
name: hermesc-apple
path: ./packages/react-native/sdks/hermes/build_host_hermesc
- name: Cache hermesc apple
uses: actions/cache/save@v4.0.0
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
with:
path: ./packages/react-native/sdks/hermes/build_host_hermesc
key: v2-hermesc-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
enableCrossOsArchive: true
build_apple_slices_hermes:
runs-on: macos-14
needs: [build_hermesc_apple, prepare_hermes_workspace]
@@ -57,24 +80,97 @@ jobs:
HERMES_WS_DIR: /tmp/hermes
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
HERMES_OSXBIN_ARTIFACTS_DIR: /tmp/hermes/osx-bin
IOS_DEPLOYMENT_TARGET: "15.1"
IOS_DEPLOYMENT_TARGET: "13.4"
XROS_DEPLOYMENT_TARGET: "1.0"
MAC_DEPLOYMENT_TARGET: "10.15"
continue-on-error: true
strategy:
fail-fast: false
matrix:
flavor: [Debug, Release]
slice: [macosx, iphoneos, iphonesimulator, appletvos, appletvsimulator, catalyst, xros, xrsimulator]
slice: [macosx, iphoneos, iphonesimulator, catalyst, xros, xrsimulator]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Slice
uses: ./.github/actions/build-apple-slices-hermes
uses: actions/checkout@v4.1.1
- name: Setup xcode
uses: ./.github/actions/setup-xcode
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Restore HermesC Artifact
uses: actions/download-artifact@v4.1.3
with:
flavor: ${{ matrix.flavor }}
slice: ${{ matrix.slice}}
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
name: hermesc-apple
path: ./packages/react-native/sdks/hermes/build_host_hermesc
- name: Restore Slice From Cache
id: restore-slice-cache
uses: actions/cache/restore@v4.0.0
with:
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ matrix.slice }}-${{ matrix.flavor }}
- name: Build the Hermes ${{ matrix.slice }} frameworks
run: |
cd ./packages/react-native/sdks/hermes || exit 1
SLICE=${{ matrix.slice }}
FLAVOR=${{ matrix.flavor }}
FINAL_PATH=build_"$SLICE"_"$FLAVOR"
echo "Final path for this slice is: $FINAL_PATH"
if [[ -d "$FINAL_PATH" ]]; then
echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH".
exit 0
fi
if [[ "$ARTIFACTS_EXIST" ]]; then
echo "[HERMES] Skipping! Artifacts exists already."
exit 0
fi
export RELEASE_VERSION=${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
# HermesC is used to build hermes, so it has to be executable
chmod +x ./build_host_hermesc/bin/hermesc
if [[ "$SLICE" == "macosx" ]]; then
echo "[HERMES] Building Hermes for MacOS"
chmod +x ./utils/build-mac-framework.sh
BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-mac-framework.sh
else
echo "[HERMES] Building Hermes for iOS: $SLICE"
chmod +x ./utils/build-ios-framework.sh
BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-ios-framework.sh "$SLICE"
fi
echo "Moving from build_$SLICE to $FINAL_PATH"
mv build_"$SLICE" "$FINAL_PATH"
# check whether everything is there
if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then
echo "Successfully built hermes.framework for $SLICE in $FLAVOR"
else
echo "Failed to built hermes.framework for $SLICE in $FLAVOR"
exit 1
fi
if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then
echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR"
else
echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR"
echo "Please try again"
exit 1
fi
- name: Upload Artifact for Slice (${{ matrix.slice }}, ${{ matrix.flavor }}}
uses: actions/upload-artifact@v4.3.1
with:
name: slice-${{ matrix.slice }}-${{ matrix.flavor }}
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
- name: Save slice cache
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
uses: actions/cache/save@v4.0.0
with:
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ matrix.slice }}-${{ matrix.flavor }}
build_hermes_macos:
runs-on: macos-13
@@ -89,13 +185,181 @@ jobs:
flavor: [Debug, Release]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Hermes MacOS
uses: ./.github/actions/build-hermes-macos
uses: actions/checkout@v4.1.1
- name: Setup xcode
uses: ./.github/actions/setup-xcode
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Restore Cached Artifacts
uses: actions/cache/restore@v4.0.0
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
flavor: ${{ matrix.flavor }}
key: v2-hermes-osx-bin-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
/tmp/hermes/osx-bin/${{ matrix.flavor }}
/tmp/hermes/dSYM/${{ matrix.flavor }}
/tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ matrix.flavor }}.tar.gz
- name: Check if the required artifacts already exist
id: check_if_apple_artifacts_are_there
run: |
FLAVOR="${{ matrix.flavor }}"
echo "Flavor is $FLAVOR"
OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR"
DSYM="/tmp/hermes/dSYM/$FLAVOR"
HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz"
if [[ -d "$OSX_BIN" ]] && \
[[ -d "$DSYM" ]] && \
[[ -f "$HERMES" ]]; then
echo "Artifacts are there!"
echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV
echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT
fi
- name: Yarn- Install Dependencies
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: yarn install --non-interactive
- name: Slice cache macosx
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_macosx_${{ matrix.flavor }}
name: slice-macosx-${{ matrix.flavor }}
- name: Slice cache iphoneos
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_iphoneos_${{ matrix.flavor }}
name: slice-iphoneos-${{ matrix.flavor }}
- name: Slice cache iphonesimulator
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_iphonesimulator_${{ matrix.flavor }}
name: slice-iphonesimulator-${{ matrix.flavor }}
- name: Slice cache catalyst
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_catalyst_${{ matrix.flavor }}
name: slice-catalyst-${{ matrix.flavor }}
- name: Slice cache xros
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_xros_${{ matrix.flavor }}
name: slice-xros-${{ matrix.flavor }}
- name: Slice cache xrsimulator
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
uses: actions/download-artifact@v4.1.3
with:
path: ./packages/react-native/sdks/hermes/build_xrsimulator_${{ matrix.flavor }}
name: slice-xrsimulator-${{ matrix.flavor }}
- name: Move back build folders
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
ls -l ./packages/react-native/sdks/hermes
cd ./packages/react-native/sdks/hermes || exit 1
mv build_macosx_${{ matrix.flavor }} build_macosx
mv build_iphoneos_${{ matrix.flavor }} build_iphoneos
mv build_iphonesimulator_${{ matrix.flavor }} build_iphonesimulator
mv build_catalyst_${{ matrix.flavor }} build_catalyst
mv build_xros_${{ matrix.flavor }} build_xros
mv build_xrsimulator_${{ matrix.flavor }} build_xrsimulator
- name: Prepare destroot folder
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
cd ./packages/react-native/sdks/hermes || exit 1
chmod +x ./utils/build-apple-framework.sh
. ./utils/build-apple-framework.sh
prepare_dest_root_for_ci
- name: Create fat framework for iOS
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
cd ./packages/react-native/sdks/hermes || exit 1
echo "[HERMES] Creating the universal framework"
chmod +x ./utils/build-ios-framework.sh
./utils/build-ios-framework.sh build_framework
chmod +x ./destroot/bin/hermesc
- name: Package the Hermes Apple frameworks
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
BUILD_TYPE="${{ matrix.flavor }}"
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX)
TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \
--inputDir ./packages/react-native/sdks/hermes \
--buildType "$BUILD_TYPE" \
--outputDir $TARBALL_OUTPUT_DIR)
echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH"
mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR
cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/.
mkdir -p /tmp/hermes/osx-bin/${{ matrix.flavor }}
cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/${{ matrix.flavor }}
ls -lR /tmp/hermes/osx-bin/
- name: Create dSYM archive
if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }}
run: |
FLAVOR=${{ matrix.flavor }}
WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR"
mkdir -p "$WORKING_DIR/macosx"
mkdir -p "$WORKING_DIR/catalyst"
mkdir -p "$WORKING_DIR/iphoneos"
mkdir -p "$WORKING_DIR/iphonesimulator"
mkdir -p "$WORKING_DIR/xros"
mkdir -p "$WORKING_DIR/xrsimulator"
cd ./packages/react-native/sdks/hermes || exit 1
DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM
cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/"
cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/"
cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/"
cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/"
cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/"
cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/"
DEST_DIR="/tmp/hermes/dSYM/$FLAVOR"
tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" .
mkdir -p "$DEST_DIR"
mv "hermes.framework.dSYM" "$DEST_DIR"
- name: Upload hermes dSYM artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: hermes-dSYM-${{ matrix.flavor }}
path: /tmp/hermes/dSYM/${{ matrix.flavor }}
- name: Upload hermes Runtime artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: hermes-darwin-bin-${{ matrix.flavor }}
path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ matrix.flavor }}.tar.gz
- name: Upload hermes osx artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: hermes-osx-bin-${{ matrix.flavor }}
path: /tmp/hermes/osx-bin/${{ matrix.flavor }}
- name: Upload Hermes Artifacts
uses: actions/cache/save@v4.0.0
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
with:
key: v2-hermes-artifacts-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
/tmp/hermes/osx-bin/${{ matrix.flavor }}
/tmp/hermes/dSYM/${{ matrix.flavor }}
/tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ matrix.flavor }}.tar.gz
build_hermesc_linux:
runs-on: ubuntu-latest
@@ -105,12 +369,41 @@ jobs:
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build HermesC Linux
uses: ./.github/actions/build-hermesc-linux
uses: actions/checkout@v4.1.1
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y git openssh-client cmake build-essential \
libreadline-dev libicu-dev jq zip python3
- name: Restore Hermes workspace
uses: ./.github/actions/restore-hermes-workspace
- name: Linux cache
uses: actions/cache@v4.0.0
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
key: v1-hermes-${{ github.job }}-linux-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
/tmp/hermes/linux64-bin/
/tmp/hermes/hermes/destroot/
- name: Set up workspace
run: |
mkdir -p /tmp/hermes/linux64-bin
- name: Build HermesC for Linux
run: |
if [ -f /tmp/hermes/linux64-bin/hermesc ]; then
echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.'
else
cd /tmp/hermes
cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive"
cmake --build build --target hermesc -j 4
cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/.
fi
- name: Upload linux artifacts
uses: actions/upload-artifact@v4.3.0
with:
name: hermes-linux-bin
path: /tmp/hermes/linux64-bin
build_hermesc_windows:
runs-on: windows-2019
@@ -124,12 +417,81 @@ jobs:
CMAKE_DIR: 'C:\Program Files\CMake\bin'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build HermesC Windows
uses: ./.github/actions/build-hermesc-windows
uses: actions/checkout@v4.1.1
- name: Download Previous Artifacts
uses: actions/download-artifact@v4
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
name: hermes-workspace
path: 'D:\tmp\hermes'
- name: Set up workspace
run: |
mkdir -p D:\tmp\hermes\osx-bin
mkdir -p .\packages\react-native\sdks\hermes
cp -r -Force D:\tmp\hermes\hermes\* .\packages\react-native\sdks\hermes\.
cp -r -Force .\packages\react-native\sdks\hermes-engine\utils\* .\packages\react-native\sdks\hermes\.
- name: Windows cache
uses: actions/cache@v4.0.0
with:
key: v2-hermes-${{ github.job }}-windows-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
path: |
D:\tmp\hermes\win64-bin\
D:\tmp\hermes\hermes\icu\
D:\tmp\hermes\hermes\deps\
D:\tmp\hermes\hermes\build_release\
- name: setup-msbuild
uses: microsoft/setup-msbuild@v1.3.2
- name: Set up workspace
run: |
#New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\icu
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\deps
New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\win64-bin
#New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\hermes
#New-Item -ItemType SymbolicLink -ErrorAction SilentlyContinue -Target tmp\hermes\hermes -Path $Env:HERMES_WS_DIR -Name hermes
- name: Build HermesC for Windows
run: |
if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) {
choco install --no-progress cmake --version 3.14.7
if (-not $?) { throw "Failed to install CMake" }
cd $Env:HERMES_WS_DIR\icu
# If Invoke-WebRequest shows a progress bar, it will fail with
# Win32 internal error "Access is denied" 0x5 occurred [...]
$progressPreference = 'silentlyContinue'
Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip"
Expand-Archive -Path "icu.zip" -DestinationPath "."
cd $Env:HERMES_WS_DIR
Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps"
# Include MSVC++ 2015 redistributables
Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps"
$Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR"
$Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu"
cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF
if (-not $?) { throw "Failed to configure Hermes" }
echo "Running windows build..."
cd build_release
cmake --build . --target hermesc --config Release
if (-not $?) { throw "Failed to build Hermes" }
echo "Copying hermesc.exe to win64-bin"
cd $Env:HERMES_WS_DIR
Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin"
# Include Windows runtime dependencies
Copy-Item -Path "deps\*" -Destination "win64-bin"
}
else {
Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild."
}
- name: Upload windows artifacts
uses: actions/upload-artifact@v4.3.0
with:
name: hermes-win64-bin
path: D:\tmp\hermes\win64-bin\
build_android:
runs-on: 8-core-ubuntu
@@ -139,76 +501,245 @@ jobs:
env:
TERM: "dumb"
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Android
uses: ./.github/actions/build-android
uses: actions/checkout@v4.1.1
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Install dependencies
run: yarn install --non-interactive
- name: Set React Native Version
run: |
git config --global --add safe.directory /__w/react-native/react-native
node ./scripts/releases/set-rn-version.js --build-type ${{ needs.set_release_type.outputs.RELEASE_TYPE }}
- name: Setup gradle
uses: ./.github/actions/setup-gradle
- name: Build and publish all the Android Artifacts to /tmp/maven-local
run: |
# By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs.
if [[ "${{ needs.set_release_type.outputs.RELEASE_TYPE }}" == "dry-run" ]]; then
export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a"
else
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
fi
./gradlew publishAllToMavenTempLocal build -PenableWarningsAsErrors=true
shell: bash
- name: Upload test results
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.0
with:
release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }}
name: build-android-results
compression-level: 1
path: |
packages/react-native-gradle-plugin/react-native-gradle-plugin/build/reports
packages/react-native-gradle-plugin/settings-plugin/build/reports
packages/react-native/ReactAndroid/build/reports
- name: Upload RNTester APK
if: ${{ always() }}
uses: actions/upload-artifact@v4.3.0
with:
name: rntester-apk
path: packages/rn-tester/android/app/build/outputs/apk/
compression-level: 0
build_npm_package:
runs-on: 8-core-ubuntu
needs:
[
set_release_type,
prepare_hermes_workspace,
build_hermes_macos,
build_hermesc_linux,
build_hermesc_windows,
build_android,
]
needs: [set_release_type, prepare_hermes_workspace, build_hermes_macos, build_hermesc_linux, build_hermesc_windows,build_android]
container:
image: reactnativecommunity/react-native-android:latest
env:
TERM: "dumb"
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
GRADLE_OPTS: '-Dorg.gradle.daemon=false'
# By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs.
ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a"
# Repeated here, as the environment key in this executor will overwrite the one in defaults
PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }}
PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }}
HERMES_WS_DIR: /tmp/hermes
env:
HERMES_WS_DIR: /tmp/hermes
GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }}
ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED }}
ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }}
REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.1.1
- name: Create /tmp/hermes/osx-bin directory
run: mkdir -p /tmp/hermes/osx-bin
- name: Download osx-bin release artifacts
uses: actions/download-artifact@v4.1.3
with:
fetch-depth: 0
fetch-tags: true
- name: Build and Publish NPM PAckage
uses: ./.github/actions/build-npm-package
name: hermes-osx-bin-Release
path: /tmp/hermes/osx-bin/Release
- name: Download osx-bin debug artifacts
uses: actions/download-artifact@v4.1.3
with:
hermes-ws-dir: ${{ env.HERMES_WS_DIR }}
release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }}
gha-npm-token: ${{ env.GHA_NPM_TOKEN }}
name: hermes-osx-bin-Debug
path: /tmp/hermes/osx-bin/Debug
- name: Download darwin-bin release artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-darwin-bin-Release
path: /tmp/hermes/hermes-runtime-darwin
- name: Download darwin-bin debug artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-darwin-bin-Debug
path: /tmp/hermes/hermes-runtime-darwin
- name: Download hermes dSYM debug artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-dSYM-Debug
path: /tmp/hermes/dSYM/Debug
- name: Download hermes dSYM release vartifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-dSYM-Release
path: /tmp/hermes/dSYM/Release
- name: Download windows-bin artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-win64-bin
path: /tmp/hermes/win64-bin
- name: Download linux-bin artifacts
uses: actions/download-artifact@v4.1.3
with:
name: hermes-linux-bin
path: /tmp/hermes/linux64-bin
- name: Cache setup
id: cache_setup
uses: ./.github/actions/cache_setup
with:
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
- name: Show /tmp/hermes directory
run: ls -lR /tmp/hermes
- name: Copy Hermes binaries
shell: bash
run: |
mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin
# When build_hermes_macos runs as a matrix, it outputs
if [[ -d $HERMES_WS_DIR/osx-bin/Release ]]; then
cp -r $HERMES_WS_DIR/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/.
elif [[ -d $HERMES_WS_DIR/osx-bin/Debug ]]; then
cp -r $HERMES_WS_DIR/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/.
else
ls $HERMES_WS_DIR/osx-bin || echo "hermesc macOS artifacts directory missing."
echo "Could not locate macOS hermesc binary."; exit 1;
fi
# Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them.
if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then
mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz"
fi
if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then
mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz"
fi
cp -r $HERMES_WS_DIR/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/.
cp -r $HERMES_WS_DIR/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/.
# Make sure the hermesc files are actually executable.
chmod -R +x packages/react-native/sdks/hermesc/*
mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz
cp $HERMES_WS_DIR/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz
cp $HERMES_WS_DIR/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Install dependencies
run: yarn install --non-interactive
- name: Build packages
run: yarn build
# Continue with publish steps
- name: Set npm credentials
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.GHA_NPM_TOKEN }}" > ~/.npmrc
- name: Publish NPM
run: |
git config --global --add safe.directory /__w/react-native/react-native
echo "GRADLE_OPTS = $GRADLE_OPTS"
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
node ./scripts/releases-ci/publish-npm.js -t release
- name: Zip Maven Artifacts from /tmp/maven-local
working-directory: /tmp
run: zip -r maven-local.zip maven-local
- name: Upload Maven Artifacts
uses: actions/upload-artifact@v4.3.1
with:
name: maven-local
path: /tmp/maven-local.zip
- name: Upload npm logs
uses: actions/upload-artifact@v4.3.1
with:
name: npm-logs
path: ~/.npm/_logs
- name: Build release package as a job artifact
if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run'
run: |
mkdir -p build
FILENAME=$(cd packages/react-native; npm pack | tail -1)
mv packages/react-native/$FILENAME build/
echo $FILENAME > build/react-native-package-version
- name: Upload release package
uses: actions/upload-artifact@v4.3.1
if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run'
with:
name: react-native-package
path: build
- name: Publish @react-native-community/template
id: publish-template-to-npm
uses: actions/github-script@v6
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
script: |
const {publishTemplate} = require('./.github/workflow-scripts/publishTemplate.js')
const version = "${{ github.ref_name }}"
const isDryRun = false
await publishTemplate(github, version, isDryRun);
if: needs.set_release_type.outputs.RELEASE_TYPE == 'release'
shell: bash
id: publish-to-npm
run: |
COMMIT_MSG=$(git log -n1 --pretty=%B);
if grep -q '#publish-packages-to-npm&latest' <<< "$COMMIT_MSG"; then
echo "TAG=latest" >> $GITHUB_OUTPUT
IS_LATEST=true
else
IS_LATEST=false
fi
# Go from v0.75.0-rc.4 -> 0.75-stable, which is the template's branching scheme
VERSION=$(grep -oE '\d+\.\d+' <<< "${{ github.ref_name }}" | { read version; echo "$version-stable"; })
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
curl -L -X POST https://api.github.com/repos/react-native-community/template/release.yaml/dispatches \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \
-d "{\"ref\":\"$VERSION\",\"inputs\":{\"version\":\"${{ github.ref_name }}\",\"is_latest_on_npm\":\"$IS_LATEST\"}}\n"
- name: Wait for template to be published
if: needs.set_release_type.outputs.RELEASE_TYPE == 'release'
timeout-minutes: 3
uses: actions/github-script@v6
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
script: |
const {verifyPublishedTemplate, isLatest} = require('./.github/workflow-scripts/publishTemplate.js')
const version = "${{ github.ref_name }}"
await verifyPublishedTemplate(version, isLatest());
shell: bash
env:
VERSION: ${{ steps.publish-to-npm.outputs.VERSION }}
TAG: ${{ steps.publish-to-npm.outputs.TAG }}
run: |
echo "Waiting until @react-native-community/template is published to npm"
while true; do
if curl -o /dev/null -s -f "https://registry.npmjs.org/@react-native-community/template/$VERSION"; then
echo "Confirm that @react-native-community/template@$VERSION is published on npm"
break
fi
sleep 10
done
while [ "$TAG" == "latest" ]; do
CURRENT=$(curl -s "https://registry.npmjs.org/react-native/latest" | jq -r '.version');
if [ "$CURRENT" == "$VERSION" ]; then
echo "Confirm that @react-native-community/template@latest == $VERSION on npm"
break
fi
sleep 10
done
- name: Update rn-diff-purge to generate upgrade-support diff
if: needs.set_release_type.outputs.RELEASE_TYPE == 'release'
run: |
curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \
-H "Accept: application/vnd.github.v3+json" \
+26
View File
@@ -0,0 +1,26 @@
name: Run E2E Tests
# This workflow is used to trigger E2E tests on a PR when a comment is made
# containing the text "#run-e2e-tests".
on:
issue_comment:
types: [created]
permissions:
contents: read
jobs:
rebase:
name: Trigger E2E Tests
permissions:
contents: write # for cirrus-actions/rebase to push code to rebase
pull-requests: read # for cirrus-actions/rebase to get info about PR
runs-on: ubuntu-latest
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '#run-e2e-tests')
steps:
- name: Checkout the latest code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo
- name: Push empty commit
run: |
git commit -m "#run-e2e-tests" --allow-empty
git push origin $(git branch --show-current)
+4 -4
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 180
stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
stale-pr-message: 'This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
@@ -30,7 +30,7 @@ jobs:
- uses: actions/stale@v9
with:
ascending: true
repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 180
stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
stale-pr-message: 'This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
@@ -47,7 +47,7 @@ jobs:
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
any-of-labels: 'Needs: Author Feedback'
days-before-stale: 24
stale-issue-message: "This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days."
@@ -66,7 +66,7 @@ jobs:
- uses: actions/stale@v9
with:
ascending: true
repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
any-of-labels: 'Needs: Author Feedback'
days-before-stale: 24
stale-issue-message: "This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days."
File diff suppressed because it is too large Load Diff
@@ -1,75 +0,0 @@
name: Test Libraries on Nightlies
on:
workflow_call:
jobs:
test-library-on-nightly-android:
name: "[Android] ${{ matrix.library }}"
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
library: [
"react-native-async-storage",
"react-native-blob-util",
"@react-native-clipboard/clipboard",
"@react-native-community/datetimepicker",
"react-native-gesture-handler",
"react-native-image-picker",
"react-native-linear-gradient",
"@react-native-masked-view/masked-view",
"react-native-maps",
"@react-native-community/netinfo",
"react-native-reanimated",
"react-native-svg",
"react-native-video",
"react-native-webview",
"react-native-mmkv",
"react-native-screens",
"react-native-pager-view",
"@react-native-community/slider"
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Test ${{ inputs.library-name }}
uses: ./.github/actions/test-library-on-nightly
with:
library-npm-package: ${{ matrix.library }}
platform: android
test-library-on-nightly-ios:
name: "[iOS] ${{ matrix.library }}"
runs-on: macos-13-large
continue-on-error: true
strategy:
matrix:
library: [
"react-native-async-storage",
"react-native-blob-util",
"@react-native-clipboard/clipboard",
"@react-native-community/datetimepicker",
"react-native-gesture-handler",
"react-native-image-picker",
"react-native-linear-gradient",
"@react-native-masked-view/masked-view",
"react-native-maps",
"@react-native-community/netinfo",
"react-native-reanimated",
"react-native-svg",
"react-native-video",
"react-native-webview",
"react-native-mmkv",
"react-native-screens",
"react-native-pager-view",
"@react-native-community/slider"
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Test ${{ inputs.library-name }}
uses: ./.github/actions/test-library-on-nightly
with:
library-npm-package: ${{ matrix.library }}
platform: ios
@@ -1,45 +0,0 @@
name: Trigger E2E Tests on Comment
# This workflow is used to automatically trigger E2E tests when a comment is made
# containing the text "/run-e2e-tests".
on:
issue_comment:
types: [created]
permissions:
contents: read
jobs:
trigger-e2e-tests:
name: Trigger E2E Tests
runs-on: ubuntu-latest
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/test-e2e')
steps:
# This is needed because of https://github.com/actions/runner-images/issues/6283
# TL;DR: brew is not in the PATH anymore.
- name: Setup Homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Install jq
run: brew install jq
- name: Run E2E Tests
run: |
# Github does not provide the branch of a PR when a comment on a PR is made
# So, given the issue number, which is the PR number, we can retrieve the branch with
# a quick API call
echo "Retrieving branch"
BRANCH=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/facebook/react-native/pulls/$PR_NUMBER | jq -r '.head.ref')
echo "Trigger Test All workflow for branch $BRANCH"
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/facebook/react-native/actions/workflows/test-all.yml/dispatches \
-d "{\"ref\": \"$BRANCH\", \"inputs\": {\"run-e2e-tests\": \"true\"}}"
env:
GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number }}
@@ -1,18 +0,0 @@
name: Update node modules cache
on:
workflow_dispatch:
push:
branches:
- main
jobs:
update_node_modules_cache:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install yarn dependencies and update cache
uses: ./.github/actions/yarn-install-with-cache
with:
update-cache: "true"
+11 -4
View File
@@ -39,6 +39,8 @@ project.xcworkspace
/packages/react-native/ReactAndroid/external-artifacts/artifacts/
/packages/react-native/ReactAndroid/hermes-engine/build/
/packages/react-native/ReactAndroid/hermes-engine/.cxx/
/packages/react-native/template/android/app/build/
/packages/react-native/template/android/build/
/packages/helloworld/android/app/build/
/packages/helloworld/android/build/
/packages/react-native-popup-menu-android/android/build/
@@ -106,12 +108,16 @@ package-lock.json
# Ruby Gems (Bundler)
/packages/react-native/vendor
/packages/react-native/template/vendor
/packages/helloworld/vendor
.ruby-version
/**/.ruby-version
vendor/
# iOS / CocoaPods
/packages/react-native/template/ios/build/
/packages/react-native/template/ios/Pods/
/packages/react-native/template/ios/Podfile.lock
/packages/helloworld/ios/build/
/packages/helloworld/ios/Pods/
/packages/helloworld/ios/Podfile.lock
@@ -124,7 +130,7 @@ vendor/
!/packages/rn-tester/Pods/__offline_mirrors_jsc__
# @react-native/codegen
/packages/react-native/React/FBReactNativeSpec/
/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec
/packages/react-native-codegen/lib
/packages/react-native-codegen/tmp/
/packages/react-native/ReactCommon/react/renderer/components/rncore/
@@ -153,8 +159,9 @@ vendor/
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
# E2E files
/packages/rn-tester-e2e/apps/*.apk
/packages/rn-tester-e2e/apps/*.app
# CircleCI
.circleci/generated_config.yml
# Jest Integration
/jest/integration/build/
-1305
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -3,6 +3,5 @@ source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"
gem 'cocoapods', '~> 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'cocoapods', '~> 1.13'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
gem 'xcodeproj', '< 1.26.0'
+1 -1
View File
@@ -90,7 +90,7 @@ PLATFORMS
DEPENDENCIES
activesupport (>= 6.1.7.5, < 7.1.0)
cocoapods (~> 1.13, != 1.15.1, != 1.15.0)
cocoapods (~> 1.13)
RUBY VERSION
ruby 3.2.0p0
+1 -1
View File
@@ -87,7 +87,7 @@ The full documentation for React Native can be found on our [website][docs].
The React Native documentation discusses components, APIs, and topics that are specific to React Native. For further documentation on the React API that is shared between React Native and React DOM, refer to the [React documentation][r-docs].
The source for the React Native documentation and website is hosted on a separate repository, [**@facebook/react-native-website**][repo-website].
The source for the React Native documentation and website is hosted on a separate repo, [**@facebook/react-native-website**][repo-website].
[docs]: https://reactnative.dev/docs/getting-started
[r-docs]: https://react.dev/learn
+5 -4
View File
@@ -60,7 +60,7 @@ nexusPublishing {
tasks.register("clean", Delete::class.java) {
description = "Remove all the build files and intermediate build outputs"
dependsOn(gradle.includedBuild("gradle-plugin").task(":clean"))
dependsOn(gradle.includedBuild("react-native-gradle-plugin").task(":clean"))
subprojects.forEach {
if (it.project.plugins.hasPlugin("com.android.library") ||
it.project.plugins.hasPlugin("com.android.application")) {
@@ -86,7 +86,7 @@ tasks.register("clean", Delete::class.java) {
tasks.register("build") {
description = "Build and test all the React Native relevant projects."
dependsOn(gradle.includedBuild("gradle-plugin").task(":build"))
dependsOn(gradle.includedBuild("react-native-gradle-plugin").task(":build"))
}
tasks.register("publishAllToMavenTempLocal") {
@@ -97,9 +97,10 @@ tasks.register("publishAllToMavenTempLocal") {
":packages:react-native:ReactAndroid:hermes-engine:publishAllPublicationsToMavenTempLocalRepository")
}
tasks.register("publishAndroidToSonatype") {
description = "Publish the Android artifacts to Sonatype (Maven Central or Snapshot repository)"
tasks.register("publishAllToSonatype") {
description = "Publish all the artifacts to Sonatype (Maven Central or Snapshot repository)"
dependsOn(":packages:react-native:ReactAndroid:publishToSonatype")
dependsOn(":packages:react-native:ReactAndroid:external-artifacts:publishToSonatype")
dependsOn(":packages:react-native:ReactAndroid:hermes-engine:publishToSonatype")
}
-9
View File
@@ -900,9 +900,7 @@ declare module '@babel/traverse' {
isImportAttribute(opts?: Opts): boolean;
isImportDeclaration(opts?: Opts): boolean;
isImportDefaultSpecifier(opts?: Opts): boolean;
isImportExpression(opts?: Opts): boolean;
isImportNamespaceSpecifier(opts?: Opts): boolean;
isImportOrExportDeclaration(opts?: Opts): boolean;
isImportSpecifier(opts?: Opts): boolean;
isIndexedAccessType(opts?: Opts): boolean;
isInferredPredicate(opts?: Opts): boolean;
@@ -1217,9 +1215,7 @@ declare module '@babel/traverse' {
assertImportAttribute(opts?: Opts): void;
assertImportDeclaration(opts?: Opts): void;
assertImportDefaultSpecifier(opts?: Opts): void;
assertImportExpression(opts?: Opts): void;
assertImportNamespaceSpecifier(opts?: Opts): void;
assertImportOrExportDeclaration(opts?: Opts): void;
assertImportSpecifier(opts?: Opts): void;
assertIndexedAccessType(opts?: Opts): void;
assertInferredPredicate(opts?: Opts): void;
@@ -1575,15 +1571,10 @@ declare module '@babel/traverse' {
ImportAttribute?: VisitNode<BabelNodeImportAttribute, TState>,
ImportDeclaration?: VisitNode<BabelNodeImportDeclaration, TState>,
ImportDefaultSpecifier?: VisitNode<BabelNodeImportDefaultSpecifier, TState>,
ImportExpression?: VisitNode<BabelNodeImportExpression, TState>,
ImportNamespaceSpecifier?: VisitNode<
BabelNodeImportNamespaceSpecifier,
TState,
>,
ImportOrExportDeclaration?: VisitNode<
BabelNodeImportOrExportDeclaration,
TState,
>,
ImportSpecifier?: VisitNode<BabelNodeImportSpecifier, TState>,
IndexedAccessType?: VisitNode<BabelNodeIndexedAccessType, TState>,
InferredPredicate?: VisitNode<BabelNodeInferredPredicate, TState>,
+37 -58
View File
File diff suppressed because one or more lines are too long
-40
View File
@@ -1,40 +0,0 @@
/**
* (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary.
*
* @flow strict
* @format
* @oncall react_native
*/
declare module 'jest-diff' {
import type {CompareKeys} from 'pretty-format';
declare export type DiffOptionsColor = (arg: string) => string; // subset of Chalk type
declare export type DiffOptions = {
aAnnotation?: string,
aColor?: DiffOptionsColor,
aIndicator?: string,
bAnnotation?: string,
bColor?: DiffOptionsColor,
bIndicator?: string,
changeColor?: DiffOptionsColor,
changeLineTrailingSpaceColor?: DiffOptionsColor,
commonColor?: DiffOptionsColor,
commonIndicator?: string,
commonLineTrailingSpaceColor?: DiffOptionsColor,
contextLines?: number,
emptyFirstOrLastLinePlaceholder?: string,
expand?: boolean,
includeChangeCounts?: boolean,
omitAnnotationLines?: boolean,
patchColor?: DiffOptionsColor,
compareKeys?: CompareKeys,
};
declare export function diff(
a: mixed,
b: mixed,
options?: DiffOptions,
): string | null;
}
+18
View File
@@ -0,0 +1,18 @@
// flow-typed signature: b1b274e8ae71623bf11c20224c446842
// flow-typed version: c6154227d1/mkdirp_v0.5.x/flow_>=v0.104.x
declare module 'mkdirp' {
declare type Options = number | {
mode?: number,
fs?: mixed,
...
};
declare type Callback = (err: ?Error, path: ?string) => void;
declare module.exports: {
(path: string, options?: Options | Callback, callback?: Callback): void,
sync(path: string, options?: Options): void,
...
};
}
+39
View File
@@ -0,0 +1,39 @@
/**
* 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.
*
* @flow strict
* @format
* @oncall react_native
*/
declare module '@pkgjs/parseargs' {
declare export function parseArgs<
TOptions: {[string]: util$ParseArgsOption} = {},
>(config: {
args?: Array<string>,
options?: TOptions,
strict?: boolean,
allowPositionals?: boolean,
tokens?: false,
}): {
values: util$ParseArgsOptionsToValues<TOptions>,
positionals: Array<string>,
};
declare export function parseArgs<
TOptions: {[string]: util$ParseArgsOption} = {},
>(config: {
args?: Array<string>,
options?: TOptions,
strict?: boolean,
allowPositionals?: boolean,
tokens: true,
}): {
values: util$ParseArgsOptionsToValues<TOptions>,
positionals: Array<string>,
tokens: Array<util$ParseArgsToken>,
};
}
+49
View File
@@ -0,0 +1,49 @@
/**
* @flow strict
* @format
*/
type PrettyFormatPlugin =
| {
test: (value: mixed) => boolean,
print: (value: mixed) => string,
}
| {
test: (value: mixed) => boolean,
serialize: (value: mixed) => string,
};
declare module 'pretty-format' {
declare module.exports: {
(
value: mixed,
options?: ?{
callToJSON?: ?boolean,
escapeRegex?: ?boolean,
escapeString?: ?boolean,
highlight?: ?boolean,
indent?: ?number,
maxDepth?: ?number,
min?: ?boolean,
plugins?: ?Array<PrettyFormatPlugin>,
printFunctionName?: ?boolean,
theme?: ?{
comment?: ?string,
prop?: ?string,
tag?: ?string,
value: ?string,
},
},
): string,
plugins: {
AsymmetricMatcher: PrettyFormatPlugin,
ConvertAnsi: PrettyFormatPlugin,
DOMCollection: PrettyFormatPlugin,
DOMElement: PrettyFormatPlugin,
Immutable: PrettyFormatPlugin,
ReactElement: PrettyFormatPlugin,
ReactTestComponent: PrettyFormatPlugin,
},
};
}
-76
View File
@@ -1,76 +0,0 @@
/**
* (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary.
*
* @flow strict
* @format
* @oncall react_native
*/
declare type Print = (value: mixed) => string;
declare type Indent = (value: string) => string;
declare type PluginOptions = {
edgeSpacing: string,
min: boolean,
spacing: string,
};
declare type Colors = {
comment: {close: string, open: string},
content: {close: string, open: string},
prop: {close: string, open: string},
tag: {close: string, open: string},
value: {close: string, open: string},
};
declare type PrettyFormatPlugin =
| {
print: (
value: mixed,
print?: ?Print,
indent?: ?Indent,
options?: ?PluginOptions,
colors?: ?Colors,
) => string,
test: (value: mixed) => boolean,
}
| {
serialize: (value: mixed) => string,
test: (value: mixed) => boolean,
};
declare module 'pretty-format' {
declare export type CompareKeys =
| ((a: string, b: string) => number)
| null
| void;
declare export function format(
value: mixed,
options?: ?{
callToJSON?: ?boolean,
compareKeys?: CompareKeys,
escapeRegex?: ?boolean,
escapeString?: ?boolean,
highlight?: ?boolean,
indent?: ?number,
maxDepth?: ?number,
maxWidth?: ?number,
min?: ?boolean,
plugins?: ?Array<PrettyFormatPlugin>,
printBasicPrototype?: ?boolean,
printFunctionName?: ?boolean,
theme?: ?{
comment?: ?string,
content?: ?string,
prop?: ?string,
tag?: ?string,
value: ?string,
},
},
): string;
declare export const plugins: {
AsymmetricMatcher: PrettyFormatPlugin,
DOMCollection: PrettyFormatPlugin,
DOMElement: PrettyFormatPlugin,
Immutable: PrettyFormatPlugin,
ReactElement: PrettyFormatPlugin,
ReactTestComponent: PrettyFormatPlugin,
};
}
+10 -7
View File
@@ -1,3 +1,6 @@
// flow-typed signature: 7bac6c05f7415881918d3d510109e739
// flow-typed version: fce74493f0/react-test-renderer_v16.x.x/flow_>=v0.104.x
// Type definitions for react-test-renderer 16.x.x
// Ported from: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-test-renderer
@@ -41,14 +44,14 @@ type ReactTestInstance = {
...
};
type TestRendererOptions = { createNodeMock(element: React.MixedElement): any, ... };
type TestRendererOptions = { createNodeMock(element: React$Element<any>): any, ... };
declare module "react-test-renderer" {
declare export type ReactTestRenderer = {
toJSON(): null | ReactTestRendererJSON,
toTree(): null | ReactTestRendererTree,
unmount(nextElement?: React.MixedElement): void,
update(nextElement: React.MixedElement): void,
unmount(nextElement?: React$Element<any>): void,
update(nextElement: React$Element<any>): void,
getInstance(): ?ReactComponentInstance,
root: ReactTestInstance,
...
@@ -57,7 +60,7 @@ declare module "react-test-renderer" {
declare type Thenable = { then(resolve: () => mixed, reject?: () => mixed): mixed, ... };
declare function create(
nextElement: React.MixedElement,
nextElement: React$Element<any>,
options?: TestRendererOptions
): ReactTestRenderer;
@@ -68,9 +71,9 @@ declare module "react-test-renderer/shallow" {
declare export default class ShallowRenderer {
static createRenderer(): ShallowRenderer;
getMountedInstance(): ReactTestInstance;
getRenderOutput<E: React.MixedElement>(): E;
getRenderOutput(): React.MixedElement;
render(element: React.MixedElement, context?: any): void;
getRenderOutput<E: React$Element<any>>(): E;
getRenderOutput(): React$Element<any>;
render(element: React$Element<any>, context?: any): void;
unmount(): void;
}
}
-229
View File
@@ -1,229 +0,0 @@
declare module 'semver' {
declare type Release =
| "major"
| "premajor"
| "minor"
| "preminor"
| "patch"
| "prepatch"
| "prerelease";
// The supported comparators are taken from the source here:
// https://github.com/npm/node-semver/blob/8bd070b550db2646362c9883c8d008d32f66a234/semver.js#L623
declare type Operator =
| "==="
| "!=="
| "=="
| "="
| "" // Not sure why you would want this, but whatever.
| "!="
| ">"
| ">="
| "<"
| "<=";
declare class SemVer {
build: Array<string>;
loose: ?boolean;
major: number;
minor: number;
patch: number;
prerelease: Array<string | number>;
raw: string;
version: string;
constructor(version: string | SemVer, options?: Options): SemVer;
compare(other: string | SemVer): -1 | 0 | 1;
compareMain(other: string | SemVer): -1 | 0 | 1;
comparePre(other: string | SemVer): -1 | 0 | 1;
compareBuild(other: string | SemVer): -1 | 0 | 1;
format(): string;
inc(release: Release, identifier: string): this;
}
declare class Comparator {
options?: Options;
operator: Operator;
semver: SemVer;
value: string;
constructor(comp: string | Comparator, options?: Options): Comparator;
parse(comp: string): void;
test(version: string): boolean;
}
declare class Range {
loose: ?boolean;
raw: string;
set: Array<Array<Comparator>>;
constructor(range: string | Range, options?: Options): Range;
format(): string;
parseRange(range: string): Array<Comparator>;
test(version: string): boolean;
toString(): string;
}
declare var SEMVER_SPEC_VERSION: string;
declare var re: Array<RegExp>;
declare var src: Array<string>;
declare type Options = {
options?: Options,
includePrerelease?: boolean,
...
} | boolean;
// Functions
declare function valid(v: string | SemVer, options?: Options): string | null;
declare function clean(v: string | SemVer, options?: Options): string | null;
declare function inc(
v: string | SemVer,
release: Release,
options?: Options,
identifier?: string
): string | null;
declare function inc(
v: string | SemVer,
release: Release,
identifier: string
): string | null;
declare function major(v: string | SemVer, options?: Options): number;
declare function minor(v: string | SemVer, options?: Options): number;
declare function patch(v: string | SemVer, options?: Options): number;
declare function intersects(r1: string | SemVer, r2: string | SemVer, loose?: boolean): boolean;
declare function minVersion(r: string | Range): Range | null;
// Comparison
declare function gt(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): boolean;
declare function gte(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): boolean;
declare function lt(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): boolean;
declare function lte(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): boolean;
declare function eq(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): boolean;
declare function neq(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): boolean;
declare function cmp(
v1: string | SemVer,
comparator: Operator,
v2: string | SemVer,
options?: Options
): boolean;
declare function compare(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): -1 | 0 | 1;
declare function rcompare(
v1: string | SemVer,
v2: string | SemVer,
options?: Options
): -1 | 0 | 1;
declare function diff(v1: string | SemVer, v2: string | SemVer): ?Release;
declare function intersects(comparator: Comparator): boolean;
declare function sort(
list: Array<string | SemVer>,
options?: Options
): Array<string | SemVer>;
declare function rsort(
list: Array<string | SemVer>,
options?: Options
): Array<string | SemVer>;
declare function compareIdentifiers(
v1: string | SemVer,
v2: string | SemVer
): -1 | 0 | 1;
declare function rcompareIdentifiers(
v1: string | SemVer,
v2: string | SemVer
): -1 | 0 | 1;
// Ranges
declare function validRange(
range: string | Range,
options?: Options
): string | null;
declare function satisfies(
version: string | SemVer,
range: string | Range,
options?: Options
): boolean;
declare function maxSatisfying(
versions: Array<string | SemVer>,
range: string | Range,
options?: Options
): string | SemVer | null;
declare function minSatisfying(
versions: Array<string | SemVer>,
range: string | Range,
options?: Options
): string | SemVer | null;
declare function gtr(
version: string | SemVer,
range: string | Range,
options?: Options
): boolean;
declare function ltr(
version: string | SemVer,
range: string | Range,
options?: Options
): boolean;
declare function outside(
version: string | SemVer,
range: string | Range,
hilo: ">" | "<",
options?: Options
): boolean;
declare function intersects(
range: Range
): boolean;
declare function simplifyRange(
ranges: Array<string>,
range: string | Range,
options?: Options,
): string | Range;
declare function subset(
sub: string | Range,
dom: string | Range,
options?: Options,
): boolean;
// Coercion
declare function coerce(
version: string | SemVer,
options?: Options
): ?SemVer
// Not explicitly documented, or deprecated
declare function parse(version: string, options?: Options): ?SemVer;
declare function toComparators(
range: string | Range,
options?: Options
): Array<Array<string>>;
}
declare module 'semver/preload' {
declare module.exports: $Exports<"semver">;
}
-20
View File
@@ -16,13 +16,6 @@ declare interface undici$Agent$Options {
}
declare module 'undici' {
declare export type RequestOptions = $ReadOnly<{
dispatcher?: Dispatcher,
method?: string,
headers?: HeadersInit,
...
}>;
declare export class Dispatcher extends events$EventEmitter {
constructor(): void;
}
@@ -30,17 +23,4 @@ declare module 'undici' {
declare export class Agent extends Dispatcher {
constructor(opts?: undici$Agent$Options): void;
}
declare export function request(
url: string | URL,
options: RequestOptions,
): Promise<{
statusCode: number,
headers: Headers,
body: {
read(): Promise<Buffer>,
...
},
...
}>;
}
-1
View File
@@ -323,7 +323,6 @@ declare module "yargs" {
updateStrings(obj: { [key: string]: string, ... }): this;
usage(message: string, opts?: { [key: string]: Options, ... }): this;
usage(message: string, desc?: string, builder: CommonModuleObject["builder"], handler: CommonModuleObject["handler"]): this;
version(): this;
version(version: string | false): this;
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+1 -4
View File
@@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -86,8 +84,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Vendored
-7
View File
@@ -1,8 +1,3 @@
@REM Copyright (c) Meta Platforms, Inc. and affiliates.
@REM
@REM This source code is licensed under the MIT license found in the
@REM LICENSE file in the root directory of this source tree.
@rem
@rem Copyright 2015 the original author or authors.
@rem
@@ -18,8 +13,6 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
+3 -12
View File
@@ -11,11 +11,6 @@
const {defaults} = require('jest-config');
const PODS_LOCATIONS = [
'packages/rn-tester/Pods',
'packages/helloworld/ios/Pods',
];
module.exports = {
transform: {
'^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp)$':
@@ -35,11 +30,11 @@ module.exports = {
testRegex: '/__tests__/.*-test(\\.fb)?\\.js$',
testPathIgnorePatterns: [
'/node_modules/',
'<rootDir>/packages/react-native/template',
'<rootDir>/packages/react-native/sdks',
'<rootDir>/packages/react-native/Libraries/Renderer',
'<rootDir>/packages/rn-tester/e2e',
'<rootDir>/packages/react-native-test-renderer/src',
'<rootDir>/packages/react-native/sdks/hermes/',
...PODS_LOCATIONS,
],
transformIgnorePatterns: ['node_modules/(?!@react-native/)'],
haste: {
@@ -47,11 +42,7 @@ module.exports = {
platforms: ['ios', 'android'],
},
moduleFileExtensions: ['fb.js'].concat(defaults.moduleFileExtensions),
modulePathIgnorePatterns: [
'scripts/.*/__fixtures__/',
'<rootDir>/packages/react-native/sdks/hermes/',
...PODS_LOCATIONS,
],
modulePathIgnorePatterns: ['scripts/.*/__fixtures__/'],
unmockedModulePathPatterns: [
'node_modules/react/',
'packages/react-native/Libraries/Renderer',
-30
View File
@@ -1,30 +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 crypto = require('crypto');
const fs = require('fs');
module.exports = {
getHasteName(filePath) {
if (filePath.endsWith('ReactNativeInternalFeatureFlags.js')) {
return 'ReactNativeInternalFeatureFlags';
}
return null;
},
getCacheKey() {
return crypto
.createHash('sha1')
.update(fs.readFileSync(__filename))
.digest('hex');
},
};
-29
View File
@@ -1,29 +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 baseConfig = require('../../../jest.config');
const path = require('path');
module.exports = {
rootDir: path.resolve(__dirname, '../../..'),
roots: [
'<rootDir>/packages/react-native',
'<rootDir>/jest/integration/runtime',
],
moduleFileExtensions: [...baseConfig.moduleFileExtensions, 'cpp', 'h'],
// This allows running Meta-internal tests with the `-test.fb.js` suffix.
testRegex: '/__tests__/.*-itest(\\.fb)?\\.js$',
testPathIgnorePatterns: baseConfig.testPathIgnorePatterns,
transformIgnorePatterns: ['.*'],
testRunner: './jest/integration/runner/index.js',
watchPathIgnorePatterns: ['<rootDir>/jest/integration/build/'],
globalSetup: './jest/integration/runner/warmup/index.js',
};
-53
View File
@@ -1,53 +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 {getDefaultConfig} = require('@react-native/metro-config');
const {mergeConfig} = require('metro-config');
const path = require('path');
const rnTesterConfig = getDefaultConfig(
path.resolve('../../../packages/rn-tester'),
);
const JS_DIR = process.env.JS_DIR
? path.resolve(process.cwd(), process.env.JS_DIR)
: null;
const config = {
projectRoot: path.resolve(__dirname, '../../..'),
reporter: {
update: () => {},
},
resolver: {
blockList: /\/RendererProxy\.fb\.js$/, // Disable dependency injection for the renderer
disableHierarchicalLookup: !!JS_DIR,
sourceExts: ['fb.js', ...rnTesterConfig.resolver.sourceExts],
nodeModulesPaths: JS_DIR
? [path.join(JS_DIR, 'public', 'node_modules')]
: [],
hasteImplModulePath: path.resolve(__dirname, 'hasteImpl.js'),
},
transformer: {
// We need to wrap the default transformer so we can run it from source
// using babel-register.
babelTransformerPath: path.resolve(__dirname, 'metro-babel-transformer.js'),
},
watchFolders: JS_DIR
? [
path.join(JS_DIR, 'RKJSModules', 'vendor', 'react'),
path.join(JS_DIR, 'tools', 'metro'),
path.join(JS_DIR, 'node_modules'),
path.join(JS_DIR, 'public', 'node_modules'),
]
: [],
};
module.exports = mergeConfig(rnTesterConfig, config);
@@ -1,35 +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.
*
* @flow strict-local
* @format
* @oncall react_native
*/
module.exports = function entrypointTemplate({
testPath,
setupModulePath,
}: {
testPath: string,
setupModulePath: string,
}): string {
return `/**
* 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.
*
* ${'@'}generated
* @noformat
* @noflow
* @oncall react_native
*/
import {registerTest} from '${setupModulePath}';
registerTest(() => require('${testPath}'));
`;
};
-229
View File
@@ -1,229 +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.
*
* @flow strict-local
* @format
* @oncall react_native
*/
import type {TestSuiteResult} from '../runtime/setup';
import entrypointTemplate from './entrypoint-template';
import {
getBuckModeForPlatform,
getDebugInfoFromCommandResult,
getFantomTestConfig,
getShortHash,
runBuck2,
symbolicateStackTrace,
} from './utils';
import fs from 'fs';
// $FlowExpectedError[untyped-import]
import {formatResultsErrors} from 'jest-message-util';
import Metro from 'metro';
import nullthrows from 'nullthrows';
import path from 'path';
const BUILD_OUTPUT_PATH = path.resolve(__dirname, '..', 'build');
const PRINT_FANTOM_OUTPUT: false = false;
function parseRNTesterCommandResult(result: ReturnType<typeof runBuck2>): {
logs: string,
testResult: TestSuiteResult,
} {
const stdout = result.stdout.toString();
const outputArray = stdout
.trim()
.split('\n')
.filter(log => !log.startsWith('Running "')); // remove AppRegistry logs.
// The last line should be the test output in JSON format
const testResultJSON = outputArray.pop();
let testResult;
try {
testResult = JSON.parse(nullthrows(testResultJSON));
} catch (error) {
throw new Error(
'Failed to parse test results from RN tester binary result.\n' +
getDebugInfoFromCommandResult(result),
);
}
return {logs: outputArray.join('\n'), testResult};
}
function generateBytecodeBundle({
sourcePath,
bytecodePath,
isOptimizedMode,
}: {
sourcePath: string,
bytecodePath: string,
isOptimizedMode: boolean,
}): void {
const hermesCompilerCommandResult = runBuck2([
'run',
getBuckModeForPlatform(isOptimizedMode),
'//xplat/hermes/tools/hermesc:hermesc',
'--',
'-emit-binary',
'-O',
'-max-diagnostic-width',
'80',
'-out',
bytecodePath,
sourcePath,
]);
if (hermesCompilerCommandResult.status !== 0) {
throw new Error(getDebugInfoFromCommandResult(hermesCompilerCommandResult));
}
}
module.exports = async function runTest(
globalConfig: {...},
config: {...},
environment: {...},
runtime: {...},
testPath: string,
): mixed {
const startTime = Date.now();
const testConfig = getFantomTestConfig(testPath);
const isOptimizedMode = testConfig.mode === 'opt';
const metroConfig = await Metro.loadConfig({
config: path.resolve(__dirname, '..', 'config', 'metro.config.js'),
});
const setupModulePath = path.resolve(__dirname, '../runtime/setup.js');
const entrypointContents = entrypointTemplate({
testPath: `${path.relative(BUILD_OUTPUT_PATH, testPath)}`,
setupModulePath: `${path.relative(BUILD_OUTPUT_PATH, setupModulePath)}`,
});
const entrypointPath = path.join(
BUILD_OUTPUT_PATH,
`${getShortHash(entrypointContents)}-${path.basename(testPath)}`,
);
const testBundlePath = entrypointPath + '.bundle';
const testJSBundlePath = testBundlePath + '.js';
const testBytecodeBundlePath = testJSBundlePath + '.hbc';
fs.mkdirSync(path.dirname(entrypointPath), {recursive: true});
fs.writeFileSync(entrypointPath, entrypointContents, 'utf8');
const sourceMapPath = path.join(
path.dirname(testJSBundlePath),
path.basename(testJSBundlePath, '.js') + '.map',
);
await Metro.runBuild(metroConfig, {
entry: entrypointPath,
out: testJSBundlePath,
platform: 'android',
minify: isOptimizedMode,
dev: !isOptimizedMode,
sourceMap: true,
sourceMapUrl: sourceMapPath,
});
if (isOptimizedMode) {
generateBytecodeBundle({
sourcePath: testJSBundlePath,
bytecodePath: testBytecodeBundlePath,
isOptimizedMode,
});
}
const rnTesterCommandResult = runBuck2([
'run',
getBuckModeForPlatform(isOptimizedMode),
'//xplat/ReactNative/react-native-cxx/samples/tester:tester',
'--',
'--bundlePath',
testBundlePath,
]);
if (rnTesterCommandResult.status !== 0) {
throw new Error(getDebugInfoFromCommandResult(rnTesterCommandResult));
}
if (PRINT_FANTOM_OUTPUT) {
console.log(getDebugInfoFromCommandResult(rnTesterCommandResult));
}
const rnTesterParsedOutput = parseRNTesterCommandResult(
rnTesterCommandResult,
);
const testResultError = rnTesterParsedOutput.testResult.error;
if (testResultError) {
const error = new Error(testResultError.message);
error.stack = symbolicateStackTrace(sourceMapPath, testResultError.stack);
throw error;
}
const endTime = Date.now();
if (process.env.SANDCASTLE == null) {
console.log(rnTesterParsedOutput.logs);
}
const testResults =
nullthrows(rnTesterParsedOutput.testResult.testResults).map(testResult => ({
ancestorTitles: [] as Array<string>,
failureDetails: [] as Array<string>,
testFilePath: testPath,
...testResult,
failureMessages: testResult.failureMessages.map(maybeStackTrace =>
symbolicateStackTrace(sourceMapPath, maybeStackTrace),
),
})) ?? [];
return {
testFilePath: testPath,
failureMessage: formatResultsErrors(
testResults,
config,
globalConfig,
testPath,
),
leaks: false,
openHandles: [],
perfStats: {
start: startTime,
end: endTime,
duration: endTime - startTime,
runtime: endTime - startTime,
slow: false,
},
snapshot: {
added: 0,
fileDeleted: false,
matched: 0,
unchecked: 0,
uncheckedKeys: [],
unmatched: 0,
updated: 0,
},
numTotalTests: testResults.length,
numPassingTests: testResults.filter(test => test.status === 'passed')
.length,
numFailingTests: testResults.filter(test => test.status === 'failed')
.length,
numPendingTests: testResults.filter(test => test.status === 'pending')
.length,
numTodoTests: 0,
skipped: false,
testResults,
};
};
-158
View File
@@ -1,158 +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.
*
* @flow strict-local
* @format
* @oncall react_native
*/
import {spawnSync} from 'child_process';
import crypto from 'crypto';
import fs from 'fs';
// $FlowExpectedError[untyped-import]
import {extract, parse} from 'jest-docblock';
import os from 'os';
// $FlowExpectedError[untyped-import]
import {SourceMapConsumer} from 'source-map';
type DocblockPragmas = {[key: string]: string | string[]};
type FantomTestMode = 'dev' | 'opt';
type FantomTestConfig = {
mode: FantomTestMode,
};
const DEFAULT_MODE: FantomTestMode = 'dev';
/**
* Extracts the Fantom configuration from the test file, specified as part of
* the docblock comment. E.g.:
*
* ```
* /**
* * @flow strict-local
* * @fantom mode:opt
* *
* ```
*
* So far the only supported option is `mode`, which can be 'dev' or 'opt'.
*/
export function getFantomTestConfig(testPath: string): FantomTestConfig {
const docblock = extract(fs.readFileSync(testPath, 'utf8'));
const pragmas = parse(docblock) as DocblockPragmas;
const config = {
mode: DEFAULT_MODE,
};
const maybeMode = pragmas.fantom_mode;
if (maybeMode != null) {
if (Array.isArray(maybeMode)) {
throw new Error('Expected a single value for @fantom_mode');
}
const mode = maybeMode;
if (mode === 'dev' || mode === 'opt') {
config.mode = mode;
} else {
throw new Error(`Invalid Fantom mode: ${mode}`);
}
}
return config;
}
export function getBuckModeForPlatform(enableRelease: boolean = false): string {
const mode = enableRelease ? 'opt' : 'dev';
switch (os.platform()) {
case 'linux':
return `@//arvr/mode/linux/${mode}`;
case 'darwin':
return os.arch() === 'arm64'
? `@//arvr/mode/mac-arm/${mode}`
: `@//arvr/mode/mac/${mode}`;
case 'win32':
return `@//arvr/mode/win/${mode}`;
default:
throw new Error(`Unsupported platform: ${os.platform()}`);
}
}
type SpawnResultWithOriginalCommand = {
...ReturnType<typeof spawnSync>,
originalCommand: string,
...
};
export function runBuck2(args: Array<string>): SpawnResultWithOriginalCommand {
const result = spawnSync('buck2', args, {
encoding: 'utf8',
env: {
...process.env,
PATH: `/usr/local/bin:${process.env.PATH ?? ''}`,
},
});
return {
...result,
originalCommand: `buck2 ${args.join(' ')}`,
};
}
export function getDebugInfoFromCommandResult(
commandResult: SpawnResultWithOriginalCommand,
): string {
const logLines = [
`Command ${commandResult.status === 0 ? 'succeeded' : 'failed'}: ${commandResult.originalCommand}`,
'',
'stdout:',
commandResult.stdout,
'',
'stderr:',
commandResult.stderr,
];
if (commandResult.error) {
logLines.push('', 'error:', String(commandResult.error));
}
return logLines.join('\n');
}
export function getShortHash(contents: string): string {
return crypto.createHash('md5').update(contents).digest('hex').slice(0, 8);
}
export function symbolicateStackTrace(
sourceMapPath: string,
stackTrace: string,
): string {
const sourceMapData = JSON.parse(fs.readFileSync(sourceMapPath, 'utf8'));
const consumer = new SourceMapConsumer(sourceMapData);
return stackTrace
.split('\n')
.map(line => {
const match = line.match(/at (.*) \((.*):(\d+):(\d+)\)/);
if (match) {
const functionName = match[1];
// const fileName = match[2];
const lineNumber = parseInt(match[3], 10);
const columnNumber = parseInt(match[4], 10);
// Get the original position
const originalPosition = consumer.originalPositionFor({
line: lineNumber,
column: columnNumber,
});
return `at ${originalPosition.name ?? functionName} (${originalPosition.source}:${originalPosition.line}:${originalPosition.column})`;
} else {
return line;
}
})
.join('\n');
}
-13
View File
@@ -1,13 +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
* @oncall react_native
*/
require('../../../../scripts/build/babel-register').registerForMonorepo();
module.exports = require('./warmup');
-97
View File
@@ -1,97 +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.
*
* @flow strict-local
* @format
* @oncall react_native
*/
import {
getBuckModeForPlatform,
getDebugInfoFromCommandResult,
runBuck2,
} from '../utils';
// $FlowExpectedError[untyped-import]
import fs from 'fs';
import Metro from 'metro';
import os from 'os';
import path from 'path';
export default async function warmUp(
globalConfig: {...},
projectConfig: {...},
): Promise<void> {
try {
warmUpHermesCompiler();
warmUpRNTesterCLI();
await warmUpMetro();
} catch (e) {
// Sandcastle fails to parse the test output if we log stuff to stdout/stderr.
if ((process.env.SANDCASTLE ?? '') !== '') {
console.error(
'Global warmup failed. Tests will continue to run but will likely fail. Details:\n',
e,
);
}
}
}
async function warmUpMetro(): Promise<void> {
const metroConfig = await Metro.loadConfig({
config: path.resolve(__dirname, '..', '..', 'config', 'metro.config.js'),
});
const entrypointPath = path.resolve(
__dirname,
'..',
'..',
'runtime',
'WarmUpEntryPoint.js',
);
const bundlePath = path.join(
os.tmpdir(),
`fantom-warmup-bundle-${Date.now()}.js`,
);
await Metro.runBuild(metroConfig, {
entry: entrypointPath,
out: bundlePath,
platform: 'android',
minify: false,
dev: true,
});
try {
fs.unlinkSync(bundlePath);
} catch {}
}
function warmUpHermesCompiler(): void {
const buildHermesCompilerCommandResult = runBuck2([
'build',
getBuckModeForPlatform(),
'//xplat/hermes/tools/hermesc:hermesc',
]);
if (buildHermesCompilerCommandResult.status !== 0) {
throw new Error(
getDebugInfoFromCommandResult(buildHermesCompilerCommandResult),
);
}
}
function warmUpRNTesterCLI(): void {
const buildRNTesterCommandResult = runBuck2([
'build',
getBuckModeForPlatform(),
'//xplat/ReactNative/react-native-cxx/samples/tester:tester',
]);
if (buildRNTesterCommandResult.status !== 0) {
throw new Error(getDebugInfoFromCommandResult(buildRNTesterCommandResult));
}
}
@@ -1,17 +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
* @oncall react_native
*/
/**
* This is just an entrypoint to warm up the Metro cache before the tests run.
*/
import 'react-native/Libraries/Core/InitializeCore.js';
import 'react-native/src/private/__tests__/ReactNativeTester';
import './setup';
-451
View File
@@ -1,451 +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.
*
* @flow strict-local
* @format
* @oncall react_native
*/
import deepEqual from 'deep-equal';
import nullthrows from 'nullthrows';
export type TestCaseResult = {
ancestorTitles: Array<string>,
title: string,
fullName: string,
status: 'passed' | 'failed' | 'pending',
duration: number,
failureMessages: Array<string>,
numPassingAsserts: number,
// location: string,
};
export type TestSuiteResult =
| {
testResults: Array<TestCaseResult>,
}
| {
error: {
message: string,
stack: string,
},
};
const tests: Array<{
title: string,
ancestorTitles: Array<string>,
implementation: () => mixed,
isFocused: boolean,
isSkipped: boolean,
result?: TestCaseResult,
}> = [];
const ancestorTitles: Array<string> = [];
const globalModifiers: Array<'focused' | 'skipped'> = [];
const globalDescribe = (global.describe = (
title: string,
implementation: () => mixed,
) => {
ancestorTitles.push(title);
implementation();
ancestorTitles.pop();
});
const globalIt =
(global.it =
global.test =
(title: string, implementation: () => mixed) =>
tests.push({
title,
implementation,
ancestorTitles: ancestorTitles.slice(),
isFocused:
globalModifiers.length > 0 &&
globalModifiers[globalModifiers.length - 1] === 'focused',
isSkipped:
globalModifiers.length > 0 &&
globalModifiers[globalModifiers.length - 1] === 'skipped',
}));
// $FlowExpectedError[prop-missing]
global.fdescribe = global.describe.only = (
title: string,
implementation: () => mixed,
) => {
globalModifiers.push('focused');
globalDescribe(title, implementation);
globalModifiers.pop();
};
// $FlowExpectedError[prop-missing]
global.it.only =
global.fit =
// $FlowExpectedError[prop-missing]
global.test.only =
(title: string, implementation: () => mixed) => {
globalModifiers.push('focused');
globalIt(title, implementation);
globalModifiers.pop();
};
// $FlowExpectedError[prop-missing]
global.xdescribe = global.describe.skip = (
title: string,
implementation: () => mixed,
) => {
globalModifiers.push('skipped');
globalDescribe(title, implementation);
globalModifiers.pop();
};
// $FlowExpectedError[prop-missing]
global.it.skip =
global.xit =
// $FlowExpectedError[prop-missing]
global.test.skip =
global.xtest =
(title: string, implementation: () => mixed) => {
globalModifiers.push('skipped');
globalIt(title, implementation);
globalModifiers.pop();
};
global.jest = {
fn: createMockFunction,
};
const MOCK_FN_TAG = Symbol('mock function');
function createMockFunction<TArgs: $ReadOnlyArray<mixed>, TReturn>(
initialImplementation?: (...TArgs) => TReturn,
): JestMockFn<TArgs, TReturn> {
let implementation: ?(...TArgs) => TReturn = initialImplementation;
const mock: JestMockFn<TArgs, TReturn>['mock'] = {
calls: [],
// $FlowExpectedError[incompatible-type]
lastCall: undefined,
instances: [],
contexts: [],
results: [],
};
const mockFunction = function (this: mixed, ...args: TArgs): TReturn {
let result: JestMockFn<TArgs, TReturn>['mock']['results'][number] = {
isThrow: false,
// $FlowExpectedError[incompatible-type]
value: undefined,
};
if (implementation != null) {
try {
result.value = implementation.apply(this, args);
} catch (error) {
result.isThrow = true;
result.value = error;
}
}
mock.calls.push(args);
mock.lastCall = args;
// $FlowExpectedError[incompatible-call]
mock.instances.push(new.target ? this : undefined);
mock.contexts.push(this);
mock.results.push(result);
if (result.isThrow) {
throw result.value;
}
return result.value;
};
mockFunction.mock = mock;
// $FlowExpectedError[invalid-computed-prop]
mockFunction[MOCK_FN_TAG] = true;
// $FlowExpectedError[prop-missing]
return mockFunction;
}
// flowlint unsafe-getters-setters:off
class ErrorWithCustomBlame extends Error {
// Initially 5 to ignore all the frames from Babel helpers to instantiate this
// custom error class.
#ignoredFrameCount: number = 5;
#cachedProcessedStack: ?string;
blameToPreviousFrame(): this {
this.#ignoredFrameCount++;
return this;
}
get stack(): string {
if (this.#cachedProcessedStack == null) {
const originalStack = super.stack;
if (originalStack == null) {
this.#cachedProcessedStack = originalStack;
} else {
const lines = originalStack.split('\n');
const index = lines.findIndex(line =>
/at (.*) \((.*):(\d+):(\d+)\)/.test(line),
);
lines.splice(index > -1 ? index : 1, this.#ignoredFrameCount);
this.#cachedProcessedStack = lines.join('\n');
}
}
return this.#cachedProcessedStack;
}
set stack(value: string) {
// no-op
}
}
class Expect {
#received: mixed;
#isNot: boolean = false;
constructor(received: mixed) {
this.#received = received;
}
get not(): this {
this.#isNot = !this.#isNot;
return this;
}
toEqual(expected: mixed): void {
const pass = deepEqual(this.#received, expected, {strict: true});
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected${this.#maybeNotLabel()} to equal ${String(expected)} but received ${String(this.#received)}.`,
).blameToPreviousFrame();
}
}
toBe(expected: mixed): void {
const pass = this.#received === expected;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected${this.#maybeNotLabel()} ${String(expected)} but received ${String(this.#received)}.`,
).blameToPreviousFrame();
}
}
toBeInstanceOf(expected: Class<mixed>): void {
const pass = this.#received instanceof expected;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`expected ${String(this.#received)}${this.#maybeNotLabel()} to be an instance of ${String(expected)}`,
).blameToPreviousFrame();
}
}
toBeCloseTo(expected: number, precision: number = 2): void {
const pass =
Math.abs(expected - Number(this.#received)) < Math.pow(10, -precision);
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be close to ${expected}`,
).blameToPreviousFrame();
}
}
toBeNull(): void {
const pass = this.#received == null;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be null`,
).blameToPreviousFrame();
}
}
toThrow(expected?: string): void {
if (expected != null && typeof expected !== 'string') {
throw new ErrorWithCustomBlame(
'toThrow() implementation only accepts strings as arguments.',
).blameToPreviousFrame();
}
let pass = false;
try {
// $FlowExpectedError[not-a-function]
this.#received();
} catch (error) {
pass = expected != null ? error.message === expected : true;
}
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to throw`,
).blameToPreviousFrame();
}
}
toHaveBeenCalled(): void {
const mock = this.#requireMock();
const pass = mock.calls.length > 0;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to have been called, but it was${this.#isNot ? '' : "n't"}`,
).blameToPreviousFrame();
}
}
toHaveBeenCalledTimes(times: number): void {
const mock = this.#requireMock();
const pass = mock.calls.length === times;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to have been called ${times} times, but it was called ${mock.calls.length} times`,
).blameToPreviousFrame();
}
}
toBeGreaterThanOrEqual(expected: number): void {
if (typeof this.#received !== 'number') {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)} to be a number but it was a ${typeof this.#received}`,
).blameToPreviousFrame();
}
if (typeof expected !== 'number') {
throw new ErrorWithCustomBlame(
`Expected ${String(expected)} to be a number but it was a ${typeof expected}`,
).blameToPreviousFrame();
}
const pass = this.#received >= expected;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be greater than or equal to ${expected}`,
).blameToPreviousFrame();
}
}
toBeLessThanOrEqual(expected: number): void {
if (typeof this.#received !== 'number') {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)} to be a number but it was a ${typeof this.#received}`,
).blameToPreviousFrame();
}
if (typeof expected !== 'number') {
throw new ErrorWithCustomBlame(
`Expected ${String(expected)} to be a number but it was a ${typeof expected}`,
).blameToPreviousFrame();
}
const pass = this.#received <= expected;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be less than or equal to ${expected}`,
).blameToPreviousFrame();
}
}
#isExpectedResult(pass: boolean): boolean {
return this.#isNot ? !pass : pass;
}
#maybeNotLabel(): string {
return this.#isNot ? ' not' : '';
}
#requireMock(): JestMockFn<$ReadOnlyArray<mixed>, mixed>['mock'] {
// $FlowExpectedError[incompatible-use]
if (!this.#received?.[MOCK_FN_TAG]) {
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)} to be a mock function, but it wasn't`,
)
.blameToPreviousFrame()
.blameToPreviousFrame();
}
// $FlowExpectedError[incompatible-use]
return this.#received.mock;
}
}
global.expect = (received: mixed) => new Expect(received);
function runWithGuard(fn: () => void) {
try {
fn();
} catch (error) {
let reportedError =
error instanceof Error ? error : new Error(String(error));
reportTestSuiteResult({
error: {
message: reportedError.message,
stack: reportedError.stack,
},
});
}
}
function executeTests() {
const hasFocusedTests = tests.some(test => test.isFocused);
for (const test of tests) {
const result: TestCaseResult = {
title: test.title,
fullName: [...test.ancestorTitles, test.title].join(' '),
ancestorTitles: test.ancestorTitles,
status: 'pending',
duration: 0,
failureMessages: [],
numPassingAsserts: 0,
};
test.result = result;
if (!test.isSkipped && (!hasFocusedTests || test.isFocused)) {
let status;
let error;
const start = Date.now();
try {
test.implementation();
status = 'passed';
} catch (e) {
error = e;
status = 'failed';
}
result.status = status;
result.duration = Date.now() - start;
result.failureMessages =
status === 'failed' && error
? [error.stack ?? error.message ?? String(error)]
: [];
}
}
reportTestSuiteResult({
testResults: tests.map(test => nullthrows(test.result)),
});
}
function reportTestSuiteResult(testSuiteResult: TestSuiteResult): void {
console.log(JSON.stringify(testSuiteResult));
}
global.$$RunTests$$ = () => {
executeTests();
};
export function registerTest(setUpTest: () => void) {
runWithGuard(() => {
setUpTest();
});
}
+15 -23
View File
@@ -12,31 +12,18 @@
'use strict';
// eslint-disable-next-line lint/sort-imports
const {
transformFromAstSync: babelTransformFromAstSync,
transformSync: babelTransformSync,
} = require('@babel/core');
const generate = require('@babel/generator').default;
const createCacheKeyFunction =
require('@jest/create-cache-key-function').default;
/* eslint-disable lint/sort-imports */
const metroBabelRegister = require('metro-babel-register');
const nullthrows = require('nullthrows');
const createCacheKeyFunction =
require('@jest/create-cache-key-function').default;
if (process.env.FBSOURCE_ENV === '1') {
// If we're running in the Meta-internal monorepo, use the central Babel
// registration, which registers all of the relevant source directories
// including Metro's root.
//
// $FlowExpectedError[cannot-resolve-module] - Won't resolve in OSS
require('@fb-tools/babel-register');
} else {
// Register Babel to allow local packages to be loaded from source
require('../scripts/build/babel-register').registerForMonorepo();
}
const transformer = require('@react-native/metro-babel-transformer');
const metroTransformPlugins = require('metro-transform-plugins');
const {
transformSync: babelTransformSync,
transformFromAstSync: babelTransformFromAstSync,
} = require('@babel/core');
const generate = require('@babel/generator').default;
// Files matching this pattern will be transformed with the Node JS Babel
// transformer, rather than with the React Native Babel transformer. Scripts
@@ -47,6 +34,10 @@ const nodeFiles = /[\\/]metro(?:-[^/]*)[\\/]/;
// hook. This is used below to configure babelTransformSync under Jest.
const {only: _, ...nodeBabelOptions} = metroBabelRegister.config([]);
// Register Babel to allow the transformer itself to be loaded from source.
require('../scripts/build/babel-register').registerForMonorepo();
const transformer = require('@react-native/metro-babel-transformer');
// Set BUILD_EXCLUDE_BABEL_REGISTER (see ../scripts/build/babel-register.js) to
// prevent inline Babel registration in code under test, normally required when
// running from source, but not in combination with the Jest transformer.
@@ -99,7 +90,8 @@ module.exports = {
ast: true,
retainLines: true,
plugins: [
metroTransformPlugins.inlineRequiresPlugin,
// TODO(moti): Replace with require('metro-transform-plugins').inlineRequiresPlugin when available in OSS
require('babel-preset-fbjs/plugins/inline-requires'),
babelPluginPreventBabelRegister,
],
sourceType: 'module',
+24 -29
View File
@@ -3,7 +3,6 @@
"private": true,
"version": "1000.0.0",
"license": "MIT",
"packageManager": "yarn@1.22.22",
"scripts": {
"android": "cd packages/rn-tester && npm run android",
"build-android": "./gradlew :packages:react-native:ReactAndroid:build",
@@ -14,7 +13,8 @@
"flow": "flow",
"format-check": "prettier --list-different \"./**/*.{js,md,yml,ts,tsx}\"",
"format": "npm run prettier && npm run clang-format",
"featureflags": "cd packages/react-native && yarn featureflags",
"featureflags-check": "cd packages/react-native && yarn featureflags-check",
"featureflags-update": "cd packages/react-native && yarn featureflags-update",
"lint-ci": "./scripts/circleci/analyze_code.sh && yarn shellcheck",
"lint-java": "node ./scripts/lint-java.js",
"lint": "eslint .",
@@ -22,7 +22,7 @@
"print-packages": "node ./scripts/monorepo/print",
"shellcheck": "./scripts/circleci/analyze_scripts.sh",
"start": "cd packages/rn-tester && npm run start",
"set-version": "node ./scripts/releases/set-version.js",
"set-version": "node ./scripts/releases/set-version",
"test-android": "./gradlew :packages:react-native:ReactAndroid:test",
"test-ci": "jest --maxWorkers=2 --ci --reporters=\"default\" --reporters=\"jest-junit\"",
"test-e2e-local-clean": "node ./scripts/release-testing/test-e2e-local-clean.js",
@@ -36,32 +36,31 @@
},
"workspaces": [
"packages/*",
"tools/*",
"!packages/helloworld"
"tools/*"
],
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.25.1",
"@babel/generator": "^7.25.0",
"@babel/plugin-transform-regenerator": "^7.24.7",
"@babel/preset-env": "^7.25.3",
"@babel/preset-flow": "^7.24.7",
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.20.0",
"@babel/generator": "^7.20.0",
"@babel/plugin-transform-regenerator": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/preset-flow": "^7.20.0",
"@definitelytyped/dtslint": "^0.0.127",
"@jest/create-cache-key-function": "^29.6.3",
"@react-native/metro-babel-transformer": "0.77.0-main",
"@react-native/metro-config": "0.77.0-main",
"@pkgjs/parseargs": "^0.11.0",
"@react-native/metro-babel-transformer": "0.75.1",
"@react-native/metro-config": "0.75.1",
"@tsconfig/node18": "1.0.1",
"@types/react": "^18.2.6",
"@typescript-eslint/parser": "^7.1.1",
"ansi-styles": "^4.2.1",
"babel-plugin-minify-dead-code-elimination": "^0.5.2",
"babel-plugin-syntax-hermes-parser": "0.25.1",
"babel-plugin-transform-define": "^2.1.4",
"babel-plugin-transform-define": "^2.1.2",
"babel-plugin-transform-flow-enums": "^0.0.2",
"babel-preset-fbjs": "^3.4.0",
"chalk": "^4.0.0",
"clang-format": "^1.8.0",
"connect": "^3.6.5",
"deep-equal": "1.1.1",
"eslint": "^8.57.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-babel": "^5.3.1",
@@ -76,24 +75,23 @@
"eslint-plugin-react-native": "^4.0.0",
"eslint-plugin-redundant-undefined": "^0.4.0",
"eslint-plugin-relay": "^1.8.3",
"flow-api-translator": "0.25.1",
"flow-bin": "^0.255.0",
"flow-api-translator": "0.22.0",
"flow-bin": "^0.238.0",
"glob": "^7.1.1",
"hermes-eslint": "0.25.1",
"hermes-transform": "0.25.1",
"hermes-eslint": "0.22.0",
"hermes-transform": "0.22.0",
"inquirer": "^7.1.0",
"jest": "^29.6.3",
"jest-diff": "^29.7.0",
"jest-junit": "^10.0.0",
"jscodeshift": "^0.14.0",
"metro-babel-register": "^0.81.0",
"metro-memory-fs": "^0.81.0",
"metro-transform-plugins": "^0.81.0",
"metro-babel-register": "^0.80.0",
"metro-memory-fs": "^0.80.0",
"micromatch": "^4.0.4",
"mkdirp": "^0.5.1",
"node-fetch": "^2.2.0",
"nullthrows": "^1.1.1",
"prettier": "2.8.8",
"prettier-plugin-hermes-parser": "0.25.1",
"prettier-plugin-hermes-parser": "0.22.0",
"react": "18.3.1",
"react-test-renderer": "18.3.1",
"rimraf": "^3.0.2",
@@ -101,9 +99,6 @@
"signedsource": "^1.0.0",
"supports-color": "^7.1.0",
"typescript": "5.0.4",
"ws": "^6.2.3"
},
"resolutions": {
"react-is": "18.3.1"
"ws": "^6.2.2"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/assets-registry",
"version": "0.77.0-main",
"version": "0.75.1",
"description": "Asset support code for React Native.",
"license": "MIT",
"repository": {

Some files were not shown because too many files have changed in this diff Show More