mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2519010b1c | ||
|
|
be0bfe70d7 | ||
|
|
c40ba02767 | ||
|
|
492ceb7612 | ||
|
|
cf906cc599 | ||
|
|
0f242a1300 | ||
|
|
9fe07ef090 |
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
"module:@react-native/babel-preset"
|
||||
],
|
||||
"plugins": [
|
||||
"babel-plugin-transform-flow-enums"
|
||||
]
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
|
||||
[android]
|
||||
target = Google Inc.:Google APIs:23
|
||||
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
||||
|
||||
[alias]
|
||||
movies = //Examples/Movies/android/app:app
|
||||
uiexplorer = //Examples/UIExplorer/android/app:app
|
||||
@@ -0,0 +1 @@
|
||||
-Xmx512m -XX:+HeapDumpOnOutOfMemoryError
|
||||
@@ -1,2 +0,0 @@
|
||||
BUNDLE_PATH: "vendor/bundle"
|
||||
BUNDLE_FORCE_RUBY_PLATFORM: 1
|
||||
@@ -1,172 +0,0 @@
|
||||
# Circle CI
|
||||
|
||||
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.
|
||||
@@ -1,114 +0,0 @@
|
||||
version: 2.1
|
||||
|
||||
# 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:
|
||||
choose_ci_jobs:
|
||||
docker:
|
||||
- image: debian:bullseye
|
||||
resource_class: small
|
||||
steps:
|
||||
- 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: /.*/
|
||||
@@ -1,580 +0,0 @@
|
||||
# -------------------------
|
||||
# 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
|
||||
@@ -1,38 +0,0 @@
|
||||
# -------------------------
|
||||
# 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
@@ -1,99 +0,0 @@
|
||||
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"]
|
||||
@@ -1,58 +0,0 @@
|
||||
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"]
|
||||
@@ -1,9 +0,0 @@
|
||||
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
|
||||
@@ -1,86 +0,0 @@
|
||||
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"]
|
||||
@@ -1,11 +0,0 @@
|
||||
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
|
||||
@@ -1,149 +0,0 @@
|
||||
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
|
||||
@@ -1,28 +0,0 @@
|
||||
# -------------------------
|
||||
# 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
|
||||
@@ -1,93 +0,0 @@
|
||||
---
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: [ FOR_EACH_RANGE, FOR_EACH, ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*\.h(pp)?>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
QualifierAlignment: Left
|
||||
---
|
||||
Language: ObjC
|
||||
ColumnLimit: 120
|
||||
BreakBeforeBraces: WebKit
|
||||
PointerAlignment: Right
|
||||
...
|
||||
+1
-10
@@ -1,4 +1,4 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
@@ -9,12 +9,3 @@ end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.gradle]
|
||||
indent_size = 4
|
||||
|
||||
[*.kts]
|
||||
indent_size = 4
|
||||
|
||||
[BUCK]
|
||||
indent_size = 4
|
||||
|
||||
+4
-16
@@ -1,17 +1,5 @@
|
||||
**/main.js
|
||||
# node_modules ignored by default
|
||||
|
||||
**/staticBundle.js
|
||||
docs/generatedComponentApiDocs.js
|
||||
packages/react-native/flow/
|
||||
packages/react-native/sdks/
|
||||
packages/react-native/ReactAndroid/hermes-engine/build/
|
||||
packages/react-native/Libraries/Renderer/*
|
||||
packages/react-native/Libraries/vendor/**/*
|
||||
node_modules/
|
||||
packages/*/node_modules
|
||||
packages/*/dist
|
||||
packages/debugger-frontend/dist/**/*
|
||||
packages/react-native-codegen/lib
|
||||
tools/eslint/rules/sort-imports.js
|
||||
**/Pods/*
|
||||
**/*.macos.js
|
||||
**/*.windows.js
|
||||
**/main.js
|
||||
Libraries/vendor/**/*
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
{
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
|
||||
"env": {
|
||||
"es6": true,
|
||||
"jasmine": true,
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
|
||||
// Map from global var to bool specifying if it can be redefined
|
||||
"globals": {
|
||||
"__DEV__": true,
|
||||
"__dirname": false,
|
||||
"__fbBatchedBridgeConfig": false,
|
||||
"alert": false,
|
||||
"cancelAnimationFrame": false,
|
||||
"cancelIdleCallback": false,
|
||||
"clearImmediate": true,
|
||||
"clearInterval": false,
|
||||
"clearTimeout": false,
|
||||
"console": false,
|
||||
"document": false,
|
||||
"escape": false,
|
||||
"Event": false,
|
||||
"EventTarget": false,
|
||||
"exports": false,
|
||||
"fetch": false,
|
||||
"FormData": false,
|
||||
"global": false,
|
||||
"jest": false,
|
||||
"Map": true,
|
||||
"module": false,
|
||||
"navigator": false,
|
||||
"process": false,
|
||||
"Promise": true,
|
||||
"requestAnimationFrame": true,
|
||||
"requestIdleCallback": true,
|
||||
"require": false,
|
||||
"Set": true,
|
||||
"setImmediate": true,
|
||||
"setInterval": false,
|
||||
"setTimeout": false,
|
||||
"window": false,
|
||||
"XMLHttpRequest": false,
|
||||
"pit": false,
|
||||
|
||||
// Flow global types.
|
||||
"ReactComponent": false,
|
||||
"ReactClass": false,
|
||||
"ReactElement": false,
|
||||
"ReactPropsCheckType": false,
|
||||
"ReactPropsChainableTypeChecker": false,
|
||||
"ReactPropTypes": false,
|
||||
"SyntheticEvent": false,
|
||||
"$Either": false,
|
||||
"$All": false,
|
||||
"$Tuple": false,
|
||||
"$Supertype": false,
|
||||
"$Subtype": false,
|
||||
"$Shape": false,
|
||||
"$Diff": false,
|
||||
"$Keys": false,
|
||||
"$Enum": false,
|
||||
"$Exports": false,
|
||||
"$FlowIssue": false,
|
||||
"$FlowFixMe": false,
|
||||
"$FixMe": false
|
||||
},
|
||||
|
||||
"rules": {
|
||||
"comma-dangle": 0, // disallow trailing commas in object literals
|
||||
"no-cond-assign": 1, // disallow assignment in conditional expressions
|
||||
"no-console": 0, // disallow use of console (off by default in the node environment)
|
||||
"no-constant-condition": 0, // disallow use of constant expressions in conditions
|
||||
"no-control-regex": 1, // disallow control characters in regular expressions
|
||||
"no-debugger": 1, // disallow use of debugger
|
||||
"no-dupe-keys": 1, // disallow duplicate keys when creating object literals
|
||||
"no-empty": 0, // disallow empty statements
|
||||
"no-ex-assign": 1, // disallow assigning to the exception in a catch block
|
||||
"no-extra-boolean-cast": 1, // disallow double-negation boolean casts in a boolean context
|
||||
"no-extra-parens": 0, // disallow unnecessary parentheses (off by default)
|
||||
"no-extra-semi": 1, // disallow unnecessary semicolons
|
||||
"no-func-assign": 1, // disallow overwriting functions written as function declarations
|
||||
"no-inner-declarations": 0, // disallow function or variable declarations in nested blocks
|
||||
"no-invalid-regexp": 1, // disallow invalid regular expression strings in the RegExp constructor
|
||||
"no-negated-in-lhs": 1, // disallow negation of the left operand of an in expression
|
||||
"no-obj-calls": 1, // disallow the use of object properties of the global object (Math and JSON) as functions
|
||||
"no-regex-spaces": 1, // disallow multiple spaces in a regular expression literal
|
||||
"no-reserved-keys": 0, // disallow reserved words being used as object literal keys (off by default)
|
||||
"no-sparse-arrays": 1, // disallow sparse arrays
|
||||
"no-unreachable": 1, // disallow unreachable statements after a return, throw, continue, or break statement
|
||||
"use-isnan": 1, // disallow comparisons with the value NaN
|
||||
"valid-jsdoc": 0, // Ensure JSDoc comments are valid (off by default)
|
||||
"valid-typeof": 1, // Ensure that the results of typeof are compared against a valid string
|
||||
|
||||
// Best Practices
|
||||
// These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns.
|
||||
|
||||
"block-scoped-var": 0, // treat var statements as if they were block scoped (off by default)
|
||||
"complexity": 0, // specify the maximum cyclomatic complexity allowed in a program (off by default)
|
||||
"consistent-return": 0, // require return statements to either always or never specify values
|
||||
"curly": 1, // specify curly brace conventions for all control statements
|
||||
"default-case": 0, // require default case in switch statements (off by default)
|
||||
"dot-notation": 1, // encourages use of dot notation whenever possible
|
||||
"eqeqeq": [1, "allow-null"], // require the use of === and !==
|
||||
"guard-for-in": 0, // make sure for-in loops have an if statement (off by default)
|
||||
"no-alert": 1, // disallow the use of alert, confirm, and prompt
|
||||
"no-caller": 1, // disallow use of arguments.caller or arguments.callee
|
||||
"no-div-regex": 1, // disallow division operators explicitly at beginning of regular expression (off by default)
|
||||
"no-else-return": 0, // disallow else after a return in an if (off by default)
|
||||
"no-eq-null": 0, // disallow comparisons to null without a type-checking operator (off by default)
|
||||
"no-eval": 1, // disallow use of eval()
|
||||
"no-extend-native": 1, // disallow adding to native types
|
||||
"no-extra-bind": 1, // disallow unnecessary function binding
|
||||
"no-fallthrough": 1, // disallow fallthrough of case statements
|
||||
"no-floating-decimal": 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default)
|
||||
"no-implied-eval": 1, // disallow use of eval()-like methods
|
||||
"no-labels": 1, // disallow use of labeled statements
|
||||
"no-iterator": 1, // disallow usage of __iterator__ property
|
||||
"no-lone-blocks": 1, // disallow unnecessary nested blocks
|
||||
"no-loop-func": 0, // disallow creation of functions within loops
|
||||
"no-multi-str": 0, // disallow use of multiline strings
|
||||
"no-native-reassign": 0, // disallow reassignments of native objects
|
||||
"no-new": 1, // disallow use of new operator when not part of the assignment or comparison
|
||||
"no-new-func": 1, // disallow use of new operator for Function object
|
||||
"no-new-wrappers": 1, // disallows creating new instances of String,Number, and Boolean
|
||||
"no-octal": 1, // disallow use of octal literals
|
||||
"no-octal-escape": 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
|
||||
"no-proto": 1, // disallow usage of __proto__ property
|
||||
"no-redeclare": 0, // disallow declaring the same variable more then once
|
||||
"no-return-assign": 1, // disallow use of assignment in return statement
|
||||
"no-script-url": 1, // disallow use of javascript: urls.
|
||||
"no-self-compare": 1, // disallow comparisons where both sides are exactly the same (off by default)
|
||||
"no-sequences": 1, // disallow use of comma operator
|
||||
"no-unused-expressions": 0, // disallow usage of expressions in statement position
|
||||
"no-void": 1, // disallow use of void operator (off by default)
|
||||
"no-warning-comments": 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default)
|
||||
"no-with": 1, // disallow use of the with statement
|
||||
"radix": 1, // require use of the second argument for parseInt() (off by default)
|
||||
"semi-spacing": 1, // require a space after a semi-colon
|
||||
"vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default)
|
||||
"wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses (off by default)
|
||||
"yoda": 1, // require or disallow Yoda conditions
|
||||
|
||||
// Variables
|
||||
// These rules have to do with variable declarations.
|
||||
|
||||
"no-catch-shadow": 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment)
|
||||
"no-delete-var": 1, // disallow deletion of variables
|
||||
"no-label-var": 1, // disallow labels that share a name with a variable
|
||||
"no-shadow": 1, // disallow declaration of variables already declared in the outer scope
|
||||
"no-shadow-restricted-names": 1, // disallow shadowing of names such as arguments
|
||||
"no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block
|
||||
"no-undefined": 0, // disallow use of undefined variable (off by default)
|
||||
"no-undef-init": 1, // disallow use of undefined when initializing variables
|
||||
"no-unused-vars": [1, {"vars": "all", "args": "none"}], // disallow declaration of variables that are not used in the code
|
||||
"no-use-before-define": 0, // disallow use of variables before they are defined
|
||||
|
||||
// Node.js
|
||||
// These rules are specific to JavaScript running on Node.js.
|
||||
|
||||
"handle-callback-err": 1, // enforces error handling in callbacks (off by default) (on by default in the node environment)
|
||||
"no-mixed-requires": 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment)
|
||||
"no-new-require": 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment)
|
||||
"no-path-concat": 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment)
|
||||
"no-process-exit": 0, // disallow process.exit() (on by default in the node environment)
|
||||
"no-restricted-modules": 1, // restrict usage of specified node modules (off by default)
|
||||
"no-sync": 0, // disallow use of synchronous methods (off by default)
|
||||
|
||||
// Stylistic Issues
|
||||
// These rules are purely matters of style and are quite subjective.
|
||||
|
||||
"key-spacing": 0,
|
||||
"keyword-spacing": 1, // enforce spacing before and after keywords
|
||||
"jsx-quotes": [1, "prefer-double"],
|
||||
"comma-spacing": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"brace-style": 0, // enforce one true brace style (off by default)
|
||||
"camelcase": 0, // require camel case names
|
||||
"consistent-this": [1, "self"], // enforces consistent naming when capturing the current execution context (off by default)
|
||||
"eol-last": 1, // enforce newline at the end of file, with no multiple empty lines
|
||||
"func-names": 0, // require function expressions to have a name (off by default)
|
||||
"func-style": 0, // enforces use of function declarations or expressions (off by default)
|
||||
"new-cap": 0, // require a capital letter for constructors
|
||||
"new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments
|
||||
"no-nested-ternary": 0, // disallow nested ternary expressions (off by default)
|
||||
"no-array-constructor": 1, // disallow use of the Array constructor
|
||||
"no-lonely-if": 0, // disallow if as the only statement in an else block (off by default)
|
||||
"no-new-object": 1, // disallow use of the Object constructor
|
||||
"no-spaced-func": 1, // disallow space between function identifier and application
|
||||
"no-ternary": 0, // disallow the use of ternary operators (off by default)
|
||||
"no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines
|
||||
"no-underscore-dangle": 0, // disallow dangling underscores in identifiers
|
||||
"no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation
|
||||
"quotes": [1, "single", "avoid-escape"], // specify whether double or single quotes should be used
|
||||
"quote-props": 0, // require quotes around object literal property names (off by default)
|
||||
"semi": 1, // require or disallow use of semicolons instead of ASI
|
||||
"sort-vars": 0, // sort variables within the same declaration block (off by default)
|
||||
"space-in-brackets": 0, // require or disallow spaces inside brackets (off by default)
|
||||
"space-in-parens": 0, // require or disallow spaces inside parentheses (off by default)
|
||||
"space-infix-ops": 1, // require spaces around operators
|
||||
"space-unary-ops": [1, { "words": true, "nonwords": false }], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default)
|
||||
"max-nested-callbacks": 0, // specify the maximum depth callbacks can be nested (off by default)
|
||||
"one-var": 0, // allow just one var statement per function (off by default)
|
||||
"wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default)
|
||||
|
||||
// Legacy
|
||||
// The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same.
|
||||
|
||||
"max-depth": 0, // specify the maximum depth that blocks can be nested (off by default)
|
||||
"max-len": 0, // specify the maximum length of a line in your program (off by default)
|
||||
"max-params": 0, // limits the number of parameters that can be used in the function declaration. (off by default)
|
||||
"max-statements": 0, // specify the maximum number of statement allowed in a function (off by default)
|
||||
"no-bitwise": 1, // disallow use of bitwise operators (off by default)
|
||||
"no-plusplus": 0, // disallow use of unary operators, ++ and -- (off by default)
|
||||
|
||||
"react/display-name": 0,
|
||||
"react/jsx-boolean-value": 0,
|
||||
"react/jsx-no-duplicate-props": 2,
|
||||
"react/jsx-no-undef": 1,
|
||||
"react/jsx-sort-props": 0,
|
||||
"react/jsx-uses-react": 1,
|
||||
"react/jsx-uses-vars": 1,
|
||||
"react/no-did-mount-set-state": [1, "allow-in-func"],
|
||||
"react/no-did-update-set-state": [1, "allow-in-func"],
|
||||
"react/no-multi-comp": 0,
|
||||
"react/no-string-refs": 1,
|
||||
"react/no-unknown-property": 0,
|
||||
"react/prop-types": 0,
|
||||
"react/react-in-jsx-scope": 1,
|
||||
"react/self-closing-comp": 1,
|
||||
"react/wrap-multilines": 0,
|
||||
}
|
||||
}
|
||||
-124
@@ -1,124 +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 path = require('node:path');
|
||||
|
||||
require('eslint-plugin-lint').load(path.join(__dirname, 'tools/eslint/rules'));
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
|
||||
extends: ['@react-native'],
|
||||
|
||||
plugins: ['@react-native/eslint-plugin-specs', 'lint'],
|
||||
|
||||
overrides: [
|
||||
// overriding the JS config from @react-native/eslint-config to ensure
|
||||
// that we use hermes-eslint for all js files
|
||||
{
|
||||
files: ['*.js', '*.js.flow', '*.jsx'],
|
||||
parser: 'hermes-eslint',
|
||||
rules: {
|
||||
// These rules are not required with hermes-eslint
|
||||
'ft-flow/define-flow-type': 0,
|
||||
'ft-flow/use-flow-type': 0,
|
||||
// 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',
|
||||
},
|
||||
{
|
||||
files: ['package.json'],
|
||||
rules: {
|
||||
'lint/react-native-manifest': 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['flow-typed/**/*.js'],
|
||||
rules: {
|
||||
'lint/valid-flow-typed-signature': 2,
|
||||
'no-unused-vars': 0,
|
||||
quotes: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'packages/react-native/Libraries/**/*.js',
|
||||
'packages/react-native/src/**/*.js',
|
||||
],
|
||||
rules: {
|
||||
'@react-native/platform-colors': 2,
|
||||
'@react-native/specs/react-native-modules': 2,
|
||||
'lint/no-haste-imports': 2,
|
||||
'lint/no-react-native-imports': 2,
|
||||
'lint/require-extends-error': 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'**/__fixtures__/**/*.js',
|
||||
'**/__mocks__/**/*.js',
|
||||
'**/__tests__/**/*.js',
|
||||
'packages/react-native/jest/**/*.js',
|
||||
'packages/rn-tester/**/*.js',
|
||||
],
|
||||
globals: {
|
||||
// Expose some Jest globals for test helpers
|
||||
afterAll: true,
|
||||
afterEach: true,
|
||||
beforeAll: true,
|
||||
beforeEach: true,
|
||||
expect: true,
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/__tests__/**/*-test.js'],
|
||||
env: {
|
||||
jasmine: true,
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'react-native/no-inline-styles': 'off',
|
||||
'@typescript-eslint/no-shadow': 'off',
|
||||
'no-self-compare': 'off',
|
||||
'react/self-closing-comp': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.d.ts'],
|
||||
plugins: ['redundant-undefined'],
|
||||
rules: {
|
||||
'no-dupe-class-members': 'off',
|
||||
'redundant-undefined/redundant-undefined': [
|
||||
'error',
|
||||
{followExactOptionalPropertyTypes: true},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
+32
-69
@@ -1,94 +1,57 @@
|
||||
[ignore]
|
||||
; Ignore templates for 'react-native init'
|
||||
<PROJECT_ROOT>/packages/react-native/template/.*
|
||||
<PROJECT_ROOT>/packages/react-native/sdks/.*
|
||||
|
||||
; Ignore the codegen e2e tests
|
||||
<PROJECT_ROOT>/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeEnumTurboModule.js
|
||||
# We fork some components by platform.
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore the Dangerfile
|
||||
<PROJECT_ROOT>/packages/react-native-bots/dangerfile.js
|
||||
# Ignore templates with `@flow` in header
|
||||
.*/local-cli/generator.*
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
# Ignore malformed json
|
||||
.*/node_modules/y18n/test/.*\.json
|
||||
|
||||
# Ignore the website subdir
|
||||
<PROJECT_ROOT>/website/.*
|
||||
|
||||
# Ignore BUCK generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore other platform suffixes
|
||||
.*\.macos\.js$
|
||||
.*\.windows\.js$
|
||||
# Ignore unexpected extra @providesModule
|
||||
.*/node_modules/commoner/test/source/widget/share.js
|
||||
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||
|
||||
; Checked-in build output
|
||||
<PROJECT_ROOT>/packages/debugger-frontend/dist/
|
||||
|
||||
; Generated build output
|
||||
<PROJECT_ROOT>/packages/.*/dist
|
||||
|
||||
; helloworld
|
||||
<PROJECT_ROOT>/packages/helloworld/ios/Pods/
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
# Ignore duplicate module providers
|
||||
# For RN Apps installed via npm, "Libraries" folder is inside node_modules/react-native but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
.*/Libraries/react-native/ReactNative.js
|
||||
.*/node_modules/jest-runtime/build/__tests__/.*
|
||||
|
||||
[include]
|
||||
|
||||
[declarations]
|
||||
.*/node_modules/.*
|
||||
|
||||
[libs]
|
||||
flow-typed/
|
||||
packages/react-native/interface.js
|
||||
packages/react-native/flow/
|
||||
Libraries/react-native/react-native-interface.js
|
||||
flow/
|
||||
|
||||
[options]
|
||||
enums=true
|
||||
casting_syntax=both
|
||||
module.system=haste
|
||||
|
||||
emoji=true
|
||||
esproposal.class_static_fields=enable
|
||||
esproposal.class_instance_fields=enable
|
||||
|
||||
exact_by_default=true
|
||||
|
||||
format.bracket_spacing=false
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
|
||||
experimental.multi_platform=true
|
||||
experimental.multi_platform.extensions=.ios
|
||||
experimental.multi_platform.extensions=.android
|
||||
experimental.strict_type_args=true
|
||||
|
||||
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\)$' -> '<PROJECT_ROOT>/packages/react-native/Libraries/Image/RelativeImageStub'
|
||||
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
|
||||
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\)$' -> 'RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
suppress_type=$FlowFixMeEmpty
|
||||
suppress_type=$FixMe
|
||||
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=error
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
unused-promise=error
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-2]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-2]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
nonstrict-import
|
||||
sketchy-null
|
||||
unclear-type
|
||||
unsafe-getters-setters
|
||||
untyped-import
|
||||
untyped-type-import
|
||||
unsafe.enable_getters_and_setters=true
|
||||
|
||||
[version]
|
||||
^0.238.0
|
||||
^0.32.0
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Force LF line endings for Bash scripts. On Windows the rest of the source
|
||||
# files will typically have CR+LF endings (Git default on Windows), but Bash
|
||||
# scripts need to have LF endings to work (under Cygwin), thus override to force
|
||||
# that.
|
||||
gradlew text eol=lf
|
||||
*.sh text eol=lf
|
||||
@@ -1,4 +1,42 @@
|
||||
✋ To keep the backlog clean and actionable, issues will be
|
||||
🚫 closed if they do not follow one of the issue templates:
|
||||
👉 https://github.com/facebook/react-native/issues/new/choose
|
||||
## Hey there and thank you for using React Native!
|
||||
|
||||
React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. Before opening a new issue, make sure to carefully read the following guidelines.
|
||||
|
||||
- Is this something you can **debug and fix**?
|
||||
Send a pull request! Bug fixes and documentation fixes are welcome.
|
||||
- Have a **usage** question?
|
||||
We use GitHub Issues for bugs. Ask your usage question on Stack Overflow: http://stackoverflow.com/questions/tagged/react-native
|
||||
- Have an idea for a **feature**?
|
||||
Post the feature request on Product Pains, which has a voting system to surface important issues: https://productpains.com/product/react-native/
|
||||
|
||||
GitHub issues should only be used for bugs. Make sure these boxes are checked before submitting your issue:
|
||||
|
||||
- [ ] You're using the latest release of React Native: https://github.com/facebook/react-native/releases
|
||||
|
||||
- [ ] You've searched through existing issues: https://github.com/facebook/react-native/issues
|
||||
Chances are that your issue has been reported or resolved before.
|
||||
|
||||
- [ ] You have filled out the template below, or provided an equivalent amount of detail.
|
||||
Issues without sufficient information will be labeled 'Needs more information' and will be closed until there is enough information.
|
||||
|
||||
Describe your issue in as much detail as possible. Provide **screenshots** where appropriate. Provide a **minimal code snippet** / [rnplay](https://rnplay.org/) example that reproduces the bug, or include a list of detailed list of steps that reproduce the issue.
|
||||
|
||||
--- delete everything above this line before submitting your issue ---
|
||||
|
||||
### Issue Description
|
||||
|
||||
[FILL THIS OUT]
|
||||
|
||||
### Steps to Reproduce / Code Snippets
|
||||
|
||||
[FILL THIS OUT]
|
||||
|
||||
#### Expected Results
|
||||
|
||||
[FILL THIS OUT]
|
||||
|
||||
### Additional Information
|
||||
|
||||
* React Native version: [FILL THIS OUT]
|
||||
* Platform(s) (iOS, Android, or both?): [FILL THIS OUT]
|
||||
* Operating System (macOS, Linux, or Windows?): [FILL THIS OUT]
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Report a reproducible bug or regression in React Native.
|
||||
labels: ["Needs: Triage :mag:"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "## Reporting a bug to React Native"
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to report an issue for React Native, your contribution will help
|
||||
make the framework better for everyone.
|
||||
|
||||
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're 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:
|
||||
* Have a **valid reproducer** (either a [Expo Snack](https://snack.expo.dev/) or a [empty project from template](https://github.com/react-native-community/reproducer-react-native).
|
||||
* Is tested against the [**latest stable**](https://github.com/facebook/react-native/releases/) of React Native.
|
||||
|
||||
Due to the extreme number of bugs we receive, we will be looking **ONLY** into issues with a reproducer, and on [supported versions](https://github.com/reactwg/react-native-releases#which-versions-are-currently-supported) 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 reproduce the issue.
|
||||
placeholder: |
|
||||
1. Install the application with `yarn android`
|
||||
2. Click on the button on the Home
|
||||
3. Notice the crash
|
||||
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.73.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platforms
|
||||
attributes:
|
||||
label: Affected Platforms
|
||||
description: Please select which platform you're developing to, and which OS you're using for building.
|
||||
multiple: true
|
||||
options:
|
||||
- Runtime - Android
|
||||
- Runtime - iOS
|
||||
- Runtime - Web
|
||||
- Runtime - Desktop
|
||||
- Build - MacOS
|
||||
- Build - Windows
|
||||
- Build - Linux
|
||||
- Other (please specify)
|
||||
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: stacktrace
|
||||
attributes:
|
||||
label: Stacktrace or Logs
|
||||
description: Please provide a stacktrace or a log of your crash or failure
|
||||
render: text
|
||||
placeholder: |
|
||||
Paste your stacktraces and logs here. They might look like:
|
||||
|
||||
java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libfabricjni.so caused by: com.facebook.react.fabric.StateWrapperImpl result: 0
|
||||
at com.facebook.soloader.SoLoader.g(Unknown Source:341)
|
||||
at com.facebook.soloader.SoLoader.t(Unknown Source:124)
|
||||
at com.facebook.soloader.SoLoader.s(Unknown Source:2)
|
||||
at com.facebook.soloader.SoLoader.q(Unknown Source:42)
|
||||
at com.facebook.soloader.SoLoader.p(Unknown Source:1)
|
||||
...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: reproducer
|
||||
attributes:
|
||||
label: Reproducer
|
||||
description: A link to a Expo Snack or a public repository that reproduces this bug, using [this template](https://github.com/react-native-community/reproducer-react-native). Reproducers are **mandatory**.
|
||||
placeholder: "https://github.com/<myuser>/<myreproducer>"
|
||||
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**.
|
||||
@@ -1,26 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ⬆️ Upgrade - Build Regression
|
||||
url: https://github.com/reactwg/react-native-releases/issues/new/choose
|
||||
about: |
|
||||
If you are upgrading to a new React Native version (stable or pre-release) and encounter a build regression.
|
||||
- name: 🚀 Expo Issue
|
||||
url: https://github.com/expo/expo/issues/new
|
||||
about: |
|
||||
If you're using Expo in your project, please report the issue first in the Expo issue tracker.
|
||||
- name: 📃 Documentation Issue
|
||||
url: https://github.com/facebook/react-native-website/issues
|
||||
about: Please report documentation issues in the React Native website repository.
|
||||
- name: 📦 Metro Issue
|
||||
url: https://github.com/facebook/metro/issues/new
|
||||
about: |
|
||||
If you've encountered a module resolution problem, e.g. "Error: Unable to resolve module ...", or something else that might be related to Metro, please open an issue in the Metro repo instead.
|
||||
- name: 🤔 Questions and Help
|
||||
url: https://reactnative.dev/help
|
||||
about: Looking for help with your app? Please refer to the React Native community's support resources.
|
||||
- name: 💫 New Architecture - Questions & Technical Deep dive insights
|
||||
url: https://github.com/reactwg/react-native-new-architecture
|
||||
about: Questions and doubts related to technical questions for the New Architecture should be directed to the Working Group. Instructions on how to join are available in the README.
|
||||
- name: 🚀 Discussions and Proposals
|
||||
url: https://github.com/react-native-community/discussions-and-proposals
|
||||
about: Discuss the future of React Native in the React Native community's discussions and proposals repository.
|
||||
@@ -1,135 +0,0 @@
|
||||
name: 💫 New Architecture - Bug Report
|
||||
description: Report a reproducible bug or a build issue when using the New Architecture (Fabric & TurboModules) in React Native.
|
||||
labels: ["Needs: Triage :mag:", "Type: New Architecture"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "## New Architecture Related Bugs"
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to report an issue for [the New Architecture of React Native](https://reactnative.dev/docs/the-new-architecture/landing-page),
|
||||
your contribution will help make the framework better for everyone.
|
||||
|
||||
If you're **NOT** using the New Architecture, please use this [other bug type](https://github.com/facebook/react-native/issues/new?template=bug_report.yml).
|
||||
Do not attempt to open a bug in this category if you're not using the New Architecture as your bug will be closed.
|
||||
|
||||
Make sure that your issue:
|
||||
* Have a **valid reproducer** (either a [Expo Snack](https://snack.expo.dev/) or a [empty project from template](https://github.com/react-native-community/reproducer-react-native).
|
||||
* Is tested against the [**latest stable**](https://github.com/facebook/react-native/releases/) of React Native.
|
||||
|
||||
Due to the extreme number of bugs we receive, we will be looking **ONLY** into issues with a reproducer, and on [supported versions](https://github.com/reactwg/react-native-releases#which-versions-are-currently-supported) 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 reproduce the issue.
|
||||
placeholder: |
|
||||
1. Install the application with `yarn android`
|
||||
2. Click on the button on the Home
|
||||
3. Notice the crash
|
||||
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.73.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platforms
|
||||
attributes:
|
||||
label: Affected Platforms
|
||||
description: Please select which platform you're developing to, and which OS you're using for building.
|
||||
multiple: true
|
||||
options:
|
||||
- Runtime - Android
|
||||
- Runtime - iOS
|
||||
- Runtime - Web
|
||||
- Runtime - Desktop
|
||||
- Build - MacOS
|
||||
- Build - Windows
|
||||
- Build - Linux
|
||||
- Other (please specify)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: areas
|
||||
attributes:
|
||||
label: Areas
|
||||
description: Which areas of the New Architecture are affected by this bug report?
|
||||
multiple: true
|
||||
options:
|
||||
- Fabric - The New Renderer
|
||||
- TurboModule - The New Native Module System
|
||||
- JSI - Javascript Interface
|
||||
- Bridgeless - The New Initialization Flow
|
||||
- Codegen
|
||||
- Other (please specify)
|
||||
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: stacktrace
|
||||
attributes:
|
||||
label: Stacktrace or Logs
|
||||
description: Please provide a stacktrace or a log of your crash or failure
|
||||
render: text
|
||||
placeholder: |
|
||||
Paste your stacktraces and logs here. They might look like:
|
||||
|
||||
java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libfabricjni.so caused by: com.facebook.react.fabric.StateWrapperImpl result: 0
|
||||
at com.facebook.soloader.SoLoader.g(Unknown Source:341)
|
||||
at com.facebook.soloader.SoLoader.t(Unknown Source:124)
|
||||
at com.facebook.soloader.SoLoader.s(Unknown Source:2)
|
||||
at com.facebook.soloader.SoLoader.q(Unknown Source:42)
|
||||
at com.facebook.soloader.SoLoader.p(Unknown Source:1)
|
||||
...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: reproducer
|
||||
attributes:
|
||||
label: Reproducer
|
||||
description: A link to a Expo Snack or a public repository that reproduces this bug, using [this template](https://github.com/react-native-community/reproducer-react-native). Reproducers are **mandatory**.
|
||||
placeholder: "https://github.com/<myuser>/<myreproducer>"
|
||||
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**.
|
||||
@@ -1,21 +1,19 @@
|
||||
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. -->
|
||||
Thanks for submitting a pull request! Please provide enough information so that others can review your pull request:
|
||||
|
||||
## Summary:
|
||||
> **Unless you are a React Native release maintainer and cherry-picking an *existing* commit into a current release, ensure your pull request is targeting the `master` React Native branch.**
|
||||
|
||||
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
|
||||
Explain the **motivation** for making this change. What existing problem does the pull request solve?
|
||||
|
||||
## Changelog:
|
||||
Prefer **small pull requests**. These are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
|
||||
|
||||
<!-- Help reviewers and the release process by writing your own changelog entry.
|
||||
**Test plan (required)**
|
||||
|
||||
Pick one each for the category and type tags:
|
||||
Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI.
|
||||
|
||||
[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message
|
||||
Make sure tests pass on both Travis and Circle CI.
|
||||
|
||||
For more details, see:
|
||||
https://reactnative.dev/contributing/changelogs-in-pull-requests
|
||||
-->
|
||||
**Code formatting**
|
||||
|
||||
## Test Plan:
|
||||
Look around. Match the style of the rest of the codebase. See also the simple [style guide](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#style-guide).
|
||||
|
||||
<!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes the user interface. -->
|
||||
For more info, see the ["Pull Requests" section of our "Contributing" guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#pull-requests).
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
<!-- Template for pre-release GitHub release -->
|
||||
|
||||
<!-- TODO Post about this release to https://github.com/reactwg/react-native-releases/discussions) -->
|
||||
|
||||
- <!-- TODO List out notable picks for this patch -->
|
||||
|
||||
---
|
||||
|
||||
To test it, run:
|
||||
|
||||
npx react-native init RN__SHORT_VERSION__ --version __VERSION__
|
||||
|
||||
---
|
||||
|
||||
You can participate in the conversation on the status of this release in the [working group](https://github.com/reactwg/react-native-releases/discussions).
|
||||
|
||||
---
|
||||
|
||||
To help you upgrade to this version, you can use the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) ⚛️
|
||||
|
||||
---
|
||||
|
||||
See changes from this release in the [changelog PR](https://github.com/facebook/react-native/labels/%F0%9F%93%9D%20Changelog)
|
||||
@@ -1,35 +0,0 @@
|
||||
Thanks for using React Native! If you need help with your React Native app, the right place to go depends on the type of help that you need.
|
||||
|
||||
|
||||
## 🤔 I have a question or need help with my React Native app.
|
||||
|
||||
If you have a coding question related to React Native, it might be better suited for Stack Overflow. It's a great place to browse through [frequent questions about using React Native](https://stackoverflow.com/questions/tagged/react-native?sort=frequent&pageSize=15), as well as [ask for help with specific questions](https://stackoverflow.com/questions/tagged/react-native).
|
||||
|
||||
[Reactiflux](https://www.reactiflux.com/) is an active community of React and React Native developers. If you are looking for immediate assistance or have a general question about React Native, the #react-native channel is a good place to start.
|
||||
|
||||
|
||||
## 📃 I found something that seems wrong in the documentation.
|
||||
|
||||
The React Native website is hosted on a [separate repository](https://github.com/facebook/react-native-website). If you want to report something that is wrong or missing from the documentation, [please open a new issue there](https://github.com/facebook/react-native-website/issues).
|
||||
|
||||
|
||||
## 🐛 I found a bug in React Native.
|
||||
|
||||
If you want to report a reproducible bug or regression in the React Native library, you can [create a new issue](https://github.com/facebook/react-native/issues/new?labels=Type%3A+Bug+Report&template=bug_report.md). It's a good idea to look through [open issues](https://github.com/facebook/react-native/issues) before doing so, as someone else may have reported a similar issue.
|
||||
|
||||
|
||||
## 🚀 I want to discuss the future of React Native.
|
||||
|
||||
If you'd like to discuss topics related to the future of React Native, please check out the [React Native Community Discussions and Proposals](https://github.com/react-native-community/discussions-and-proposals) repository.
|
||||
|
||||
|
||||
## 💬 I want to talk to other React Native developers.
|
||||
|
||||
If you want to participate in casual discussions about the use of React Native, consider participating in one of the following forums:
|
||||
|
||||
- [Reactiflux Discord Server](https://www.reactiflux.com)
|
||||
- [Spectrum Chat](https://spectrum.chat/react-native)
|
||||
- [React Native Community Facebook Group](https://www.facebook.com/groups/react.native.community)
|
||||
|
||||
|
||||
> For a full list of community resources, check out [React Native's Community page](https://reactnative.dev/help).
|
||||
@@ -1,88 +0,0 @@
|
||||
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
|
||||
@@ -1,45 +0,0 @@
|
||||
name: create_release
|
||||
description: Creates a new React Native release
|
||||
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:
|
||||
description: "Whether we want to tag this release as latest on NPM"
|
||||
required: true
|
||||
default: "false"
|
||||
dry_run:
|
||||
description: "Whether the job should be executed in dry-run mode or not"
|
||||
default: "false"
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Yarn install
|
||||
shell: bash
|
||||
run: yarn install --non-interactive
|
||||
- name: Configure Git
|
||||
shell: bash
|
||||
run: |
|
||||
git config --local user.email "bot@reactnative.dev"
|
||||
git config --local user.name "React Native Bot"
|
||||
- name: Creating release commit
|
||||
shell: bash
|
||||
run: |
|
||||
node scripts/releases/create-release-commit.js \
|
||||
--reactNativeVersion "${{ inputs.version }}" \
|
||||
--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' }}
|
||||
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' }}
|
||||
run: |
|
||||
CURR_BRANCH="$(git branch --show-current)"
|
||||
git push origin "$CURR_BRANCH" --follow-tags
|
||||
@@ -1,104 +0,0 @@
|
||||
name: prepare-hermes-workspace
|
||||
description: This action prepares the hermes workspace with the right hermes and react-native versions.
|
||||
inputs:
|
||||
HERMES_WS_DIR:
|
||||
required: true
|
||||
description: The hermes dir we need to use to setup the workspace
|
||||
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
|
||||
value: ${{ steps.hermes-version.outputs.VERSION }}
|
||||
react-native-version:
|
||||
description: the version of React Native tied to this run
|
||||
value: ${{ steps.react-native-version.outputs.VERSION }}
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Setup hermes version
|
||||
shell: bash
|
||||
id: hermes-version
|
||||
run: |
|
||||
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:"
|
||||
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:"
|
||||
HERMES_TAG_SHA=$(git ls-remote https://github.com/facebook/hermes main | cut -f 1 | tr -d '[:space:]')
|
||||
echo "VERSION=$HERMES_TAG_SHA" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
echo "Hermes commit is $HERMES_TAG_SHA"
|
||||
|
||||
- name: Get react-native version
|
||||
shell: bash
|
||||
id: react-native-version
|
||||
run: |
|
||||
VERSION=$(cat packages/react-native/package.json | jq -r '.version')
|
||||
# Save the react native version we are building in an output variable so we can use that file as part of the cache key.
|
||||
echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "React Native Version is $VERSION"
|
||||
|
||||
- name: Cache hermes workspace
|
||||
id: restore-hermes
|
||||
uses: actions/cache/restore@v4.0.0
|
||||
with:
|
||||
path: |
|
||||
/tmp/hermes/download/
|
||||
/tmp/hermes/hermes/
|
||||
key: v1-hermes-${{ steps.hermes-version.outputs.version }}
|
||||
enableCrossOsArchive: true
|
||||
|
||||
# It happened while testing that a cache was created from the right folders
|
||||
# but those folders where empty. Thus, the next check ensures that we can work with those caches.
|
||||
- name: Check if cache was meaningful
|
||||
id: meaningful-cache
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ -d /tmp/hermes/hermes ]] && [[ -n "$(ls -A /tmp/hermes/hermes)" ]]; then
|
||||
echo "Found a good hermes cache"
|
||||
echo "HERMES_CACHED=true" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Yarn- Install Dependencies
|
||||
if: ${{ steps.meaningful-cache.outputs.HERMES_CACHED != 'true' }}
|
||||
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/* $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.1
|
||||
with:
|
||||
name: hermes-workspace
|
||||
path: |
|
||||
/tmp/hermes/download/
|
||||
/tmp/hermes/hermes/
|
||||
|
||||
- name: Cache hermes workspace
|
||||
uses: actions/cache/save@v4.0.0
|
||||
if: ${{ github.ref == 'refs/heads/main' }} # To avoid that the cache explode.
|
||||
with:
|
||||
path: |
|
||||
/tmp/hermes/download/
|
||||
/tmp/hermes/hermes/
|
||||
key: v1-hermes-${{ steps.hermes-version.outputs.version }}
|
||||
enableCrossOsArchive: true
|
||||
@@ -1,25 +0,0 @@
|
||||
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: |
|
||||
cd packages/react-native/scripts
|
||||
sh run_ruby_tests.sh
|
||||
- name: Boot iPhone Simulator
|
||||
shell: bash
|
||||
run: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true
|
||||
- name: "Brew: Tap wix/brew"
|
||||
shell: bash
|
||||
run: brew tap wix/brew
|
||||
- name: brew install applesimutils watchman
|
||||
shell: bash
|
||||
run: brew install applesimutils watchman
|
||||
- name: Configure Watchman
|
||||
shell: bash
|
||||
run: echo "{}" > .watchmanconfig
|
||||
@@ -1,12 +0,0 @@
|
||||
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
|
||||
@@ -1,16 +0,0 @@
|
||||
name: restore-hermes-workspace
|
||||
description: "Restore hermes workspace that has been created in Prepare Hermes Workspace"
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Download Previous Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: hermes-workspace
|
||||
path: /tmp/hermes
|
||||
- name: Set up workspace
|
||||
shell: bash
|
||||
run: |
|
||||
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/.
|
||||
@@ -1,17 +0,0 @@
|
||||
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,9 +0,0 @@
|
||||
name: Setup gradle
|
||||
description: "Set up your GitHub Actions workflow with a specific version of gradle"
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Setup gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
gradle-version: wrapper
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Setup node.js
|
||||
description: 'Set up your GitHub Actions workflow with a specific version of node.js'
|
||||
inputs:
|
||||
node-version:
|
||||
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.0.0
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
cache: ${{ inputs.cache }}
|
||||
@@ -1,14 +0,0 @@
|
||||
name: Setup xcode
|
||||
description: 'Set up your GitHub Actions workflow with a specific version of xcode'
|
||||
inputs:
|
||||
xcode-version:
|
||||
description: 'The xcode version to use'
|
||||
required: false
|
||||
default: '15.2'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Setup xcode
|
||||
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd
|
||||
with:
|
||||
xcode-version: ${{ inputs.xcode-version }}
|
||||
@@ -1,28 +0,0 @@
|
||||
name: setup_xcode_build_cache
|
||||
description: Add caching to iOS jobs to speed up builds
|
||||
inputs:
|
||||
hermes-version:
|
||||
description: The version of hermes
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: See commands.yml with_xcodebuild_cache
|
||||
shell: bash
|
||||
run: echo "See commands.yml with_xcodebuild_cache"
|
||||
- name: Prepare Xcodebuild cache
|
||||
shell: bash
|
||||
run: |
|
||||
WEEK=$(date +"%U")
|
||||
YEAR=$(date +"%Y")
|
||||
echo "$WEEK-$YEAR" > /tmp/week_year
|
||||
- name: Cache podfile lock
|
||||
uses: actions/cache@v4.0.0
|
||||
with:
|
||||
path: packages/rn-tester/Podfile.lock
|
||||
key: v9-podfilelock-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile') }}-{{ hashfiles('/tmp/week_year') }}-${{ inputs.hermes-version}}
|
||||
- name: Cache cocoapods
|
||||
uses: actions/cache@v4.0.0
|
||||
with:
|
||||
path: packages/rn-tester/Pods
|
||||
key: v11-cocoapods-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile.lock') }}-{{ hashfiles('packages/rn-tester/Podfile') }}-${{ inputs.hermes-version}}
|
||||
@@ -1,110 +0,0 @@
|
||||
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"
|
||||
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
|
||||
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
|
||||
react-native-version:
|
||||
description: The version of react-native
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup xcode
|
||||
uses: ./.github/actions/setup-xcode
|
||||
- name: Setup node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Create Hermes folder
|
||||
shell: bash
|
||||
run: mkdir -p "$HERMES_WS_DIR"
|
||||
- name: Download Hermes
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: hermes-darwin-bin-${{ inputs.flavor }}
|
||||
path: /tmp/hermes/hermes-runtime-darwin/
|
||||
- name: Print Downloaded hermes
|
||||
shell: bash
|
||||
run: ls -lR "$HERMES_WS_DIR"
|
||||
- name: Run yarn
|
||||
shell: bash
|
||||
run: yarn install --non-interactive
|
||||
- name: Setup ruby
|
||||
uses: ruby/setup-ruby@v1.170.0
|
||||
with:
|
||||
ruby-version: ${{ inputs.ruby-version }}
|
||||
- name: Install iOS dependencies - Configuration ${{ inputs.flavor }}; New Architecture ${{ inputs.architecture }}; JS Engine ${{ inputs.jsengine }}
|
||||
shell: bash
|
||||
run: |
|
||||
cd packages/helloworld
|
||||
args=()
|
||||
|
||||
if [[ ${{ inputs.architecture }} == "OldArch" ]]; then
|
||||
args+=(--arch old)
|
||||
fi
|
||||
|
||||
if [[ ${{ inputs.use-frameworks }} == "DynamicFrameworks" ]]; then
|
||||
args+=(--frameworks dynamic)
|
||||
fi
|
||||
|
||||
if [[ ${{ inputs.jsengine }} == "JSC" ]]; then
|
||||
args+=(--jsvm jsc)
|
||||
yarn bootstrap ios "${args[@]}" | cat
|
||||
else
|
||||
# Tarball is restored with capital flavors suffix, but somehow the tarball name from JS at line 96 returns as lowercased.
|
||||
# Let's ensure that the tarballs have the right names
|
||||
|
||||
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
|
||||
|
||||
BUILD_TYPE="${{ inputs.flavor }}"
|
||||
TARBALL_FILENAME=$(node ../react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
|
||||
HERMES_PATH="$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME"
|
||||
HERMES_ENGINE_TARBALL_PATH="$HERMES_PATH" yarn bootstrap ios "${args[@]}" | cat
|
||||
fi
|
||||
- name: Build HelloWorld project
|
||||
shell: bash
|
||||
run: |
|
||||
cd packages/helloworld
|
||||
|
||||
args=()
|
||||
if [[ ${{ inputs.flavor }} == "Release" ]]; then
|
||||
args+=(--prod)
|
||||
fi
|
||||
yarn build ios "${args[@]}" | cat
|
||||
yarn bundle ios "${args[@]}" | cat
|
||||
@@ -1,152 +0,0 @@
|
||||
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
|
||||
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
|
||||
ruby-version:
|
||||
description: The version of ruby that must be used
|
||||
default: 2.6.10
|
||||
run-unit-tests:
|
||||
description: whether unit tests should run or not.
|
||||
default: false
|
||||
hermes-tarball-artifacts-dir:
|
||||
description: The directory where the hermes tarball artifacts are stored
|
||||
default: /tmp/hermes/hermes-runtime-darwin
|
||||
flavor:
|
||||
description: The flavor of the build. Must be one of "Debug", "Release".
|
||||
default: Debug
|
||||
hermes-version:
|
||||
description: The version of hermes
|
||||
required: true
|
||||
react-native-version:
|
||||
description: The version of react-native
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup xcode
|
||||
uses: ./.github/actions/setup-xcode
|
||||
- name: Setup node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Run yarn
|
||||
shell: bash
|
||||
run: yarn install --non-interactive
|
||||
- name: Download Hermes
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: hermes-darwin-bin-${{ inputs.flavor }}
|
||||
path: ${{ inputs.hermes-tarball-artifacts-dir }}
|
||||
- name: Setup ruby
|
||||
uses: ruby/setup-ruby@v1.170.0
|
||||
with:
|
||||
ruby-version: ${{ inputs.ruby-version }}
|
||||
- name: 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: |
|
||||
HERMES_TARBALL_ARTIFACTS_DIR=${{ inputs.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
|
||||
|
||||
TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "${{ inputs.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 "HERMES_ENGINE_TARBALL_PATH=$TARBALL_PATH" >> $GITHUB_ENV
|
||||
- name: Print Hermes version
|
||||
shell: bash
|
||||
run: |
|
||||
HERMES_TARBALL_ARTIFACTS_DIR=${{ inputs.hermes-tarball-artifacts-dir }}
|
||||
TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "${{ inputs.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
|
||||
chmod +x ./destroot/bin/hermes
|
||||
./destroot/bin/hermes test.js
|
||||
rm test.js
|
||||
rm -rf destroot
|
||||
else
|
||||
echo 'No Hermes tarball found.'
|
||||
fi
|
||||
- name: Setup xcode build cache
|
||||
uses: ./.github/actions/setup_xcode_build_cache
|
||||
with:
|
||||
hermes-version: ${{ inputs.hermes-version }}
|
||||
- name: Install CocoaPods dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ ${{ inputs.jsengine }} == "JSC" ]]; then
|
||||
export USE_HERMES=0
|
||||
else
|
||||
export HERMES_ENGINE_TARBALL_PATH=$HERMES_ENGINE_TARBALL_PATH
|
||||
fi
|
||||
|
||||
if [[ ${{ inputs.use-frameworks }} == "DynamicFrameworks" ]]; then
|
||||
export USE_FRAMEWORKS=dynamic
|
||||
fi
|
||||
|
||||
if [[ ${{ inputs.architecture }} == "NewArch" ]]; then
|
||||
export RCT_NEW_ARCH_ENABLED=1
|
||||
fi
|
||||
|
||||
cd packages/rn-tester
|
||||
|
||||
bundle install
|
||||
bundle exec pod install
|
||||
- name: Build RNTester
|
||||
if: ${{ inputs.run-unit-tests != true }}
|
||||
shell: bash
|
||||
run: |
|
||||
xcodebuild build \
|
||||
-workspace packages/rn-tester/RNTesterPods.xcworkspace \
|
||||
-scheme RNTester \
|
||||
-sdk iphonesimulator
|
||||
- name: "Run Tests: iOS Unit and Integration Tests"
|
||||
if: ${{ inputs.run-unit-tests == true }}
|
||||
shell: bash
|
||||
run: yarn test-ios
|
||||
- name: Zip Derived data folder
|
||||
if: ${{ inputs.run-unit-tests == true }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "zipping tests results"
|
||||
cd /Users/distiller/Library/Developer/Xcode
|
||||
XCRESULT_PATH=$(find . -name '*.xcresult')
|
||||
tar -zcvf xcresults.tar.gz $XCRESULT_PATH
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
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.1
|
||||
with:
|
||||
name: test-results
|
||||
path: ./reports/junit
|
||||
@@ -1,148 +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
|
||||
*/
|
||||
|
||||
module.exports = async (github, context, labelWithContext) => {
|
||||
const closeIssue = async () => {
|
||||
await github.rest.issues.update({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'closed',
|
||||
});
|
||||
};
|
||||
|
||||
const addComment = async comment => {
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment,
|
||||
});
|
||||
};
|
||||
|
||||
const requestAuthorFeedback = async () => {
|
||||
// Remove the triage label if it exists (ignore the 404 if not; it's not expected to always be there)
|
||||
try {
|
||||
await github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: 'Needs: Triage :mag:',
|
||||
});
|
||||
} catch {}
|
||||
|
||||
await github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Needs: Author Feedback'],
|
||||
});
|
||||
};
|
||||
|
||||
switch (labelWithContext.label) {
|
||||
case 'Type: Invalid':
|
||||
await addComment(
|
||||
`| :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(
|
||||
`| :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(
|
||||
`| :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(
|
||||
`| :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: | 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: | 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(
|
||||
`| :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: | 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: | 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: | 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(
|
||||
`| :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;
|
||||
default:
|
||||
// No action needed
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -1,153 +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
|
||||
*/
|
||||
|
||||
module.exports = async (github, context) => {
|
||||
const issue = context.payload.issue;
|
||||
const title = issue?.title?.toLowerCase();
|
||||
if (!title) return;
|
||||
|
||||
const addLabels = async labelsToAdd => {
|
||||
await github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: labelsToAdd,
|
||||
});
|
||||
};
|
||||
|
||||
const labelsToAdd = [];
|
||||
for (const component of components) {
|
||||
if (title.includes(component.toLowerCase())) {
|
||||
labelsToAdd.push(`Component: ${component}`);
|
||||
}
|
||||
}
|
||||
for (const api of apis) {
|
||||
if (title.includes(api.toLowerCase())) {
|
||||
labelsToAdd.push(`API: ${api}`);
|
||||
}
|
||||
}
|
||||
for (const topic of Object.keys(topics)) {
|
||||
if (title.includes(topic.toLowerCase())) {
|
||||
labelsToAdd.push(topics[topic]);
|
||||
}
|
||||
}
|
||||
if (labelsToAdd.length > 0) {
|
||||
await addLabels(labelsToAdd);
|
||||
}
|
||||
};
|
||||
|
||||
const labelAndroid = 'Platform: Android';
|
||||
const labelIos = 'Platform: iOS';
|
||||
const labelTvos = 'Platform: tvOS';
|
||||
const labelNetworking = '🌐Networking';
|
||||
const labelBundler = '📦Bundler';
|
||||
const labelCli = '💻CLI';
|
||||
const labelRegression = 'Impact: Regression';
|
||||
|
||||
const components = [
|
||||
'ActivityIndicator',
|
||||
'Button',
|
||||
'DatePickerIOS',
|
||||
'DrawerLayoutAndroid',
|
||||
'FlatList',
|
||||
'Image',
|
||||
'ImageBackground',
|
||||
'InputAccessoryView',
|
||||
'KeyboardAvoidingView',
|
||||
'ListView',
|
||||
'MaskedViewIOS',
|
||||
'Modal',
|
||||
'NavigatorIOS',
|
||||
'Picker',
|
||||
'PickerIOS',
|
||||
'ProgressBarAndroid',
|
||||
'ProgressViewIOS',
|
||||
'RefreshControl',
|
||||
'SafeAreaView',
|
||||
'ScrollView',
|
||||
'SectionList',
|
||||
'SegmentedControlIOS',
|
||||
'Slider',
|
||||
'SnapshotViewIOS',
|
||||
'StatusBar',
|
||||
'Switch',
|
||||
'TabBarIOS',
|
||||
'TextInput',
|
||||
'ToolbarAndroid',
|
||||
'TouchableHighlight',
|
||||
'TouchableNativeFeedback',
|
||||
'TouchableOpacity',
|
||||
'TouchableWithoutFeedback',
|
||||
'ViewPagerAndroid',
|
||||
'VirtualizedList',
|
||||
'WebView',
|
||||
];
|
||||
|
||||
const apis = [
|
||||
'AccessibilityInfo',
|
||||
'ActionSheetIOS',
|
||||
'Alert',
|
||||
'AlertIOS',
|
||||
'Animated',
|
||||
'AppRegistry',
|
||||
'AppState',
|
||||
'AsyncStorage',
|
||||
'BackAndroid',
|
||||
'BackHandler',
|
||||
'CameraRoll',
|
||||
'Clipboard',
|
||||
'DatePickerAndroid',
|
||||
'Dimensions',
|
||||
'Easing',
|
||||
'Geolocation',
|
||||
'ImageEditor',
|
||||
'ImagePickerIOS',
|
||||
'ImageStore',
|
||||
'InteractionManager',
|
||||
'Keyboard',
|
||||
'LayoutAnimation',
|
||||
'Linking',
|
||||
'ListViewDataSource',
|
||||
'NetInfo',
|
||||
'PanResponder',
|
||||
'PermissionsAndroid',
|
||||
'PixelRatio',
|
||||
'PushNotificationIOS',
|
||||
'Settings',
|
||||
'Share',
|
||||
'StatusBarIOS',
|
||||
'StyleSheet',
|
||||
'Systrace',
|
||||
'TimePickerAndroid',
|
||||
'ToastAndroid',
|
||||
'Transforms',
|
||||
'Vibration',
|
||||
'VibrationIOS',
|
||||
];
|
||||
|
||||
const topics = {
|
||||
Flow: 'Flow',
|
||||
'Flow-Strict': 'Flow',
|
||||
xhr: labelNetworking,
|
||||
netinfo: labelNetworking,
|
||||
fetch: labelNetworking,
|
||||
okhttp: labelNetworking,
|
||||
http: labelNetworking,
|
||||
bundle: labelBundler,
|
||||
bundling: labelBundler,
|
||||
packager: labelBundler,
|
||||
'unable to resolve module': labelBundler,
|
||||
android: labelAndroid,
|
||||
ios: labelIos,
|
||||
tvos: labelTvos,
|
||||
'react-native-cli': labelCli,
|
||||
'react-native upgrade': labelCli,
|
||||
'react-native link': labelCli,
|
||||
regression: labelRegression,
|
||||
};
|
||||
@@ -1,124 +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 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) => {
|
||||
const issueData = {
|
||||
issue_number: context.payload.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
};
|
||||
|
||||
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;
|
||||
if (isDateBefore(issueDate, SKIP_ISSUES_OLDER_THAN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const maintainerChangedLabel = await hasMaintainerChangedLabel(
|
||||
github,
|
||||
issueData,
|
||||
author,
|
||||
);
|
||||
|
||||
if (maintainerChangedLabel) {
|
||||
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
|
||||
const hasValidReproducer = entities.some(entity => {
|
||||
const hasExpoSnackLink = containsPattern(
|
||||
entity.body,
|
||||
`https?:\\/\\/snack\\.expo\\.dev\\/[^\\s)\\]]+`,
|
||||
);
|
||||
|
||||
const hasGithubRepoLink = containsPattern(
|
||||
entity.body,
|
||||
`https?:\\/\\/github\\.com\\/(${entity.user.login})\\/[^/]+\\/?\\s?`,
|
||||
);
|
||||
return hasExpoSnackLink || hasGithubRepoLink;
|
||||
});
|
||||
|
||||
if (hasValidReproducer) {
|
||||
try {
|
||||
await github.rest.issues.removeLabel({
|
||||
...issueData,
|
||||
name: NEEDS_REPRO_LABEL,
|
||||
});
|
||||
} catch (error) {
|
||||
if (!/Label does not exist/.test(error.message)) {
|
||||
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,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function containsPattern(body, pattern) {
|
||||
const regexp = new RegExp(pattern, 'gm');
|
||||
return body.search(regexp) !== -1;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
const labeledEvents = timeline.data.filter(
|
||||
event => event.event === 'labeled' || event.event === 'unlabeled',
|
||||
);
|
||||
const userEvents = labeledEvents.filter(event => event.actor.type !== 'Bot');
|
||||
|
||||
return userEvents.some(
|
||||
event =>
|
||||
event.actor.login !== author && event.label.name === NEEDS_REPRO_LABEL,
|
||||
);
|
||||
}
|
||||
|
||||
function isDateBefore(firstDate, secondDate) {
|
||||
const date1 = new Date(firstDate);
|
||||
const date2 = new Date(secondDate);
|
||||
|
||||
return date1.getTime() < date2.getTime();
|
||||
}
|
||||
@@ -1,145 +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
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
// Nightly versions are always supported
|
||||
if (reportedVersionIsNightly(issueVersionUnparsed, issueVersion)) return;
|
||||
|
||||
if (!issueVersion) {
|
||||
return {label: 'Needs: Version Info'};
|
||||
}
|
||||
|
||||
// Ensure the version matches one we support
|
||||
const recentReleases = (
|
||||
await github.rest.repos.listReleases({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
).data.map(release => release.name);
|
||||
|
||||
const latestRelease = (
|
||||
await github.rest.repos.getLatestRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
).data;
|
||||
const latestVersion = parseVersionFromString(latestRelease.name);
|
||||
|
||||
// We want to "insta-close" an issue if RN version provided is too old. And encourage users to upgrade.
|
||||
if (isVersionTooOld(issueVersion, latestVersion)) {
|
||||
return {label: 'Type: Too Old Version'};
|
||||
}
|
||||
|
||||
if (!isVersionSupported(issueVersion, latestVersion)) {
|
||||
return {label: 'Type: Unsupported Version'};
|
||||
}
|
||||
|
||||
// We want to encourage users to repro the issue on the highest available patch for the given minor.
|
||||
const latestPatchForVersion = getLatestPatchForVersion(
|
||||
issueVersion,
|
||||
recentReleases,
|
||||
);
|
||||
if (latestPatchForVersion > issueVersion.patch) {
|
||||
return {
|
||||
label: 'Newer Patch Available',
|
||||
newestPatch: `${issueVersion.major}.${issueVersion.minor}.${latestPatchForVersion}`,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the RN version provided in an issue is supported.
|
||||
*
|
||||
* "We support `N-2` minor versions, and the `latest` major".
|
||||
*/
|
||||
function isVersionSupported(actualVersion, latestVersion) {
|
||||
return (
|
||||
actualVersion.major >= latestVersion.major &&
|
||||
actualVersion.minor >= latestVersion.minor - 2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the RN version provided in an issue is too old.
|
||||
* "We support `N-2` minor versions, and the `latest` major".
|
||||
*
|
||||
* A RN version is *too old* if it's:
|
||||
* - `1` or more *major* behind the *latest major*.
|
||||
* - `5` or more *minor* behind the *latest minor* in the *same major*. Less aggressive.
|
||||
* (e.g. If `0.72.0` is the current latest then `0.67.0` and lower is too old for `0.72.0`)
|
||||
*/
|
||||
function isVersionTooOld(actualVersion, latestVersion) {
|
||||
return (
|
||||
latestVersion.major - actualVersion.major >= 1 ||
|
||||
latestVersion.minor - actualVersion.minor >= 5
|
||||
);
|
||||
}
|
||||
|
||||
// Assumes that releases are sorted in the order of recency (i.e. most recent releases are earlier in the list)
|
||||
// This enables us to stop looking as soon as we find the first release with a matching major/minor version, since
|
||||
// we know it's the most recent release, therefore the highest patch available.
|
||||
function getLatestPatchForVersion(version, releases) {
|
||||
for (releaseName of releases) {
|
||||
const release = parseVersionFromString(releaseName);
|
||||
if (
|
||||
release &&
|
||||
release.major == version.major &&
|
||||
release.minor == version.minor
|
||||
) {
|
||||
return release.patch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getReactNativeVersionFromIssueBodyIfExists(issue) {
|
||||
if (!issue || !issue.body) return;
|
||||
const rnVersionRegex = /React Native Version[\r\n]+(?<version>.+)[\r\n]*/;
|
||||
const rnVersionMatch = issue.body.match(rnVersionRegex);
|
||||
if (!rnVersionMatch || !rnVersionMatch.groups.version) return;
|
||||
return rnVersionMatch.groups.version;
|
||||
}
|
||||
|
||||
function reportedVersionIsNightly(unparsedVersionString, version) {
|
||||
if (!unparsedVersionString && !version) return false;
|
||||
const nightlyRegex = /nightly/i;
|
||||
const nightlyMatch = unparsedVersionString.match(nightlyRegex);
|
||||
const versionIsNightly = nightlyMatch && nightlyMatch[0];
|
||||
|
||||
const versionIsZero =
|
||||
version && version.major == 0 && version.minor == 0 && version.patch == 0;
|
||||
|
||||
return versionIsZero || versionIsNightly;
|
||||
}
|
||||
|
||||
function parseVersionFromString(version) {
|
||||
if (!version) return;
|
||||
// This will match the standard x.x.x semver format, as well as the non-standard prerelease x.x.x-rc.x
|
||||
const semverRegex =
|
||||
/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(-[rR]{1}[cC]{1}\.(?<prerelease>\d+))?/;
|
||||
const versionMatch = version.match(semverRegex);
|
||||
if (!versionMatch) return;
|
||||
const {major, minor, patch, prerelease} = versionMatch.groups;
|
||||
return {
|
||||
major: parseInt(major),
|
||||
minor: parseInt(minor),
|
||||
patch: parseInt(patch),
|
||||
prerelease: parseInt(prerelease),
|
||||
};
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
name: Automatic Rebase
|
||||
# This workflow is used to automatically rebase a PR when a comment is made
|
||||
# containing the text "/rebase". It uses the cirrus-actions/rebase action.
|
||||
# See https://github.com/cirrus-actions/rebase
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
rebase:
|
||||
name: Rebase
|
||||
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, '/rebase')
|
||||
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: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@1.8
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Check for reproducer
|
||||
# This workflow is triggered when issue is created or edited.
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
check-for-reproducer:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.repository == 'facebook/react-native' && github.event.issue.pull_request == null && github.event.issue.state == 'open' && !contains(github.event.issue.labels.*.name, ':open_umbrella: Umbrella')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const checkForReproducer = require('./.github/workflow-scripts/checkForReproducer.js')
|
||||
await checkForReproducer(github, context)
|
||||
@@ -1,63 +0,0 @@
|
||||
name: Label closed PR as merged and leave a comment
|
||||
on:
|
||||
push
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment-and-label:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
if(!context.payload.commits || !context.payload.commits.length) return;
|
||||
const sha = context.payload.commits[0].id;
|
||||
|
||||
const {commit, author} = (await github.rest.repos.getCommit({
|
||||
ref: sha,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})).data;
|
||||
|
||||
// Looking at the commit message, checks which PR number, if any, was closed by this commit
|
||||
const getClosedPrIfExists = (commit) => {
|
||||
if(!commit || !commit.message) return;
|
||||
const prClosingRegex = /Closes https:\/\/github.com\/facebook\/react-native\/pull\/([0-9]+)|Pull Request resolved: https:\/\/github.com\/facebook\/react-native\/pull\/([0-9]+)/;
|
||||
const prClosingMatch = commit.message.match(prClosingRegex);
|
||||
if(!prClosingMatch || (!prClosingMatch[1] && ! prClosingMatch[2])) return;
|
||||
return prClosingMatch[1] ?? prClosingMatch[2];
|
||||
};
|
||||
|
||||
const closedPrNumber = getClosedPrIfExists(commit);
|
||||
if(!closedPrNumber) return;
|
||||
|
||||
const pr = (await github.rest.pulls.get({
|
||||
pull_number: closedPrNumber,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})).data;
|
||||
|
||||
const authorName = author?.login ? `@${author.login}` : commit.author.name;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
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>`
|
||||
});
|
||||
|
||||
// If the PR has already been processed (labeled as Merged), skip it
|
||||
const mergedLabel = "Merged";
|
||||
if(pr.labels && pr.labels.some(label => label.name === mergedLabel)) return;
|
||||
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: closedPrNumber,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: [mergedLabel]
|
||||
});
|
||||
@@ -1,56 +0,0 @@
|
||||
name: Create release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
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'
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
dry_run:
|
||||
description: 'Whether the job should be executed in dry-run mode or not'
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
with:
|
||||
token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
|
||||
fetch-tags: 'true'
|
||||
fetch-depth: 0
|
||||
- name: Check if on stable branch
|
||||
id: check_stable_branch
|
||||
run: |
|
||||
BRANCH="$(git branch --show-current)"
|
||||
PATTERN='^0\.[0-9]+-stable$'
|
||||
if [[ $BRANCH =~ $PATTERN ]]; then
|
||||
echo "On a stable branch"
|
||||
echo "ON_STABLE_BRANCH=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Print output
|
||||
run: echo "ON_STABLE_BRANCH ${{steps.check_stable_branch.outputs.ON_STABLE_BRANCH}}"
|
||||
- name: Check if tag already exists
|
||||
id: check_if_tag_exists
|
||||
run: |
|
||||
TAG="v${{ inputs.version }}"
|
||||
TAG_EXISTS=$(git tag -l "$TAG")
|
||||
if [[ -n "$TAG_EXISTS" ]]; then
|
||||
echo "Version tag already exists!"
|
||||
echo "TAG_EXISTS=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Execute Prepare Release
|
||||
if: ${{ steps.check_stable_branch.outputs.ON_STABLE_BRANCH && !steps.check_if_tag_exists.outputs.TAG_EXISTS }}
|
||||
uses: ./.github/actions/create-release
|
||||
with:
|
||||
version: ${{ inputs.version }}
|
||||
is_latest_on_npm: ${{ inputs.is_latest_on_npm }}
|
||||
dry_run: ${{ inputs.dry_run }}
|
||||
@@ -1,28 +0,0 @@
|
||||
name: Run Danger on PR
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
checks: write
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
statuses: write
|
||||
|
||||
jobs:
|
||||
danger:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run Yarn Install on Root
|
||||
run: yarn install
|
||||
working-directory: .
|
||||
- name: Danger
|
||||
run: yarn danger ci --use-github-checks --failOnErrors
|
||||
working-directory: packages/react-native-bots
|
||||
env:
|
||||
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,13 +0,0 @@
|
||||
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
|
||||
@@ -1,28 +0,0 @@
|
||||
name: Issue Needs Attention
|
||||
# This workflow is triggered on issue comments.
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
applyNeedsAttentionLabel:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
issues: write # for react-native-community/needs-attention to label issues
|
||||
name: Apply Needs Attention Label
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Apply Needs Attention Label
|
||||
uses: react-native-community/needs-attention@v2.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
response-required-label: "Needs: Author Feedback"
|
||||
needs-attention-label: "Needs: Attention"
|
||||
id: needs-attention
|
||||
- name: Result
|
||||
run: echo '${{ steps.needs-attention.outputs.result }}'
|
||||
@@ -1,716 +0,0 @@
|
||||
name: Nightly
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# nightly build @ 2:15 AM UTC
|
||||
schedule:
|
||||
- cron: '15 2 * * *'
|
||||
|
||||
|
||||
jobs:
|
||||
set_release_type:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
outputs:
|
||||
RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }}
|
||||
env:
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
REF: ${{ github.ref }}
|
||||
steps:
|
||||
- id: set_release_type
|
||||
run: |
|
||||
echo "Setting release type to nightly"
|
||||
echo "RELEASE_TYPE=nightly" >> $GITHUB_OUTPUT
|
||||
|
||||
prepare_hermes_workspace:
|
||||
runs-on: ubuntu-latest
|
||||
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.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 }}
|
||||
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.1.1
|
||||
- name: Restore Hermes workspace
|
||||
uses: ./.github/actions/restore-hermes-workspace
|
||||
- name: Hermes apple cache
|
||||
uses: actions/cache/restore@v4.0.0
|
||||
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 }}
|
||||
- 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]
|
||||
env:
|
||||
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: "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, catalyst, xros, xrsimulator]
|
||||
steps:
|
||||
- name: Checkout
|
||||
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:
|
||||
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: v5-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: Compress slices to preserve Symlinks
|
||||
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 (${{ 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 }}.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.0.0
|
||||
with:
|
||||
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
|
||||
key: v5-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
|
||||
needs: [build_apple_slices_hermes, prepare_hermes_workspace]
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flavor: [Debug, Release]
|
||||
steps:
|
||||
- name: Checkout
|
||||
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:
|
||||
key: v3-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
|
||||
- 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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
name: slice-xrsimulator-${{ matrix.flavor }}
|
||||
- name: Unzip slices
|
||||
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_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' }}
|
||||
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: v3-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
|
||||
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.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:
|
||||
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.1
|
||||
with:
|
||||
name: hermes-linux-bin
|
||||
path: /tmp/hermes/linux64-bin
|
||||
|
||||
build_hermesc_windows:
|
||||
runs-on: windows-2019
|
||||
needs: prepare_hermes_workspace
|
||||
env:
|
||||
HERMES_WS_DIR: 'D:\tmp\hermes'
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: 'D:\tmp\hermes\hermes-runtime-darwin'
|
||||
HERMES_OSXBIN_ARTIFACTS_DIR: 'D:\tmp\hermes\osx-bin'
|
||||
ICU_URL: "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip"
|
||||
MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin'
|
||||
CMAKE_DIR: 'C:\Program Files\CMake\bin'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- name: Download Previous Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
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)) {
|
||||
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.1
|
||||
with:
|
||||
name: hermes-win64-bin
|
||||
path: D:\tmp\hermes\win64-bin\
|
||||
|
||||
build_android:
|
||||
runs-on: 8-core-ubuntu
|
||||
needs: [set_release_type]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
env:
|
||||
TERM: "dumb"
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
steps:
|
||||
- name: Checkout
|
||||
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.1
|
||||
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
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
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]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
env:
|
||||
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: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }}
|
||||
PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }}
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
env:
|
||||
GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }}
|
||||
ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
|
||||
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.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:
|
||||
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 }}\" }}"
|
||||
@@ -1,57 +0,0 @@
|
||||
name: On Issue Labeled
|
||||
# This workflow is triggered when a label is added to an issue.
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
# Runs automatic checks on issues labeled with "Needs: Triage",
|
||||
# then invokes actOnLabel to react to any added labels
|
||||
triage-issue:
|
||||
runs-on: ubuntu-latest
|
||||
if: "${{ github.repository == 'facebook/react-native' && contains(github.event.label.name, 'Needs: Triage :mag:') }}"
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Verify RN version
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const verifyVersion = require('./.github/workflow-scripts/verifyVersion.js')
|
||||
const labelWithContext = await verifyVersion(github, context);
|
||||
|
||||
if(labelWithContext && labelWithContext.label) {
|
||||
await github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: [labelWithContext.label]
|
||||
})
|
||||
|
||||
const actOnLabel = require('./.github/workflow-scripts/actOnLabel.js')
|
||||
await actOnLabel(github, context, labelWithContext)
|
||||
}
|
||||
|
||||
- name: Add descriptive label
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const addDescriptiveLabel = require('./.github/workflow-scripts/addDescriptiveLabels.js')
|
||||
await addDescriptiveLabel(github, context);
|
||||
|
||||
# Reacts to the label that triggered this workflow (added manually or via other workflows)
|
||||
act-on-label:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const actOnLabel = require('./.github/workflow-scripts/actOnLabel.js')
|
||||
await actOnLabel(github, context, {label: context.payload.label.name})
|
||||
@@ -1,26 +0,0 @@
|
||||
name: Publish Bumped Packages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "*-stable"
|
||||
|
||||
jobs:
|
||||
publish_bumped_packages:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- name: Setup node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Run Yarn Install
|
||||
run: yarn install
|
||||
- name: Build packages
|
||||
run: yarn build
|
||||
- name: Set NPM auth token
|
||||
run: echo "//registry.npmjs.org/:_authToken=$GHA_NPM_TOKEN" > ~/.npmrc
|
||||
- name: Find and publish all bumped packages
|
||||
run: node ./scripts/releases-ci/publish-updated-packages.js
|
||||
@@ -1,762 +0,0 @@
|
||||
name: Publish Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "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
|
||||
if: github.repository == 'facebook/react-native'
|
||||
outputs:
|
||||
RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }}
|
||||
env:
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
REF: ${{ github.ref }}
|
||||
steps:
|
||||
- id: set_release_type
|
||||
run: |
|
||||
echo "Setting release type to release"
|
||||
echo "RELEASE_TYPE=release" >> $GITHUB_OUTPUT
|
||||
|
||||
prepare_hermes_workspace:
|
||||
runs-on: ubuntu-latest
|
||||
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.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 }}
|
||||
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.1.1
|
||||
- name: Restore Hermes workspace
|
||||
uses: ./.github/actions/restore-hermes-workspace
|
||||
- name: Hermes apple cache
|
||||
uses: actions/cache/restore@v4.0.0
|
||||
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 }}
|
||||
- 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]
|
||||
env:
|
||||
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: "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, catalyst, xros, xrsimulator]
|
||||
steps:
|
||||
- name: Checkout
|
||||
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:
|
||||
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: v5-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: Compress slices to preserve Symlinks
|
||||
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 (${{ 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 }}.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.0.0
|
||||
with:
|
||||
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
|
||||
key: v5-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
|
||||
needs: [build_apple_slices_hermes, prepare_hermes_workspace]
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flavor: [Debug, Release]
|
||||
steps:
|
||||
- name: Checkout
|
||||
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:
|
||||
key: v3-hermes-artifacts-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }}
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
name: slice-xrsimulator-${{ matrix.flavor }}
|
||||
- name: Unzip slices
|
||||
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_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' }}
|
||||
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: v3-hermes-artifacts-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }}
|
||||
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
|
||||
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.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:
|
||||
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.1
|
||||
with:
|
||||
name: hermes-linux-bin
|
||||
path: /tmp/hermes/linux64-bin
|
||||
|
||||
build_hermesc_windows:
|
||||
runs-on: windows-2019
|
||||
needs: prepare_hermes_workspace
|
||||
env:
|
||||
HERMES_WS_DIR: 'D:\tmp\hermes'
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: 'D:\tmp\hermes\hermes-runtime-darwin'
|
||||
HERMES_OSXBIN_ARTIFACTS_DIR: 'D:\tmp\hermes\osx-bin'
|
||||
ICU_URL: "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip"
|
||||
MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin'
|
||||
CMAKE_DIR: 'C:\Program Files\CMake\bin'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- name: Download Previous Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
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)) {
|
||||
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.1
|
||||
with:
|
||||
name: hermes-win64-bin
|
||||
path: D:\tmp\hermes\win64-bin\
|
||||
|
||||
build_android:
|
||||
runs-on: 8-core-ubuntu
|
||||
needs: [set_release_type]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
env:
|
||||
TERM: "dumb"
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
steps:
|
||||
- name: Checkout
|
||||
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.1
|
||||
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
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
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]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
env:
|
||||
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: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }}
|
||||
PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }}
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
env:
|
||||
GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }}
|
||||
ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
|
||||
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.1.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
- 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:
|
||||
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 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
|
||||
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 https://api.github.com/repos/react-native-community/template/actions/workflows/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\"}}"
|
||||
- name: Wait for template to be published
|
||||
if: needs.set_release_type.outputs.RELEASE_TYPE == 'release'
|
||||
timeout-minutes: 3
|
||||
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" \
|
||||
-H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \
|
||||
-d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}"
|
||||
@@ -1,26 +0,0 @@
|
||||
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)
|
||||
@@ -1,77 +0,0 @@
|
||||
name: Stale bot
|
||||
on:
|
||||
schedule:
|
||||
- cron: "*/10 5 * * *"
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
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.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.'
|
||||
exempt-issue-labels: 'Help Wanted :octocat:, Good first issue, Never gets stale, Issue: Author Provided Repro'
|
||||
exempt-pr-labels: 'Help Wanted :octocat:, Never gets stale'
|
||||
stale-asc:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
ascending: true
|
||||
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.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.'
|
||||
exempt-issue-labels: 'Help Wanted :octocat:, Good first issue, Never gets stale, Issue: Author Provided Repro'
|
||||
exempt-pr-labels: 'Help Wanted :octocat:, Never gets stale'
|
||||
stale-needs-author-feedback:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
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."
|
||||
stale-pr-message: "This PR is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days"
|
||||
close-issue-message: "This issue was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
close-pr-message: "This PR was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
exempt-issue-labels: "Help Wanted :octocat:, Good first issue, Never gets stale, Issue: Author Provided Repro"
|
||||
exempt-pr-labels: "Help Wanted :octocat:, Never gets stale"
|
||||
stale-needs-author-feedback-asc:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
ascending: true
|
||||
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."
|
||||
stale-pr-message: "This PR is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days"
|
||||
close-issue-message: "This issue was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
close-pr-message: "This PR was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
exempt-issue-labels: "Help Wanted :octocat:, Good first issue, Never gets stale, Issue: Author Provided Repro"
|
||||
exempt-pr-labels: "Help Wanted :octocat:, Never gets stale"
|
||||
@@ -1,932 +0,0 @@
|
||||
name: Test All
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "*-stable"
|
||||
|
||||
jobs:
|
||||
set_release_type:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }}
|
||||
env:
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
REF: ${{ github.ref }}
|
||||
steps:
|
||||
- id: set_release_type
|
||||
run: |
|
||||
if [[ $EVENT_NAME == "schedule" ]]; then
|
||||
echo "Setting release type to nightly"
|
||||
echo "RELEASE_TYPE=nightly" >> $GITHUB_OUTPUT
|
||||
elif [[ $EVENT_NAME == "push" && $REF == refs/tags/v* ]]; then
|
||||
echo "Setting release type to release"
|
||||
echo "RELEASE_TYPE=release" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Setting release type to dry-run"
|
||||
echo "RELEASE_TYPE=dry-run" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
prepare_hermes_workspace:
|
||||
runs-on: ubuntu-latest
|
||||
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.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 }}
|
||||
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.1.1
|
||||
- name: Restore Hermes workspace
|
||||
uses: ./.github/actions/restore-hermes-workspace
|
||||
- name: Hermes apple cache
|
||||
uses: actions/cache/restore@v4.0.0
|
||||
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 }}
|
||||
- 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]
|
||||
env:
|
||||
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: "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, catalyst, xros, xrsimulator]
|
||||
steps:
|
||||
- name: Checkout
|
||||
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:
|
||||
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: v5-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: Compress slices to preserve Symlinks
|
||||
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 (${{ 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 }}.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.0.0
|
||||
with:
|
||||
path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }}
|
||||
key: v5-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
|
||||
needs: [build_apple_slices_hermes, prepare_hermes_workspace]
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flavor: [Debug, Release]
|
||||
steps:
|
||||
- name: Checkout
|
||||
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:
|
||||
key: v4-hermes-artifacts-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }}
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
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/
|
||||
name: slice-xrsimulator-${{ matrix.flavor }}
|
||||
- name: Unzip slices
|
||||
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_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' }}
|
||||
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: v4-hermes-artifacts-${{ matrix.flavor }}-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }}
|
||||
path: |
|
||||
/tmp/hermes/osx-bin/${{ matrix.flavor }}
|
||||
/tmp/hermes/dSYM/${{ matrix.flavor }}
|
||||
/tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ matrix.flavor }}.tar.gz
|
||||
|
||||
test_ios_rntester_ruby_3_2_0:
|
||||
runs-on: macos-13
|
||||
needs:
|
||||
[build_apple_slices_hermes, prepare_hermes_workspace, build_hermes_macos]
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- name: Run it
|
||||
uses: ./.github/actions/test_ios_rntester
|
||||
with:
|
||||
ruby-version: "3.2.0"
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
test_ios_rntester_dynamic_frameworks:
|
||||
runs-on: macos-13
|
||||
needs:
|
||||
[build_apple_slices_hermes, prepare_hermes_workspace, build_hermes_macos]
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jsengine: [Hermes, JSC]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- name: Run it
|
||||
uses: ./.github/actions/test_ios_rntester
|
||||
with:
|
||||
jsengine: ${{ matrix.jsengine }}
|
||||
use-frameworks: DynamicFrameworks
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
|
||||
test_ios_rntester:
|
||||
runs-on: macos-13
|
||||
needs:
|
||||
[build_apple_slices_hermes, prepare_hermes_workspace, build_hermes_macos]
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jsengine: [Hermes, JSC]
|
||||
architecture: [NewArch, OldArch]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- name: Run it
|
||||
uses: ./.github/actions/test_ios_rntester
|
||||
with:
|
||||
jsengine: ${{ matrix.jsengine }}
|
||||
architecture: ${{ matrix.architecture }}
|
||||
run-unit-tests: true
|
||||
use-frameworks: StaticLibraries
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
|
||||
build_hermesc_linux:
|
||||
runs-on: ubuntu-latest
|
||||
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.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:
|
||||
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.1
|
||||
with:
|
||||
name: hermes-linux-bin
|
||||
path: /tmp/hermes/linux64-bin
|
||||
|
||||
build_hermesc_windows:
|
||||
runs-on: windows-2019
|
||||
needs: prepare_hermes_workspace
|
||||
env:
|
||||
HERMES_WS_DIR: 'D:\tmp\hermes'
|
||||
HERMES_TARBALL_ARTIFACTS_DIR: 'D:\tmp\hermes\hermes-runtime-darwin'
|
||||
HERMES_OSXBIN_ARTIFACTS_DIR: 'D:\tmp\hermes\osx-bin'
|
||||
ICU_URL: "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip"
|
||||
MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin'
|
||||
CMAKE_DIR: 'C:\Program Files\CMake\bin'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- name: Download Previous Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
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)) {
|
||||
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.1
|
||||
with:
|
||||
name: hermes-win64-bin
|
||||
path: D:\tmp\hermes\win64-bin\
|
||||
|
||||
build_android:
|
||||
runs-on: 8-core-ubuntu
|
||||
needs: [set_release_type]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
env:
|
||||
TERM: "dumb"
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
steps:
|
||||
- name: Checkout
|
||||
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.1
|
||||
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
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
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,
|
||||
]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
env:
|
||||
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: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }}
|
||||
PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }}
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
steps:
|
||||
- name: Add github.com to SSH known hosts
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo '|1|If6MU203eXTaaWL678YEfWkVMrw=|kqLeIAyTy8pzpj8x8Ae4Fr8Mtlc= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
|
||||
- name: Checkout
|
||||
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:
|
||||
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: 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: Use Node.js 18
|
||||
uses: actions/setup-node@v4.0.0
|
||||
with:
|
||||
node-version: 18
|
||||
cache: yarn
|
||||
- name: Install dependencies
|
||||
run: yarn install --non-interactive
|
||||
- name: Build packages
|
||||
run: yarn build
|
||||
# Continue with publish steps
|
||||
- name: Set npm credentials
|
||||
if: needs.set_release_type.outputs.RELEASE_TYPE == 'release' ||
|
||||
needs.set_release_type.outputs.RELEASE_TYPE == 'nightly'
|
||||
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.CIRCLE_NPM_TOKEN }}" > ~/.npmrc
|
||||
- name: Publish NPM
|
||||
shell: bash
|
||||
run: |
|
||||
# The checkout command puts react-native in a folder that is not "safe" for git
|
||||
# Every git command run in an unsafe folder fails. We need to pick the current commit to use it as part of the version
|
||||
# The following line marks the folder where react-native lives as "safe"
|
||||
git config --global --add safe.directory /__w/react-native/react-native
|
||||
|
||||
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 [[ "${{ 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
|
||||
node ./scripts/releases-ci/publish-npm.js -t ${{ needs.set_release_type.outputs.RELEASE_TYPE }}
|
||||
- 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 }}\" }}"
|
||||
|
||||
test_android_helloworld:
|
||||
runs-on: 4-core-ubuntu
|
||||
needs: prepare_hermes_workspace
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
env:
|
||||
# Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in conatiners
|
||||
# via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127
|
||||
LC_ALL: C.UTF8
|
||||
YARN_ENABLE_IMMUTABLE_INSTALLS: false
|
||||
TERM: "dumb"
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
TARGET_ARCHITECTURE: "arm64-v8a"
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flavor: [Debug, Release]
|
||||
architecture: [NewArch, OldArch]
|
||||
jsengine: [Hermes, JSC]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- 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: Run yarn
|
||||
shell: bash
|
||||
run: yarn install --non-interactive
|
||||
- name: Setup gradle
|
||||
uses: ./.github/actions/setup-gradle
|
||||
- name: Build CodeGen JS scripts
|
||||
shell: bash
|
||||
run: |
|
||||
cd packages/react-native-codegen
|
||||
yarn run build
|
||||
- name: Monitor Disk utilization (before build)
|
||||
shell: bash
|
||||
if: always()
|
||||
run: |
|
||||
echo "On Runner:"
|
||||
df -h
|
||||
echo "Root:"
|
||||
du -hs *
|
||||
echo "Projects folder:"
|
||||
du -hs ./packages/*
|
||||
- name: Build the Helloworld application for ${{ matrix.flavor }} with Architecture set to ${{ matrix.architecture }}, and using the ${{ matrix.jsengine }} JS engine.
|
||||
shell: bash
|
||||
run: |
|
||||
cd packages/helloworld/android
|
||||
args=()
|
||||
if [[ ${{ matrix.architecture }} == "OldArch" ]]; then
|
||||
args+=(--arch old)
|
||||
fi
|
||||
if [[ ${{ matrix.jsengine }} == "JSC" ]]; then
|
||||
args+=(--jsvm jsc)
|
||||
fi
|
||||
if [[ ${{ matrix.flavor }} == "Release" ]]; then
|
||||
args+=(--prod)
|
||||
fi
|
||||
yarn build android "${args[@]}" -P reactNativeArchitectures="$TARGET_ARCHITECTURE"
|
||||
- name: Monitor Disk utilization (after build)
|
||||
shell: bash
|
||||
if: always()
|
||||
run: |
|
||||
echo "On Runner:"
|
||||
df -h
|
||||
echo "Root:"
|
||||
du -hs *
|
||||
echo "Projects folder:"
|
||||
du -hs ./packages/*
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
with:
|
||||
name: template-apk-${{ matrix.flavor }}-${{ matrix.architecture }}-${{ matrix.jsengine }}
|
||||
path: ./app/build/outputs/apk/
|
||||
compression-level: 0
|
||||
|
||||
test_ios_helloworld_with_ruby_3_2_0:
|
||||
runs-on: macos-13
|
||||
needs: [prepare_hermes_workspace, build_hermes_macos] # prepare_hermes_workspace must be there because we need its reference to retrieve a couple of outputs
|
||||
env:
|
||||
PROJECT_NAME: iOSTemplateProject
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
YARN_ENABLE_IMMUTABLE_INSTALLS: false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- uses: ./.github/actions/test_ios_helloworld
|
||||
with:
|
||||
ruby-version: 3.2.0
|
||||
architecture: NewArch
|
||||
flavor: Debug
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
|
||||
test_ios_helloworld:
|
||||
runs-on: macos-13
|
||||
needs: [prepare_hermes_workspace, build_hermes_macos] # prepare_hermes_workspace must be there because we need its reference to retrieve a couple of outputs
|
||||
strategy:
|
||||
matrix:
|
||||
flavor: [Debug, Release]
|
||||
jsengine: [Hermes, JSC]
|
||||
use_frameworks: [StaticLibraries, DynamicFrameworks]
|
||||
exclude:
|
||||
# This config is tested with Ruby 3.2.0. Let's not double test it.
|
||||
- flavor: Debug
|
||||
jsengine: Hermes
|
||||
use_frameworks: StaticLibraries
|
||||
env:
|
||||
PROJECT_NAME: iOSTemplateProject
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
YARN_ENABLE_IMMUTABLE_INSTALLS: false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.1
|
||||
- uses: ./.github/actions/test_ios_helloworld
|
||||
with:
|
||||
flavor: ${{ matrix.flavor }}
|
||||
jsengine: ${{ matrix.jsengine }}
|
||||
use-frameworks: ${{ matrix.use_frameworks }}
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
+9
-122
@@ -20,148 +20,35 @@ DerivedData
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
**/.xcode.env.local
|
||||
|
||||
# Gradle
|
||||
/build/
|
||||
/packages/rn-tester/build
|
||||
/packages/rn-tester/android/app/.cxx/
|
||||
/packages/rn-tester/android/app/build/
|
||||
/packages/rn-tester/android/app/gradle/
|
||||
/packages/rn-tester/android/app/gradlew
|
||||
/packages/rn-tester/android/app/gradlew.bat
|
||||
/packages/react-native/ReactAndroid/build/
|
||||
/packages/react-native/ReactAndroid/.cxx/
|
||||
/packages/react-native/ReactAndroid/gradle/
|
||||
/packages/react-native/ReactAndroid/gradlew
|
||||
/packages/react-native/ReactAndroid/gradlew.bat
|
||||
/packages/react-native/ReactAndroid/external-artifacts/build/
|
||||
/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/
|
||||
/packages/react-native-test-library/android/build/
|
||||
/Examples/**/android/app/build/
|
||||
/Examples/**/android/app/gradle/
|
||||
/Examples/**/android/app/gradlew
|
||||
/Examples/**/android/app/gradlew.bat
|
||||
/ReactAndroid/build/
|
||||
|
||||
# Buck
|
||||
.buckd
|
||||
buck-out
|
||||
/.lsp.buckd
|
||||
/.lsp-buck-out
|
||||
/packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/
|
||||
/packages/react-native/ReactAndroid/src/main/gen
|
||||
/.cpplsp.buckd
|
||||
|
||||
# Android Studio
|
||||
.project
|
||||
.settings
|
||||
.classpath
|
||||
|
||||
# Watchman
|
||||
.watchmanconfig
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/armeabi-v7a/
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/x86/
|
||||
|
||||
# Android
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
/packages/react-native/android/*
|
||||
!/packages/react-native/android/README.md
|
||||
/android/
|
||||
|
||||
# Node
|
||||
node_modules
|
||||
*.log
|
||||
.nvm
|
||||
package-lock.json
|
||||
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Test generated files
|
||||
*.js.meta
|
||||
|
||||
/coverage
|
||||
/third-party
|
||||
|
||||
# Test Reports
|
||||
/reports
|
||||
|
||||
# Stack Dumps generated when programs crash (Ex. bash.exe.stackdump on Win)
|
||||
*.stackdump
|
||||
|
||||
# Root dir shouldn't have Xcode project
|
||||
/*.xcodeproj
|
||||
|
||||
# ReactCommon subdir shouldn't have Xcode project
|
||||
/packages/react-native/ReactCommon/**/*.xcodeproj
|
||||
|
||||
# Libs that shouldn't have Xcode project
|
||||
/packages/react-native/Libraries/FBLazyVector/**/*.xcodeproj
|
||||
/packages/react-native/Libraries/Required/**/*.xcodeproj
|
||||
/packages/react-native/React/CoreModules/**/*.xcodeproj
|
||||
/packages/react-native/React/FBReactNativeSpec/**/*.xcodeproj
|
||||
/packages/react-native-codegen/**/*.xcodeproj
|
||||
/packages/rn-tester/**/*.xcodeproj
|
||||
|
||||
# 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
|
||||
/packages/rn-tester/Gemfile.lock
|
||||
/packages/**/RCTLegacyInteropComponents.mm
|
||||
|
||||
# Ignore RNTester specific Pods, but keep the __offline_mirrors__ here.
|
||||
/packages/rn-tester/Pods/*
|
||||
!/packages/rn-tester/Pods/__offline_mirrors_hermes__
|
||||
!/packages/rn-tester/Pods/__offline_mirrors_jsc__
|
||||
|
||||
# @react-native/codegen
|
||||
/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec
|
||||
/packages/react-native-codegen/lib
|
||||
/packages/react-native-codegen/tmp/
|
||||
/packages/react-native/ReactCommon/react/renderer/components/rncore/
|
||||
/packages/rn-tester/NativeModuleExample/ScreenshotManagerSpec*
|
||||
/**/RCTThirdPartyFabricComponentsProvider.*
|
||||
|
||||
# @react-native/codegen-typescript-test
|
||||
/packages/react-native-codegen-typescript-test/lib
|
||||
|
||||
# Additional SDKs
|
||||
/packages/react-native/sdks/download
|
||||
/packages/react-native/sdks/hermes
|
||||
/packages/react-native/sdks/hermesc
|
||||
/packages/react-native/sdks/hermes-engine/hermes-engine-from-local-source-dir.tar.gz
|
||||
|
||||
# Visual Studio Code (config dir - if present, this merges user defined
|
||||
# workspace settings on top of react-native.code-workspace)
|
||||
/.vscode
|
||||
|
||||
# Visual Studio
|
||||
.vs
|
||||
|
||||
# Android memory profiler files
|
||||
*.hprof
|
||||
|
||||
# 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
|
||||
/ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# rnpm
|
||||
/local-cli/rnpm
|
||||
@@ -1,11 +0,0 @@
|
||||
# Ignore Pods
|
||||
**/Pods
|
||||
|
||||
# Ignore hermes as it is downloaded from the react_native_pods
|
||||
**/sdks/hermes
|
||||
**/sdks/downloads
|
||||
|
||||
packages/*/dist
|
||||
vendor
|
||||
|
||||
packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeEnumTurboModule.js
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"bracketSameLine": true,
|
||||
"bracketSpacing": false,
|
||||
"requirePragma": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"endOfLine": "lf",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.code-workspace"],
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.js.flow"
|
||||
],
|
||||
"options": {
|
||||
"parser": "hermes"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
language: objective-c
|
||||
|
||||
osx_image: xcode7.3
|
||||
|
||||
install:
|
||||
- mkdir -p /Users/travis/build/facebook/.nvm
|
||||
- export NVM_DIR="/Users/travis/build/facebook/.nvm"
|
||||
- brew install nvm
|
||||
- source $(brew --prefix nvm)/nvm.sh
|
||||
# TODO npm 2 started stalling on Travis, t11852928
|
||||
- nvm install 5
|
||||
- rm -Rf "${TMPDIR}/jest_preprocess_cache"
|
||||
- npm config set spin=false
|
||||
- npm config set progress=false
|
||||
- travis_wait npm install
|
||||
|
||||
script:
|
||||
- if [[ "$TEST_TYPE" = objc ]]; then travis_retry travis_wait ./scripts/objc-test.sh; fi
|
||||
- if [[ "$TEST_TYPE" = e2e-objc ]]; then node ./scripts/run-ci-e2e-tests.js --ios --js --retries 3; fi
|
||||
- if [[ "$TEST_TYPE" = js ]]; then npm run flow check; fi
|
||||
- if [[ "$TEST_TYPE" = js ]]; then npm test -- --maxWorkers=1; fi
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- TEST_TYPE=e2e-objc
|
||||
- TEST_TYPE=objc
|
||||
- TEST_TYPE=js
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^.*-stable$/
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- bestander@gmail.com
|
||||
on_failure: change
|
||||
on_success: change
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
-2906
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
||||
# Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at <opensource-conduct@fb.com>. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1,
|
||||
available at https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
|
||||
+127
-4
@@ -1,7 +1,130 @@
|
||||
# Contributing to React Native
|
||||
|
||||
Thank you for your interest in contributing to React Native! From commenting on and triaging issues, to reviewing and sending Pull Requests, all contributions are welcome.
|
||||
We aim to build a vibrant and inclusive [ecosystem of partners, core contributors, and community](ECOSYSTEM.md) that goes beyond the main React Native GitHub repository.
|
||||
React Native is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://facebook.com). We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and preempts some questions you may have.
|
||||
|
||||
To learn more about how to contribute check out the Contributing section on the React Native website:
|
||||
* https://reactnative.dev/contributing/overview
|
||||
## Our Development Process
|
||||
|
||||
Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
|
||||
|
||||
### `master` is unsafe
|
||||
|
||||
We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to communicate these changes and version appropriately so you can lock into a specific version if need be.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
The core team will be monitoring for pull requests. When we get one, we'll run some Facebook-specific integration tests on it first. From here, we'll need to get another person to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
|
||||
|
||||
**Please submit your pull request on the `master` branch**. If the fix is critical and should be included in a stable branch please mention it and it will be cherry picked into it.
|
||||
|
||||
*Before* submitting a pull request, please make sure the following is done…
|
||||
|
||||
1. Fork the repo and create your branch from `master`.
|
||||
2. **Describe your test plan in your commit.** If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. If you've updated the docs, verify the website locally and submit screenshots if applicable.
|
||||
|
||||
```
|
||||
$ cd website
|
||||
$ npm install && npm start
|
||||
go to: http://localhost:8079/react-native/index.html
|
||||
```
|
||||
|
||||
5. Add the copyright notice to the top of any new files you've added.
|
||||
6. Ensure tests pass on Travis and Circle CI.
|
||||
7. Make sure your code lints (`node linter.js <files touched>`).
|
||||
8. If you haven't already, sign the [CLA](https://code.facebook.com/cla).
|
||||
9. Squash your commits (`git rebase -i`).
|
||||
one intent alongs with one commit makes it clearer for people to review and easier to understand your intention
|
||||
|
||||
Note: It is not necessary to keep clicking `Merge master to your branch` on PR page. You would want to merge master if there are conflicts or tests are failing. The facebook-bot ultimately squashes all commits to a single one before merging your PR.
|
||||
|
||||
#### Copyright Notice for files
|
||||
|
||||
Copy and paste this to the top of your new file(s):
|
||||
|
||||
```JS
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
```
|
||||
|
||||
If you've added a new module, add a `@providesModule <moduleName>` at the end of the comment. This will allow the haste package manager to find it.
|
||||
|
||||
### Contributor License Agreement (CLA)
|
||||
|
||||
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username.
|
||||
|
||||
[Complete your CLA here](https://code.facebook.com/cla)
|
||||
|
||||
## Bugs
|
||||
|
||||
### Where to Find Known Issues
|
||||
|
||||
We are using GitHub Issues for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn't already exist.
|
||||
|
||||
### Reporting New Issues
|
||||
|
||||
The best way to get your bug fixed is to provide a reduced test case. Please provide either a public repository with a runnable example or a [React Native Playground](https://rnplay.org/) snippet.
|
||||
|
||||
### Security Bugs
|
||||
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
|
||||
|
||||
## How to Get in Touch
|
||||
|
||||
* [Facebook group](https://www.facebook.com/groups/react.native.community/)
|
||||
* Reactiflux — [#react-native](http://join.reactiflux.com/)
|
||||
|
||||
## Style Guide
|
||||
|
||||
### Code
|
||||
|
||||
#### General
|
||||
|
||||
* **Most important: Look around.** Match the style you see used in the rest of the project. This includes formatting, naming things in code, naming things in documentation.
|
||||
* Add trailing commas,
|
||||
* 2 spaces for indentation (no tabs)
|
||||
* "Attractive"
|
||||
|
||||
#### JavaScript
|
||||
|
||||
* Use semicolons;
|
||||
* `'use strict';`
|
||||
* Prefer `'` over `"`
|
||||
* Do not use the optional parameters of `setTimeout` and `setInterval`
|
||||
* 80 character line length
|
||||
|
||||
#### JSX
|
||||
|
||||
* Prefer `"` over `'` for string literal props
|
||||
* When wrapping opening tags over multiple lines, place one prop per line
|
||||
* `{}` of props should hug their values (no spaces)
|
||||
* Place the closing `>` of opening tags on the same line as the last prop
|
||||
* Place the closing `/>` of self-closing tags on their own line and left-align them with the opening `<`
|
||||
|
||||
#### Objective-C
|
||||
|
||||
* Space after `@property` declarations
|
||||
* Brackets on *every* `if`, on the *same* line
|
||||
* `- method`, `@interface`, and `@implementation` brackets on the following line
|
||||
* *Try* to keep it around 80 characters line length (sometimes it's just not possible...)
|
||||
* `*` operator goes with the variable name (e.g. `NSObject *variableName;`)
|
||||
|
||||
#### Java
|
||||
|
||||
* If a method call spans multiple lines closing bracket is on the same line as the last argument.
|
||||
* If a method header doesn't fit on one line each argument goes on a separate line.
|
||||
* 100 character line length
|
||||
|
||||
### Documentation
|
||||
|
||||
* Do not wrap lines at 80 characters - configure your editor to soft-wrap when editing documentation.
|
||||
|
||||
## License
|
||||
|
||||
By contributing to React Native, you agree that your contributions will be licensed under its BSD license.
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
# The React Native Ecosystem
|
||||
|
||||
We aim to build a vibrant and inclusive ecosystem of partners, core contributors, and community that goes beyond the main React Native GitHub repository. This document explains the roles and responsibilities of various stakeholders and provides guidelines for the community organization. The structure outlined in this document has been in place for a while but had not been written down before.
|
||||
|
||||
There are three types of stakeholders:
|
||||
|
||||
* **Partners:** Companies significantly invested in React Native and take responsibility for the React Native vision and community.
|
||||
* **Core Contributors:** Individual people who contribute to the React Native project.
|
||||
* **Community Contributors:** Individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization.
|
||||
|
||||
## Partners
|
||||
|
||||
Partners are companies that are significantly invested in React Native and demonstrate ownership. Informed by their use of React Native, they push for improvements of the core and/or the ecosystem around it. Examples of this may include large scale contributions to `react-native` or owning essential tools or libraries.
|
||||
|
||||
Partners think of React Native as a product; they understand the trade offs that the project makes as well as future plans and goals. Together we shape the vision for React Native to make it the best way to build applications.
|
||||
|
||||
### Application process
|
||||
To become a React Native partner, an existing partner needs to refer and champion your application. Partners will undergo a 3 month incubating period, after which Partners will vote to convert to full membership.
|
||||
|
||||
Partnership is not a status symbol, it is a commitment to invest significant resources into improving React Native.
|
||||
|
||||
Maintaining partner status requires consistently meeting the baseline responsibilities, including:
|
||||
* Attending monthly meeting.
|
||||
* Contributing to the release process.
|
||||
* Engaging in the core contributor Discord.
|
||||
|
||||
Examples of contributing to the release include being a [community releaser](https://reactnative.dev/contributing/release-roles-responsibilities#release-role-2-community-releaser), testing new releases, and technical support for release issues.
|
||||
|
||||
### Current partners:
|
||||
* **[Coinbase](https://www.coinbase.com/):** Publishes [posts](https://blog.coinbase.com/tagged/react-native) advocating React Native usage. Supports `@react-native-community/datetimepicker` and other community modules to migrate to the new architecture. Supports releases in testing and feedback.
|
||||
* **[Callstack](https://callstack.com/):** Maintains the [React Native CLI](https://github.com/react-native-community/react-native-cli) and [other community libraries](https://github.com/callstack), organizes [React Native EU](https://react-native.eu/) and hosts [The React Native Show podcast](https://www.callstack.com/podcast-react-native-show)
|
||||
* **[Expo](https://expo.dev/):** Builds [Expo Go and SDK](https://github.com/expo/expo), [Snack](https://snack.expo.dev/), and [Expo Application Services](https://expo.dev/eas). Maintains [React Native Directory](https://reactnative.directory/), stewards [React Navigation](https://reactnavigation.org/) along with other partners.
|
||||
* **[Infinite Red](https://infinite.red/):** Maintains the [ignite cli/boilerplate](https://github.com/infinitered/ignite), organizes [Chain React Conf](https://cr.infinite.red/), hosts the [React Native Radio podcast](https://reactnativeradio.com), publishes the [React Native Newsletter](https://reactnativenewsletter.com)
|
||||
* **[Meta](https://opensource.fb.com/):** Oversees the React Native product and maintains the [React Native core repo](https://reactnative.dev/)
|
||||
* **[Microsoft](https://twitter.com/ReactNativeMSFT):** Develops [React Native Windows](https://github.com/Microsoft/react-native-windows) and [React Native macOS](https://github.com/microsoft/react-native-macos) for building apps that target Windows and macOS; maintains [rnx-kit](https://github.com/microsoft/rnx-kit), [react-native-test-app](https://github.com/microsoft/react-native-test-app) and coordinates cross-companies efforts such as the [bundle working group](https://github.com/microsoft/rnx-kit/discussions/categories/bundle-working-group).
|
||||
* **[Shopify](https://www.shopify.com/):** Maintains React Native open source libraries such as [flash-list](https://github.com/Shopify/flash-list) or [@shopify/react-native-skia](https://github.com/Shopify/react-native-skia) and sponsors Software Mansion.
|
||||
* **[Software Mansion](https://swmansion.com/):** Maintain core infrastructure including JSC, Animated, and other popular third-party plugins and organizes [App.js Conf](https://appjs.co/)
|
||||
* **[Wix.com](https://wix.engineering/open-source):** Maintains a variety of React Native open source projects ([see all](https://github.com/orgs/wix/repositories?q=react-native)), including: [Detox](https://wix.github.io/Detox/) end-to-end testing library for React Native apps, [RN UILib](https://wix.github.io/react-native-ui-lib/), [RN Navigation](https://wix.github.io/react-native-navigation/), [RN Calendars](https://wix.github.io/react-native-calendars/) and [RN Notifications](https://github.com/wix/react-native-notifications).
|
||||
|
||||
### Incubating partners:
|
||||
* **[Expensify](https://expensify.com/):** Developing [Expensify Chat](https://github.com/Expensify/App), an open-source React Native app built by the community, while [sponsoring dependencies](https://github.com/orgs/Expensify/sponsoring), conferences, and New Architecture advancements.
|
||||
* **[Sentry](https://sentry.io/for/react-native/):** Develops Error and Performance Monitoring [SDK for React Native](https://github.com/getsentry/sentry-react-native) and [New Architecture Turbo Modules Mixed Stack Traces](https://github.com/reactwg/react-native-new-architecture/discussions/122).
|
||||
|
||||
When you are contributing to React Native, you'll most likely meet somebody who works at one of the partner companies and who is a core contributor.
|
||||
|
||||
## Core Contributors
|
||||
|
||||
Core contributors are individuals who contribute to the React Native project. A core contributor is somebody who displayed a lasting commitment to the evolution and maintenance of React Native. The work done by core contributors includes responsibilities mentioned in the “Partners” section above, and concretely means that they:
|
||||
|
||||
* Consistently contribute high quality changes, fixes and improvements
|
||||
* Actively review changes and provide quality feedback to contributors
|
||||
* Manage the release process of React Native by maintaining release branches, communicating changes to users and publishing releases
|
||||
* Love to help out other users with issues on GitHub
|
||||
* Mentor and encourage first time contributors
|
||||
* Identify React Native community members who could be effective core contributors
|
||||
* Help build an inclusive community with people from all backgrounds
|
||||
* Are great at communicating with other contributors and the community in general
|
||||
|
||||
These are behaviors we have observed in our existing core contributors. They aren't strict rules but rather outline their usual responsibilities. We do not expect every core contributor to do all of the above things all the time. Most importantly, we want to create a supportive and friendly environment that fosters collaboration. Above all else, **we are always polite and friendly.**
|
||||
|
||||
Core contributor status is attained after consistently contributing and taking on the responsibilities outlined above and granted by other core contributors. Similarly, after a long period of inactivity (~6 months or more), a core contributor may be contacted to understand if they’re still interested in being part of the program.
|
||||
|
||||
You can use this [form](https://forms.gle/4jpA4QeNUvAUDnNe8) to either:
|
||||
* Apply yourself to become a Core Contributor. Make sure to include a list of valuable contributions you did to the React Native repository and ecosystem.
|
||||
* Nominate someone to become a Core Contributor.
|
||||
|
||||
As a core contributor, you will have access to the core contributor Discord which is used for light-weight coordination and discussion.
|
||||
|
||||
**We aim to make contributing to React Native as easy and transparent as possible.** We have discussion groups dedicated to the [new architecture rollout](https://github.com/reactwg/react-native-new-architecture), [releases](https://github.com/reactwg/react-native-releases), and [general questions and proposals](https://github.com/react-native-community/discussions-and-proposals). We are always looking for active, enthusiastic members of the React Native community to become core contributors.
|
||||
|
||||
## Community Contributors
|
||||
|
||||
Community contributors are individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization. This organization exists as an incubator for high quality components that extend the capabilities of React Native with functionality that many but not all applications require. Meta engineers will provide guidance to help build a vibrant community of people and components that make React Native better.
|
||||
|
||||
This structure has multiple benefits:
|
||||
|
||||
* Keep the core of React Native small, which improves performance and reduces the surface area
|
||||
* Provide visibility to projects through shared representation, for example on the React Native website or on Twitter
|
||||
* Ensure a consistent and high standard for code, documentation, user experience, stability and contributions for third-party components
|
||||
* Upgrade the most important components right away when we make breaking changes and move the ecosystem forward at a fast pace
|
||||
* Find new maintainers for projects that are important but were abandoned by previous owners
|
||||
|
||||
Additionally, some companies may choose to sponsor the development of one or many of the packages that are part of the community organization. They will commit to maintain projects, triage issues, fix bugs and develop features. In turn, they will be able to gain visibility for their work, for example through a mention of active maintainers in the README of individual projects after a consistent period of contributions. Such a mention may be removed if maintainers abandon the project.
|
||||
|
||||
If you are working on a popular component and would like to move it to the React Native community, please create an issue on the [discussions-and-proposals repository](https://github.com/react-native-community/discussions-and-proposals).
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-alert": 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,489 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1461632C1AC3E22900C2F5AD /* libReact.a */; };
|
||||
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F82F1771B85784500FAE87E /* libRCTWebSocket.a */; };
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||
E730D7501D4EE4E2000B7DA8 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E730D74C1D4EE4D0000B7DA8 /* libRCTNetwork.a */; };
|
||||
E730D7571D4EE538000B7DA8 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E730D7561D4EE534000B7DA8 /* libRCTImage.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
5F82F1761B85784500FAE87E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
E730D74B1D4EE4D0000B7DA8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = E730D7471D4EE4D0000B7DA8 /* RCTNetwork.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
|
||||
remoteInfo = RCTNetwork;
|
||||
};
|
||||
E730D7551D4EE534000B7DA8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = E730D7511D4EE534000B7DA8 /* RCTImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
|
||||
remoteInfo = RCTImage;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
13B07F961A680F5B00A75B9A /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = 2048/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = 2048/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = 2048/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = 2048/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = 2048/main.m; sourceTree = "<group>"; };
|
||||
146163271AC3E22900C2F5AD /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
E730D7471D4EE4D0000B7DA8 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
E730D7511D4EE534000B7DA8 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E730D7571D4EE538000B7DA8 /* libRCTImage.a in Frameworks */,
|
||||
E730D7501D4EE4E2000B7DA8 /* libRCTNetwork.a in Frameworks */,
|
||||
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */,
|
||||
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */,
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
13B07FAE1A68108700A75B9A /* 2048 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
);
|
||||
name = 2048;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
146163281AC3E22900C2F5AD /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1461632C1AC3E22900C2F5AD /* libReact.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5F82F1731B85784500FAE87E /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E730D7511D4EE534000B7DA8 /* RCTImage.xcodeproj */,
|
||||
E730D7471D4EE4D0000B7DA8 /* RCTNetwork.xcodeproj */,
|
||||
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */,
|
||||
146163271AC3E22900C2F5AD /* React.xcodeproj */,
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341B11AAA6A8300B99B32 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* 2048 */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* 2048.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E730D7481D4EE4D0000B7DA8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E730D74C1D4EE4D0000B7DA8 /* libRCTNetwork.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E730D7521D4EE534000B7DA8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E730D7561D4EE534000B7DA8 /* libRCTImage.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
13B07F861A680F5B00A75B9A /* 2048 */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "2048" */;
|
||||
buildPhases = (
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
68ACCCD51D2BE2D2008E368A /* Run Script */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = 2048;
|
||||
productName = "Hello World";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* 2048.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "2048" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = E730D7521D4EE534000B7DA8 /* Products */;
|
||||
ProjectRef = E730D7511D4EE534000B7DA8 /* RCTImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = E730D7481D4EE4D0000B7DA8 /* Products */;
|
||||
ProjectRef = E730D7471D4EE4D0000B7DA8 /* RCTNetwork.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
|
||||
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 5F82F1731B85784500FAE87E /* Products */;
|
||||
ProjectRef = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 146163281AC3E22900C2F5AD /* Products */;
|
||||
ProjectRef = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* 2048 */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
1461632C1AC3E22900C2F5AD /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 5F82F1761B85784500FAE87E /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTText.a;
|
||||
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
E730D74C1D4EE4D0000B7DA8 /* libRCTNetwork.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTNetwork.a;
|
||||
remoteRef = E730D74B1D4EE4D0000B7DA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
E730D7561D4EE534000B7DA8 /* libRCTImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTImage.a;
|
||||
remoteRef = E730D7551D4EE534000B7DA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
68ACCCD51D2BE2D2008E368A /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n$SRCROOT/../../packager/react-native-xcode.sh Examples/2048/Game2048.js\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
path = 2048;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = 2048;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = 2048;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "2048" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
13B07F951A680F5B00A75B9A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "2048" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
83CBBA211A601CBA00E9B192 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTBundleURLProvider.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"Examples/2048/Game2048" fallbackResource:nil];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"Game2048"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2048" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule Game2048
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
var Animated = require('Animated');
|
||||
var GameBoard = require('GameBoard');
|
||||
var TouchableBounce = require('TouchableBounce');
|
||||
|
||||
var BOARD_PADDING = 3;
|
||||
var CELL_MARGIN = 4;
|
||||
var CELL_SIZE = 60;
|
||||
|
||||
class Cell extends React.Component {
|
||||
render() {
|
||||
return <View style={styles.cell} />;
|
||||
}
|
||||
}
|
||||
|
||||
class Board extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.board}>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
{this.props.children}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Tile extends React.Component {
|
||||
state: any;
|
||||
|
||||
static _getPosition(index): number {
|
||||
return BOARD_PADDING + (index * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||
}
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
var tile = this.props.tile;
|
||||
|
||||
this.state = {
|
||||
opacity: new Animated.Value(0),
|
||||
top: new Animated.Value(Tile._getPosition(tile.toRow())),
|
||||
left: new Animated.Value(Tile._getPosition(tile.toColumn())),
|
||||
};
|
||||
}
|
||||
|
||||
calculateOffset(): {top: number; left: number; opacity: number} {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var offset = {
|
||||
top: this.state.top,
|
||||
left: this.state.left,
|
||||
opacity: this.state.opacity,
|
||||
};
|
||||
|
||||
if (tile.isNew()) {
|
||||
Animated.timing(this.state.opacity, {
|
||||
duration: 100,
|
||||
toValue: 1,
|
||||
}).start();
|
||||
} else {
|
||||
Animated.parallel([
|
||||
Animated.timing(offset.top, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toRow()),
|
||||
}),
|
||||
Animated.timing(offset.left, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toColumn()),
|
||||
}),
|
||||
]).start();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
render() {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var tileStyles = [
|
||||
styles.tile,
|
||||
styles['tile' + tile.value],
|
||||
this.calculateOffset(),
|
||||
];
|
||||
|
||||
var textStyles = [
|
||||
styles.value,
|
||||
tile.value > 4 && styles.whiteText,
|
||||
tile.value > 100 && styles.threeDigits,
|
||||
tile.value > 1000 && styles.fourDigits,
|
||||
];
|
||||
|
||||
return (
|
||||
<Animated.View style={tileStyles}>
|
||||
<Text style={textStyles}>{tile.value}</Text>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GameEndOverlay extends React.Component {
|
||||
render() {
|
||||
var board = this.props.board;
|
||||
|
||||
if (!board.hasWon() && !board.hasLost()) {
|
||||
return <View/>;
|
||||
}
|
||||
|
||||
var message = board.hasWon() ?
|
||||
'Good Job!' : 'Game Over';
|
||||
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<Text style={styles.overlayMessage}>{message}</Text>
|
||||
<TouchableBounce onPress={this.props.onRestart} style={styles.tryAgain}>
|
||||
<Text style={styles.tryAgainText}>Try Again?</Text>
|
||||
</TouchableBounce>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Game2048 extends React.Component {
|
||||
startX: number;
|
||||
startY: number;
|
||||
state: any;
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
this.state = {
|
||||
board: new GameBoard(),
|
||||
};
|
||||
this.startX = 0;
|
||||
this.startY = 0;
|
||||
}
|
||||
|
||||
restartGame() {
|
||||
this.setState({board: new GameBoard()});
|
||||
}
|
||||
|
||||
handleTouchStart(event: Object) {
|
||||
if (this.state.board.hasWon()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.startX = event.nativeEvent.pageX;
|
||||
this.startY = event.nativeEvent.pageY;
|
||||
}
|
||||
|
||||
handleTouchEnd(event: Object) {
|
||||
if (this.state.board.hasWon()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var deltaX = event.nativeEvent.pageX - this.startX;
|
||||
var deltaY = event.nativeEvent.pageY - this.startY;
|
||||
|
||||
var direction = -1;
|
||||
if (Math.abs(deltaX) > 3 * Math.abs(deltaY) && Math.abs(deltaX) > 30) {
|
||||
direction = deltaX > 0 ? 2 : 0;
|
||||
} else if (Math.abs(deltaY) > 3 * Math.abs(deltaX) && Math.abs(deltaY) > 30) {
|
||||
direction = deltaY > 0 ? 3 : 1;
|
||||
}
|
||||
|
||||
if (direction !== -1) {
|
||||
this.setState({board: this.state.board.move(direction)});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
var tiles = this.state.board.tiles
|
||||
.filter((tile) => tile.value)
|
||||
.map((tile) => <Tile ref={tile.id} key={tile.id} tile={tile} />);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={styles.container}
|
||||
onTouchStart={(event) => this.handleTouchStart(event)}
|
||||
onTouchEnd={(event) => this.handleTouchEnd(event)}>
|
||||
<Board>
|
||||
{tiles}
|
||||
</Board>
|
||||
<GameEndOverlay board={this.state.board} onRestart={() => this.restartGame()} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
board: {
|
||||
padding: BOARD_PADDING,
|
||||
backgroundColor: '#bbaaaa',
|
||||
borderRadius: 5,
|
||||
},
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: 'rgba(221, 221, 221, 0.5)',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
overlayMessage: {
|
||||
fontSize: 40,
|
||||
marginBottom: 20,
|
||||
},
|
||||
tryAgain: {
|
||||
backgroundColor: '#887761',
|
||||
padding: 20,
|
||||
borderRadius: 5,
|
||||
},
|
||||
tryAgainText: {
|
||||
color: '#ffffff',
|
||||
fontSize: 20,
|
||||
fontWeight: '500',
|
||||
},
|
||||
cell: {
|
||||
width: CELL_SIZE,
|
||||
height: CELL_SIZE,
|
||||
borderRadius: 5,
|
||||
backgroundColor: '#ddccbb',
|
||||
margin: CELL_MARGIN,
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
tile: {
|
||||
position: 'absolute',
|
||||
width: CELL_SIZE,
|
||||
height: CELL_SIZE,
|
||||
backgroundColor: '#ddccbb',
|
||||
borderRadius: 5,
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
value: {
|
||||
fontSize: 24,
|
||||
color: '#776666',
|
||||
fontFamily: 'Verdana',
|
||||
fontWeight: '500',
|
||||
},
|
||||
tile2: {
|
||||
backgroundColor: '#eeeeee',
|
||||
},
|
||||
tile4: {
|
||||
backgroundColor: '#eeeecc',
|
||||
},
|
||||
tile8: {
|
||||
backgroundColor: '#ffbb87',
|
||||
},
|
||||
tile16: {
|
||||
backgroundColor: '#ff9966',
|
||||
},
|
||||
tile32: {
|
||||
backgroundColor: '#ff7755',
|
||||
},
|
||||
tile64: {
|
||||
backgroundColor: '#ff5533',
|
||||
},
|
||||
tile128: {
|
||||
backgroundColor: '#eecc77',
|
||||
},
|
||||
tile256: {
|
||||
backgroundColor: '#eecc66',
|
||||
},
|
||||
tile512: {
|
||||
backgroundColor: '#eecc55',
|
||||
},
|
||||
tile1024: {
|
||||
backgroundColor: '#eecc33',
|
||||
},
|
||||
tile2048: {
|
||||
backgroundColor: '#eecc22',
|
||||
},
|
||||
whiteText: {
|
||||
color: '#ffffff',
|
||||
},
|
||||
threeDigits: {
|
||||
fontSize: 20,
|
||||
},
|
||||
fourDigits: {
|
||||
fontSize: 18,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('Game2048', () => Game2048);
|
||||
|
||||
module.exports = Game2048;
|
||||
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule GameBoard
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// NB: Taken straight from: https://github.com/IvanVergiliev/2048-react/blob/master/src/board.js
|
||||
// with no modification except to format it for CommonJS and fix lint/flow errors
|
||||
|
||||
var rotateLeft = function (matrix) {
|
||||
var rows = matrix.length;
|
||||
var columns = matrix[0].length;
|
||||
var res = [];
|
||||
for (var row = 0; row < rows; ++row) {
|
||||
res.push([]);
|
||||
for (var column = 0; column < columns; ++column) {
|
||||
res[row][column] = matrix[column][columns - row - 1];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
var Tile = function (value?: number, row?: number, column?: number) {
|
||||
this.value = value || 0;
|
||||
this.row = row || -1;
|
||||
|
||||
this.column = column || -1;
|
||||
this.oldRow = -1;
|
||||
this.oldColumn = -1;
|
||||
this.markForDeletion = false;
|
||||
this.mergedInto = null;
|
||||
this.id = Tile.id++;
|
||||
};
|
||||
|
||||
Tile.id = 0;
|
||||
|
||||
Tile.prototype.moveTo = function (row, column) {
|
||||
this.oldRow = this.row;
|
||||
this.oldColumn = this.column;
|
||||
this.row = row;
|
||||
this.column = column;
|
||||
};
|
||||
|
||||
Tile.prototype.isNew = function () {
|
||||
return this.oldRow === -1 && !this.mergedInto;
|
||||
};
|
||||
|
||||
Tile.prototype.hasMoved = function () {
|
||||
return (this.fromRow() !== -1 && (this.fromRow() !== this.toRow() || this.fromColumn() !== this.toColumn())) ||
|
||||
this.mergedInto;
|
||||
};
|
||||
|
||||
Tile.prototype.fromRow = function () {
|
||||
return this.mergedInto ? this.row : this.oldRow;
|
||||
};
|
||||
|
||||
Tile.prototype.fromColumn = function () {
|
||||
return this.mergedInto ? this.column : this.oldColumn;
|
||||
};
|
||||
|
||||
Tile.prototype.toRow = function () {
|
||||
return this.mergedInto ? this.mergedInto.row : this.row;
|
||||
};
|
||||
|
||||
Tile.prototype.toColumn = function () {
|
||||
return this.mergedInto ? this.mergedInto.column : this.column;
|
||||
};
|
||||
|
||||
var Board = function () {
|
||||
this.tiles = [];
|
||||
this.cells = [];
|
||||
for (var i = 0; i < Board.size; ++i) {
|
||||
this.cells[i] = [this.addTile(), this.addTile(), this.addTile(), this.addTile()];
|
||||
}
|
||||
this.addRandomTile();
|
||||
this.setPositions();
|
||||
this.won = false;
|
||||
};
|
||||
|
||||
Board.prototype.addTile = function () {
|
||||
var res = new Tile();
|
||||
Tile.apply(res, arguments);
|
||||
this.tiles.push(res);
|
||||
return res;
|
||||
};
|
||||
|
||||
Board.size = 4;
|
||||
|
||||
Board.prototype.moveLeft = function () {
|
||||
var hasChanged = false;
|
||||
for (var row = 0; row < Board.size; ++row) {
|
||||
var currentRow = this.cells[row].filter(function (tile) { return tile.value !== 0; });
|
||||
var resultRow = [];
|
||||
for (var target = 0; target < Board.size; ++target) {
|
||||
var targetTile = currentRow.length ? currentRow.shift() : this.addTile();
|
||||
if (currentRow.length > 0 && currentRow[0].value === targetTile.value) {
|
||||
var tile1 = targetTile;
|
||||
targetTile = this.addTile(targetTile.value);
|
||||
tile1.mergedInto = targetTile;
|
||||
var tile2 = currentRow.shift();
|
||||
tile2.mergedInto = targetTile;
|
||||
targetTile.value += tile2.value;
|
||||
}
|
||||
resultRow[target] = targetTile;
|
||||
this.won = this.won || (targetTile.value === 2048);
|
||||
hasChanged = hasChanged || (targetTile.value !== this.cells[row][target].value);
|
||||
}
|
||||
this.cells[row] = resultRow;
|
||||
}
|
||||
return hasChanged;
|
||||
};
|
||||
|
||||
Board.prototype.setPositions = function () {
|
||||
this.cells.forEach(function (row, rowIndex) {
|
||||
row.forEach(function (tile, columnIndex) {
|
||||
tile.oldRow = tile.row;
|
||||
tile.oldColumn = tile.column;
|
||||
tile.row = rowIndex;
|
||||
tile.column = columnIndex;
|
||||
tile.markForDeletion = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Board.fourProbability = 0.1;
|
||||
|
||||
Board.prototype.addRandomTile = function () {
|
||||
var emptyCells = [];
|
||||
for (var r = 0; r < Board.size; ++r) {
|
||||
for (var c = 0; c < Board.size; ++c) {
|
||||
if (this.cells[r][c].value === 0) {
|
||||
emptyCells.push({r: r, c: c});
|
||||
}
|
||||
}
|
||||
}
|
||||
var index = Math.floor(Math.random() * emptyCells.length);
|
||||
var cell = emptyCells[index];
|
||||
var newValue = Math.random() < Board.fourProbability ? 4 : 2;
|
||||
this.cells[cell.r][cell.c] = this.addTile(newValue);
|
||||
};
|
||||
|
||||
Board.prototype.move = function (direction) {
|
||||
// 0 -> left, 1 -> up, 2 -> right, 3 -> down
|
||||
this.clearOldTiles();
|
||||
for (var i = 0; i < direction; ++i) {
|
||||
this.cells = rotateLeft(this.cells);
|
||||
}
|
||||
var hasChanged = this.moveLeft();
|
||||
for (var i = direction; i < 4; ++i) {
|
||||
this.cells = rotateLeft(this.cells);
|
||||
}
|
||||
if (hasChanged) {
|
||||
this.addRandomTile();
|
||||
}
|
||||
this.setPositions();
|
||||
return this;
|
||||
};
|
||||
|
||||
Board.prototype.clearOldTiles = function () {
|
||||
this.tiles = this.tiles.filter(function (tile) { return tile.markForDeletion === false; });
|
||||
this.tiles.forEach(function (tile) { tile.markForDeletion = true; });
|
||||
};
|
||||
|
||||
Board.prototype.hasWon = function () {
|
||||
return this.won;
|
||||
};
|
||||
|
||||
Board.deltaX = [-1, 0, 1, 0];
|
||||
Board.deltaY = [0, -1, 0, 1];
|
||||
|
||||
Board.prototype.hasLost = function () {
|
||||
var canMove = false;
|
||||
for (var row = 0; row < Board.size; ++row) {
|
||||
for (var column = 0; column < Board.size; ++column) {
|
||||
canMove = canMove || (this.cells[row][column].value === 0);
|
||||
for (var dir = 0; dir < 4; ++dir) {
|
||||
var newRow = row + Board.deltaX[dir];
|
||||
var newColumn = column + Board.deltaY[dir];
|
||||
if (newRow < 0 || newRow >= Board.size || newColumn < 0 || newColumn >= Board.size) {
|
||||
continue;
|
||||
}
|
||||
canMove = canMove || (this.cells[row][column].value === this.cells[newRow][newColumn].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return !canMove;
|
||||
};
|
||||
|
||||
module.exports = Board;
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableNativeFeedback,
|
||||
View
|
||||
} = ReactNative;
|
||||
|
||||
var getStyleFromScore = require('./getStyleFromScore');
|
||||
var getImageSource = require('./getImageSource');
|
||||
var getTextFromScore = require('./getTextFromScore');
|
||||
|
||||
class MovieCell extends React.Component {
|
||||
render() {
|
||||
var criticsScore = this.props.movie.ratings.critics_score;
|
||||
var TouchableElement = TouchableHighlight;
|
||||
if (Platform.OS === 'android') {
|
||||
TouchableElement = TouchableNativeFeedback;
|
||||
}
|
||||
return (
|
||||
<View>
|
||||
<TouchableElement
|
||||
onPress={this.props.onSelect}
|
||||
onShowUnderlay={this.props.onHighlight}
|
||||
onHideUnderlay={this.props.onUnhighlight}>
|
||||
<View style={styles.row}>
|
||||
<Image
|
||||
source={getImageSource(this.props.movie, 'det')}
|
||||
style={styles.cellImage}
|
||||
/>
|
||||
<View style={styles.textContainer}>
|
||||
<Text style={styles.movieTitle} numberOfLines={2}>
|
||||
{this.props.movie.title}
|
||||
</Text>
|
||||
<Text style={styles.movieYear} numberOfLines={1}>
|
||||
{this.props.movie.year}
|
||||
{' '}•{' '}
|
||||
<Text style={getStyleFromScore(criticsScore)}>
|
||||
Critics {getTextFromScore(criticsScore)}
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableElement>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
textContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
movieTitle: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
marginBottom: 2,
|
||||
},
|
||||
movieYear: {
|
||||
color: '#999999',
|
||||
fontSize: 12,
|
||||
},
|
||||
row: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'white',
|
||||
flexDirection: 'row',
|
||||
padding: 5,
|
||||
},
|
||||
cellImage: {
|
||||
backgroundColor: '#dddddd',
|
||||
height: 93,
|
||||
marginRight: 10,
|
||||
width: 60,
|
||||
},
|
||||
cellBorder: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
height: StyleSheet.hairlineWidth,
|
||||
marginLeft: 4,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = MovieCell;
|
||||
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
var getImageSource = require('./getImageSource');
|
||||
var getStyleFromScore = require('./getStyleFromScore');
|
||||
var getTextFromScore = require('./getTextFromScore');
|
||||
|
||||
class MovieScreen extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={styles.contentContainer}>
|
||||
<View style={styles.mainSection}>
|
||||
<Image
|
||||
source={getImageSource(this.props.movie, 'det')}
|
||||
style={styles.detailsImage}
|
||||
/>
|
||||
<View style={styles.rightPane}>
|
||||
<Text style={styles.movieTitle}>{this.props.movie.title}</Text>
|
||||
<Text>{this.props.movie.year}</Text>
|
||||
<View style={styles.mpaaWrapper}>
|
||||
<Text style={styles.mpaaText}>
|
||||
{this.props.movie.mpaa_rating}
|
||||
</Text>
|
||||
</View>
|
||||
<Ratings ratings={this.props.movie.ratings} />
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.separator} />
|
||||
<Text>
|
||||
{this.props.movie.synopsis}
|
||||
</Text>
|
||||
<View style={styles.separator} />
|
||||
<Cast actors={this.props.movie.abridged_cast} />
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Ratings extends React.Component {
|
||||
render() {
|
||||
var criticsScore = this.props.ratings.critics_score;
|
||||
var audienceScore = this.props.ratings.audience_score;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.rating}>
|
||||
<Text style={styles.ratingTitle}>Critics:</Text>
|
||||
<Text style={[styles.ratingValue, getStyleFromScore(criticsScore)]}>
|
||||
{getTextFromScore(criticsScore)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.rating}>
|
||||
<Text style={styles.ratingTitle}>Audience:</Text>
|
||||
<Text style={[styles.ratingValue, getStyleFromScore(audienceScore)]}>
|
||||
{getTextFromScore(audienceScore)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Cast extends React.Component {
|
||||
render() {
|
||||
if (!this.props.actors) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text style={styles.castTitle}>Actors</Text>
|
||||
{this.props.actors.map(actor =>
|
||||
<Text key={actor.name} style={styles.castActor}>
|
||||
• {actor.name}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
contentContainer: {
|
||||
padding: 10,
|
||||
},
|
||||
rightPane: {
|
||||
justifyContent: 'space-between',
|
||||
flex: 1,
|
||||
},
|
||||
movieTitle: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
},
|
||||
rating: {
|
||||
marginTop: 10,
|
||||
},
|
||||
ratingTitle: {
|
||||
fontSize: 14,
|
||||
},
|
||||
ratingValue: {
|
||||
fontSize: 28,
|
||||
fontWeight: '500',
|
||||
},
|
||||
mpaaWrapper: {
|
||||
alignSelf: 'flex-start',
|
||||
borderColor: 'black',
|
||||
borderWidth: 1,
|
||||
paddingHorizontal: 3,
|
||||
marginVertical: 5,
|
||||
},
|
||||
mpaaText: {
|
||||
fontFamily: 'Palatino',
|
||||
fontSize: 13,
|
||||
fontWeight: '500',
|
||||
},
|
||||
mainSection: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
detailsImage: {
|
||||
width: 134,
|
||||
height: 200,
|
||||
backgroundColor: '#eaeaea',
|
||||
marginRight: 10,
|
||||
},
|
||||
separator: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
height: StyleSheet.hairlineWidth,
|
||||
marginVertical: 10,
|
||||
},
|
||||
castTitle: {
|
||||
fontWeight: '500',
|
||||
marginBottom: 3,
|
||||
},
|
||||
castActor: {
|
||||
marginLeft: 2,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = MovieScreen;
|
||||
@@ -0,0 +1,520 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341801B1AA91740003F314A /* libRCTNetwork.a */; };
|
||||
13442C061AA90EA00037E5B0 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13442C051AA90E7D0037E5B0 /* libRCTImage.a */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14312D241AC3654D00CDC950 /* libRCTLinking.a */; };
|
||||
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14A2D4411AC3E41A00CC738A /* libReact.a */; };
|
||||
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5725B1AA6236500CDF9C8 /* libRCTText.a */; };
|
||||
67C95F201B0E64A30040BCE2 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1341801A1AA91740003F314A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 134180151AA91740003F314A /* RCTNetwork.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
|
||||
remoteInfo = RCTNetwork;
|
||||
};
|
||||
13442C041AA90E7D0037E5B0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
|
||||
remoteInfo = RCTImage;
|
||||
};
|
||||
14312D231AC3654D00CDC950 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTLinking;
|
||||
};
|
||||
14A2D4401AC3E41A00CC738A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 14A2D43C1AC3E41A00CC738A /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
67C95F1D1B0E647A0040BCE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
134180151AA91740003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* Movies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movies.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Movies/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Movies/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Movies/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Movies/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Movies/main.m; sourceTree = "<group>"; };
|
||||
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
|
||||
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = SOURCE_ROOT; };
|
||||
67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
67C95F201B0E64A30040BCE2 /* libRCTWebSocket.a in Frameworks */,
|
||||
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */,
|
||||
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */,
|
||||
1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */,
|
||||
13442C061AA90EA00037E5B0 /* libRCTImage.a in Frameworks */,
|
||||
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
134180161AA91740003F314A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1341801B1AA91740003F314A /* libRCTNetwork.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13442C011AA90E7D0037E5B0 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13442C051AA90E7D0037E5B0 /* libRCTImage.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FAE1A68108700A75B9A /* Movies */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
);
|
||||
name = Movies;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
14312D1F1AC3654D00CDC950 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
14312D241AC3654D00CDC950 /* libRCTLinking.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
14A2D43D1AC3E41A00CC738A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
14A2D4411AC3E41A00CC738A /* libReact.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58C571FC1AA6124500CDF9C8 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */,
|
||||
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */,
|
||||
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */,
|
||||
134180151AA91740003F314A /* RCTNetwork.xcodeproj */,
|
||||
13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */,
|
||||
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58C572571AA6236500CDF9C8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
58C5725B1AA6236500CDF9C8 /* libRCTText.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
67C95F161B0E647A0040BCE2 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* Movies */,
|
||||
58C571FC1AA6124500CDF9C8 /* Libraries */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* Movies.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
13B07F861A680F5B00A75B9A /* Movies */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Movies" */;
|
||||
buildPhases = (
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
68ACCCEE1D2BE57F008E368A /* ShellScript */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Movies;
|
||||
productName = "Hello World";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* Movies.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Movies" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 13442C011AA90E7D0037E5B0 /* Products */;
|
||||
ProjectRef = 13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 14312D1F1AC3654D00CDC950 /* Products */;
|
||||
ProjectRef = 14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 134180161AA91740003F314A /* Products */;
|
||||
ProjectRef = 134180151AA91740003F314A /* RCTNetwork.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 58C572571AA6236500CDF9C8 /* Products */;
|
||||
ProjectRef = 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 67C95F161B0E647A0040BCE2 /* Products */;
|
||||
ProjectRef = 67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 14A2D43D1AC3E41A00CC738A /* Products */;
|
||||
ProjectRef = 14A2D43C1AC3E41A00CC738A /* React.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* Movies */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
1341801B1AA91740003F314A /* libRCTNetwork.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTNetwork.a;
|
||||
remoteRef = 1341801A1AA91740003F314A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
13442C051AA90E7D0037E5B0 /* libRCTImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTImage.a;
|
||||
remoteRef = 13442C041AA90E7D0037E5B0 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
14312D241AC3654D00CDC950 /* libRCTLinking.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTLinking.a;
|
||||
remoteRef = 14312D231AC3654D00CDC950 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
14A2D4411AC3E41A00CC738A /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 14A2D4401AC3E41A00CC738A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
58C5725B1AA6236500CDF9C8 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTText.a;
|
||||
remoteRef = 58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 67C95F1D1B0E647A0040BCE2 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
68ACCCEE1D2BE57F008E368A /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n$SRCROOT/../../packager/react-native-xcode.sh Examples/Movies/MoviesApp.ios.js\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
path = Movies;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Movies/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = Movies;
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../Libraries/**";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Movies/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = Movies;
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../Libraries/**";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Movies" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
13B07F951A680F5B00A75B9A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Movies" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
83CBBA211A601CBA00E9B192 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTBundleURLProvider.h"
|
||||
#import "RCTLinkingManager.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"Examples/Movies/MoviesApp.ios" fallbackResource:nil];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"MoviesApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation
|
||||
{
|
||||
return [RCTLinkingManager application:application
|
||||
openURL:url
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Movies" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>movies</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule MoviesApp
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
BackAndroid,
|
||||
Navigator,
|
||||
StyleSheet,
|
||||
ToolbarAndroid,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
var MovieScreen = require('./MovieScreen');
|
||||
var SearchScreen = require('./SearchScreen');
|
||||
|
||||
var _navigator;
|
||||
BackAndroid.addEventListener('hardwareBackPress', () => {
|
||||
if (_navigator && _navigator.getCurrentRoutes().length > 1) {
|
||||
_navigator.pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
var RouteMapper = function(route, navigationOperations, onComponentRef) {
|
||||
_navigator = navigationOperations;
|
||||
if (route.name === 'search') {
|
||||
return (
|
||||
<SearchScreen navigator={navigationOperations} />
|
||||
);
|
||||
} else if (route.name === 'movie') {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<ToolbarAndroid
|
||||
actions={[]}
|
||||
navIcon={require('image!android_back_white')}
|
||||
onIconClicked={navigationOperations.pop}
|
||||
style={styles.toolbar}
|
||||
titleColor="white"
|
||||
title={route.movie.title} />
|
||||
<MovieScreen
|
||||
style={{flex: 1}}
|
||||
navigator={navigationOperations}
|
||||
movie={route.movie}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class MoviesApp extends React.Component {
|
||||
render() {
|
||||
var initialRoute = {name: 'search'};
|
||||
return (
|
||||
<Navigator
|
||||
style={styles.container}
|
||||
initialRoute={initialRoute}
|
||||
configureScene={() => Navigator.SceneConfigs.FadeAndroid}
|
||||
renderScene={RouteMapper}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
toolbar: {
|
||||
backgroundColor: '#a9a9a9',
|
||||
height: 56,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('MoviesApp', () => MoviesApp);
|
||||
|
||||
module.exports = MoviesApp;
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule MoviesApp
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
NavigatorIOS,
|
||||
StyleSheet,
|
||||
} = ReactNative;
|
||||
|
||||
var SearchScreen = require('./SearchScreen');
|
||||
|
||||
class MoviesApp extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
initialRoute={{
|
||||
title: 'Movies',
|
||||
component: SearchScreen,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('MoviesApp', () => MoviesApp);
|
||||
|
||||
module.exports = MoviesApp;
|
||||
@@ -0,0 +1,57 @@
|
||||
# Movies app
|
||||
|
||||
The Movies app is a demonstration of basic concepts, such as fetching data, rendering a list of data including images, and navigating between different screens.
|
||||
|
||||
## Running this app
|
||||
|
||||
Before running the app, make sure you ran:
|
||||
|
||||
git clone https://github.com/facebook/react-native.git
|
||||
cd react-native
|
||||
npm install
|
||||
|
||||
### Running on iOS
|
||||
|
||||
Mac OS and Xcode are required.
|
||||
|
||||
- Open `Examples/Movies/Movies.xcodeproj` in Xcode
|
||||
- Hit the Run button
|
||||
|
||||
See [Running on device](https://facebook.github.io/react-native/docs/running-on-device-ios.html) if you want to use a physical device.
|
||||
|
||||
### Running on Android
|
||||
|
||||
You'll need to have all the [prerequisites](https://github.com/facebook/react-native/tree/master/ReactAndroid#prerequisites) (SDK, NDK) for Building React Native installed.
|
||||
|
||||
Start an Android emulator ([Genymotion](https://www.genymotion.com) is recommended).
|
||||
|
||||
cd react-native
|
||||
./gradlew :Examples:Movies:android:app:installDebug
|
||||
./packager/packager.sh
|
||||
|
||||
_Note: Building for the first time can take a while._
|
||||
|
||||
Open the Movies app in your emulator.
|
||||
|
||||
See [Running on Device](https://facebook.github.io/react-native/docs/running-on-device-android.html) in case you want to use a physical device.
|
||||
|
||||
### Running with Buck
|
||||
|
||||
Follow the same setup as running with gradle.
|
||||
|
||||
Install Buck from [here](https://buckbuild.com/setup/install.html).
|
||||
|
||||
Run the following commands from the react-native folder:
|
||||
|
||||
./gradlew :ReactAndroid:packageReactNdkLibsForBuck
|
||||
buck fetch movies
|
||||
buck install -r movies
|
||||
./packager/packager.sh
|
||||
|
||||
_Note: The native libs are still built using gradle. Full build with buck is coming soon(tm)._
|
||||
|
||||
## Built from source
|
||||
|
||||
Building the app on both iOS and Android means building the React Native framework from source. This way you're running the latest native and JS code the way you see it in your clone of the github repo.
|
||||
|
||||
This is different from apps created using `react-native init` which have a dependency on a specific version of React Native JS and native code, declared in a `package.json` file (and `build.gradle` for Android apps).
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule SearchBar
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
Platform,
|
||||
ActivityIndicator,
|
||||
TextInput,
|
||||
StyleSheet,
|
||||
TouchableNativeFeedback,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
var IS_RIPPLE_EFFECT_SUPPORTED = Platform.Version >= 21;
|
||||
|
||||
class SearchBar extends React.Component {
|
||||
render() {
|
||||
var background = IS_RIPPLE_EFFECT_SUPPORTED ?
|
||||
TouchableNativeFeedback.SelectableBackgroundBorderless() :
|
||||
TouchableNativeFeedback.SelectableBackground();
|
||||
return (
|
||||
<View style={styles.searchBar}>
|
||||
<TouchableNativeFeedback
|
||||
background={background}
|
||||
onPress={() => this.refs.input && this.refs.input.focus()}>
|
||||
<View>
|
||||
<Image
|
||||
source={require('image!android_search_white')}
|
||||
style={styles.icon}
|
||||
/>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
<TextInput
|
||||
ref="input"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
autoFocus={true}
|
||||
onChange={this.props.onSearchChange}
|
||||
placeholder="Search a movie..."
|
||||
placeholderTextColor="rgba(255, 255, 255, 0.5)"
|
||||
onFocus={this.props.onFocus}
|
||||
style={styles.searchBarInput}
|
||||
/>
|
||||
<ActivityIndicator
|
||||
animating={this.props.isLoading}
|
||||
color="white"
|
||||
size="large"
|
||||
style={styles.spinner}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
searchBar: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#a9a9a9',
|
||||
height: 56,
|
||||
},
|
||||
searchBarInput: {
|
||||
flex: 1,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
height: 50,
|
||||
padding: 0,
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
spinner: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
marginRight: 16,
|
||||
},
|
||||
icon: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SearchBar;
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule SearchBar
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
ActivityIndicator,
|
||||
TextInput,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
class SearchBar extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.searchBar}>
|
||||
<TextInput
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
onChange={this.props.onSearchChange}
|
||||
placeholder="Search a movie..."
|
||||
onFocus={this.props.onFocus}
|
||||
style={styles.searchBarInput}
|
||||
/>
|
||||
<ActivityIndicator
|
||||
animating={this.props.isLoading}
|
||||
style={styles.spinner}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
searchBar: {
|
||||
marginTop: 64,
|
||||
padding: 3,
|
||||
paddingLeft: 8,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
searchBarInput: {
|
||||
fontSize: 15,
|
||||
flex: 1,
|
||||
height: 30,
|
||||
},
|
||||
spinner: {
|
||||
width: 30,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SearchBar;
|
||||
@@ -0,0 +1,369 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
ActivityIndicator,
|
||||
ListView,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = ReactNative;
|
||||
var TimerMixin = require('react-timer-mixin');
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var dismissKeyboard = require('dismissKeyboard');
|
||||
|
||||
var MovieCell = require('./MovieCell');
|
||||
var MovieScreen = require('./MovieScreen');
|
||||
var SearchBar = require('SearchBar');
|
||||
|
||||
/**
|
||||
* This is for demo purposes only, and rate limited.
|
||||
* In case you want to use the Rotten Tomatoes' API on a real app you should
|
||||
* create an account at http://developer.rottentomatoes.com/
|
||||
*/
|
||||
var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/';
|
||||
var API_KEYS = [
|
||||
'7waqfqbprs7pajbz28mqf6vz',
|
||||
// 'y4vwv8m33hed9ety83jmv52f', Fallback api_key
|
||||
];
|
||||
|
||||
// Results should be cached keyed by the query
|
||||
// with values of null meaning "being fetched"
|
||||
// and anything besides null and undefined
|
||||
// as the result of a valid query
|
||||
var resultsCache = {
|
||||
dataForQuery: {},
|
||||
nextPageNumberForQuery: {},
|
||||
totalForQuery: {},
|
||||
};
|
||||
|
||||
var LOADING = {};
|
||||
|
||||
var SearchScreen = React.createClass({
|
||||
mixins: [TimerMixin],
|
||||
|
||||
timeoutID: (null: any),
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isLoadingTail: false,
|
||||
dataSource: new ListView.DataSource({
|
||||
rowHasChanged: (row1, row2) => row1 !== row2,
|
||||
}),
|
||||
filter: '',
|
||||
queryNumber: 0,
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.searchMovies('');
|
||||
},
|
||||
|
||||
_urlForQueryAndPage: function(query: string, pageNumber: number): string {
|
||||
var apiKey = API_KEYS[this.state.queryNumber % API_KEYS.length];
|
||||
if (query) {
|
||||
return (
|
||||
API_URL + 'movies.json?apikey=' + apiKey + '&q=' +
|
||||
encodeURIComponent(query) + '&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
} else {
|
||||
// With no query, load latest movies
|
||||
return (
|
||||
API_URL + 'lists/movies/in_theaters.json?apikey=' + apiKey +
|
||||
'&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
searchMovies: function(query: string) {
|
||||
this.timeoutID = null;
|
||||
|
||||
this.setState({filter: query});
|
||||
|
||||
var cachedResultsForQuery = resultsCache.dataForQuery[query];
|
||||
if (cachedResultsForQuery) {
|
||||
if (!LOADING[query]) {
|
||||
this.setState({
|
||||
dataSource: this.getDataSource(cachedResultsForQuery),
|
||||
isLoading: false
|
||||
});
|
||||
} else {
|
||||
this.setState({isLoading: true});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LOADING[query] = true;
|
||||
resultsCache.dataForQuery[query] = null;
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
queryNumber: this.state.queryNumber + 1,
|
||||
isLoadingTail: false,
|
||||
});
|
||||
|
||||
fetch(this._urlForQueryAndPage(query, 1))
|
||||
.then((response) => response.json())
|
||||
.catch((error) => {
|
||||
LOADING[query] = false;
|
||||
resultsCache.dataForQuery[query] = undefined;
|
||||
|
||||
this.setState({
|
||||
dataSource: this.getDataSource([]),
|
||||
isLoading: false,
|
||||
});
|
||||
})
|
||||
.then((responseData) => {
|
||||
LOADING[query] = false;
|
||||
resultsCache.totalForQuery[query] = responseData.total;
|
||||
resultsCache.dataForQuery[query] = responseData.movies;
|
||||
resultsCache.nextPageNumberForQuery[query] = 2;
|
||||
|
||||
if (this.state.filter !== query) {
|
||||
// do not update state if the query is stale
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
dataSource: this.getDataSource(responseData.movies),
|
||||
});
|
||||
})
|
||||
.done();
|
||||
},
|
||||
|
||||
hasMore: function(): boolean {
|
||||
var query = this.state.filter;
|
||||
if (!resultsCache.dataForQuery[query]) {
|
||||
return true;
|
||||
}
|
||||
return (
|
||||
resultsCache.totalForQuery[query] !==
|
||||
resultsCache.dataForQuery[query].length
|
||||
);
|
||||
},
|
||||
|
||||
onEndReached: function() {
|
||||
var query = this.state.filter;
|
||||
if (!this.hasMore() || this.state.isLoadingTail) {
|
||||
// We're already fetching or have all the elements so noop
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOADING[query]) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOADING[query] = true;
|
||||
this.setState({
|
||||
queryNumber: this.state.queryNumber + 1,
|
||||
isLoadingTail: true,
|
||||
});
|
||||
|
||||
var page = resultsCache.nextPageNumberForQuery[query];
|
||||
invariant(page != null, 'Next page number for "%s" is missing', query);
|
||||
fetch(this._urlForQueryAndPage(query, page))
|
||||
.then((response) => response.json())
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
LOADING[query] = false;
|
||||
this.setState({
|
||||
isLoadingTail: false,
|
||||
});
|
||||
})
|
||||
.then((responseData) => {
|
||||
var moviesForQuery = resultsCache.dataForQuery[query].slice();
|
||||
|
||||
LOADING[query] = false;
|
||||
// We reached the end of the list before the expected number of results
|
||||
if (!responseData.movies) {
|
||||
resultsCache.totalForQuery[query] = moviesForQuery.length;
|
||||
} else {
|
||||
for (var i in responseData.movies) {
|
||||
moviesForQuery.push(responseData.movies[i]);
|
||||
}
|
||||
resultsCache.dataForQuery[query] = moviesForQuery;
|
||||
resultsCache.nextPageNumberForQuery[query] += 1;
|
||||
}
|
||||
|
||||
if (this.state.filter !== query) {
|
||||
// do not update state if the query is stale
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isLoadingTail: false,
|
||||
dataSource: this.getDataSource(resultsCache.dataForQuery[query]),
|
||||
});
|
||||
})
|
||||
.done();
|
||||
},
|
||||
|
||||
getDataSource: function(movies: Array<any>): ListView.DataSource {
|
||||
return this.state.dataSource.cloneWithRows(movies);
|
||||
},
|
||||
|
||||
selectMovie: function(movie: Object) {
|
||||
if (Platform.OS === 'ios') {
|
||||
this.props.navigator.push({
|
||||
title: movie.title,
|
||||
component: MovieScreen,
|
||||
passProps: {movie},
|
||||
});
|
||||
} else {
|
||||
dismissKeyboard();
|
||||
this.props.navigator.push({
|
||||
title: movie.title,
|
||||
name: 'movie',
|
||||
movie: movie,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onSearchChange: function(event: Object) {
|
||||
var filter = event.nativeEvent.text.toLowerCase();
|
||||
|
||||
this.clearTimeout(this.timeoutID);
|
||||
this.timeoutID = this.setTimeout(() => this.searchMovies(filter), 100);
|
||||
},
|
||||
|
||||
renderFooter: function() {
|
||||
if (!this.hasMore() || !this.state.isLoadingTail) {
|
||||
return <View style={styles.scrollSpinner} />;
|
||||
}
|
||||
|
||||
return <ActivityIndicator style={styles.scrollSpinner} />;
|
||||
},
|
||||
|
||||
renderSeparator: function(
|
||||
sectionID: number | string,
|
||||
rowID: number | string,
|
||||
adjacentRowHighlighted: boolean
|
||||
) {
|
||||
var style = styles.rowSeparator;
|
||||
if (adjacentRowHighlighted) {
|
||||
style = [style, styles.rowSeparatorHide];
|
||||
}
|
||||
return (
|
||||
<View key={'SEP_' + sectionID + '_' + rowID} style={style}/>
|
||||
);
|
||||
},
|
||||
|
||||
renderRow: function(
|
||||
movie: Object,
|
||||
sectionID: number | string,
|
||||
rowID: number | string,
|
||||
highlightRowFunc: (sectionID: ?number | string, rowID: ?number | string) => void,
|
||||
) {
|
||||
return (
|
||||
<MovieCell
|
||||
key={movie.id}
|
||||
onSelect={() => this.selectMovie(movie)}
|
||||
onHighlight={() => highlightRowFunc(sectionID, rowID)}
|
||||
onUnhighlight={() => highlightRowFunc(null, null)}
|
||||
movie={movie}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var content = this.state.dataSource.getRowCount() === 0 ?
|
||||
<NoMovies
|
||||
filter={this.state.filter}
|
||||
isLoading={this.state.isLoading}
|
||||
/> :
|
||||
<ListView
|
||||
ref="listview"
|
||||
renderSeparator={this.renderSeparator}
|
||||
dataSource={this.state.dataSource}
|
||||
renderFooter={this.renderFooter}
|
||||
renderRow={this.renderRow}
|
||||
onEndReached={this.onEndReached}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
keyboardDismissMode="on-drag"
|
||||
keyboardShouldPersistTaps={true}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<SearchBar
|
||||
onSearchChange={this.onSearchChange}
|
||||
isLoading={this.state.isLoading}
|
||||
onFocus={() =>
|
||||
this.refs.listview && this.refs.listview.getScrollResponder().scrollTo({ x: 0, y: 0 })}
|
||||
/>
|
||||
<View style={styles.separator} />
|
||||
{content}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
class NoMovies extends React.Component {
|
||||
render() {
|
||||
var text = '';
|
||||
if (this.props.filter) {
|
||||
text = `No results for "${this.props.filter}"`;
|
||||
} else if (!this.props.isLoading) {
|
||||
// If we're looking at the latest movies, aren't currently loading, and
|
||||
// still have no results, show a message
|
||||
text = 'No movies found';
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.container, styles.centerText]}>
|
||||
<Text style={styles.noMoviesText}>{text}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
centerText: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
noMoviesText: {
|
||||
marginTop: 80,
|
||||
color: '#888888',
|
||||
},
|
||||
separator: {
|
||||
height: 1,
|
||||
backgroundColor: '#eeeeee',
|
||||
},
|
||||
scrollSpinner: {
|
||||
marginVertical: 20,
|
||||
},
|
||||
rowSeparator: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
height: 1,
|
||||
marginLeft: 4,
|
||||
},
|
||||
rowSeparatorHide: {
|
||||
opacity: 0.0,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SearchScreen;
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
jest.unmock('../getImageSource');
|
||||
|
||||
var getImageSource = require('../getImageSource');
|
||||
|
||||
describe('getImageSource', () => {
|
||||
it('returns null for invalid input', () => {
|
||||
expect(getImageSource().uri).toBe(null);
|
||||
});
|
||||
|
||||
it('returns a movie thumbnail', () => {
|
||||
var uri = 'https://facebook.com';
|
||||
var source = {
|
||||
posters: {
|
||||
thumbnail: uri,
|
||||
},
|
||||
};
|
||||
expect(getImageSource(source).uri).toBe(uri);
|
||||
});
|
||||
|
||||
it('returns a movie thumbnail with kind', () => {
|
||||
var uri = 'https://facebook.com?tmb';
|
||||
var source = {
|
||||
posters: {
|
||||
thumbnail: uri,
|
||||
},
|
||||
};
|
||||
expect(getImageSource(source, 'kind').uri).toBe(
|
||||
'https://facebook.com?kind'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
include_defs('//ReactAndroid/DEFS')
|
||||
|
||||
android_binary(
|
||||
name = 'app',
|
||||
manifest = 'src/main/AndroidManifest.xml',
|
||||
keystore = '//keystores:debug',
|
||||
deps = [
|
||||
':movies-lib',
|
||||
],
|
||||
)
|
||||
|
||||
android_library(
|
||||
name = 'movies-lib',
|
||||
srcs = glob(['src/main/java/**/*.java']),
|
||||
deps = [
|
||||
':res',
|
||||
react_native_dep('third-party/java/jsr-305:jsr-305'),
|
||||
react_native_target('java/com/facebook/react/modules/core:core'),
|
||||
react_native_target('java/com/facebook/react/shell:shell'),
|
||||
react_native_target('java/com/facebook/react:react'),
|
||||
react_native_target('jni/prebuilt:android-jsc'),
|
||||
# .so files are prebuilt by Gradle with `./gradlew :ReactAndroid:packageReactNdkLibsForBuck`
|
||||
react_native_target('jni/prebuilt:reactnative-libs'),
|
||||
],
|
||||
)
|
||||
|
||||
android_resource(
|
||||
name = 'res',
|
||||
res = 'src/main/res',
|
||||
package = 'com.facebook.react.movies',
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user