name: Test All on: workflow_dispatch: inputs: run-e2e-tests: description: Whether to run E2E tests or not type: boolean default: false 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 echo "Should I run E2E tests? ${{ inputs.run-e2e-tests }}" prepare_hermes_workspace: runs-on: ubuntu-latest env: HERMES_WS_DIR: /tmp/hermes HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion 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 - 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_hermesc_apple: runs-on: macos-13 needs: prepare_hermes_workspace env: HERMES_WS_DIR: /tmp/hermes steps: - name: Checkout uses: actions/checkout@v4 - name: Build HermesC Apple uses: ./.github/actions/build-hermesc-apple with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} 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: "15.1" XROS_DEPLOYMENT_TARGET: "1.0" MAC_DEPLOYMENT_TARGET: "10.15" strategy: fail-fast: false matrix: flavor: [Debug, Release] slice: [macosx, iphoneos, iphonesimulator, catalyst, xros, xrsimulator] steps: - name: Checkout uses: actions/checkout@v4 - name: Build Slice uses: ./.github/actions/build-apple-slices-hermes with: flavor: ${{ matrix.flavor }} slice: ${{ matrix.slice}} hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} 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 - name: Build Hermes MacOS uses: ./.github/actions/build-hermes-macos with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} flavor: ${{ matrix.flavor }} 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 - 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 - 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 - name: Run it uses: ./.github/actions/test-ios-rntester with: jsengine: ${{ matrix.jsengine }} architecture: ${{ matrix.architecture }} run-unit-tests: "false" use-frameworks: StaticLibraries hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} test_e2e_ios_rntester: if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }} 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] flavor: [Debug, Release] steps: - name: Checkout uses: actions/checkout@v4 - name: Run it uses: ./.github/actions/test-ios-rntester with: jsengine: ${{ matrix.jsengine }} architecture: ${{ matrix.architecture }} run-unit-tests: "false" use-frameworks: StaticLibraries hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} run-e2e-tests: "true" flavor: ${{ matrix.flavor }} - name: Run E2E Tests uses: ./.github/actions/maestro-ios with: app-path: "/tmp/RNTesterBuild/Build/Products/${{ matrix.flavor }}-iphonesimulator/RNTester.app" app-id: com.meta.RNTester.localDevelopment jsengine: ${{ matrix.jsengine }} maestro-flow: ./packages/rn-tester/.maestro/ flavor: ${{ matrix.flavor }} test_e2e_ios_templateapp: if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }} runs-on: macos-13 needs: build_npm_package 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] flavor: [Debug, Release] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup xcode uses: ./.github/actions/setup-xcode - name: Setup node.js uses: ./.github/actions/setup-node - name: Run yarn uses: ./.github/actions/yarn-install-with-cache - name: Setup ruby uses: ruby/setup-ruby@v1.170.0 with: ruby-version: 2.6.10 - name: Download Hermes uses: actions/download-artifact@v4 with: name: hermes-darwin-bin-${{matrix.flavor}} path: /tmp/react-native-tmp - name: Download React Native Package uses: actions/download-artifact@v4 with: name: react-native-package path: /tmp/react-native-tmp - name: Print /tmp folder run: ls -lR /tmp/react-native-tmp - name: Prepare artifacts run: | REACT_NATIVE_PKG=$(find /tmp/react-native-tmp -type f -name "*.tgz") echo "React Native tgs is $REACT_NATIVE_PKG" HERMES_PATH=$(find /tmp/react-native-tmp -type f -name "*.tar.gz") echo "Hermes path is $HERMES_PATH" # For stable branches, we want to use the stable branch of the template # In all the other cases, we want to use "main" BRANCH=${{ github.ref_name }} if ! [[ $BRANCH == *-stable* ]]; then BRANCH=main fi node ./scripts/e2e/init-project-e2e.js --projectName RNTestProject --currentBranch $BRANCH --directory /tmp/RNTestProject --pathToLocalReactNative $REACT_NATIVE_PKG cd /tmp/RNTestProject/ios bundle install HERMES_ENGINE_TARBALL_PATH=$HERMES_PATH bundle exec pod install xcodebuild \ -scheme "RNTestProject" \ -workspace RNTestProject.xcworkspace \ -configuration "${{ matrix.flavor }}" \ -sdk "iphonesimulator" \ -destination "generic/platform=iOS Simulator" \ -derivedDataPath "/tmp/RNTestProject" - name: Run E2E Tests uses: ./.github/actions/maestro-ios with: app-path: "/tmp/RNTestProject/Build/Products/${{ matrix.flavor }}-iphonesimulator/RNTestProject.app" app-id: org.reactjs.native.example.RNTestProject jsengine: ${{ matrix.jsengine }} maestro-flow: ./scripts/e2e/.maestro/ flavor: ${{ matrix.flavor }} working-directory: /tmp/RNTestProject test_e2e_android_templateapp: if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }} runs-on: 4-core-ubuntu needs: build_npm_package continue-on-error: true strategy: fail-fast: false matrix: jsengine: [Hermes, JSC] flavor: [debug, release] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup node.js uses: ./.github/actions/setup-node - name: Run yarn uses: ./.github/actions/yarn-install-with-cache - name: Set up JDK 17 uses: actions/setup-java@v2 with: java-version: '17' distribution: 'zulu' - name: Download Maven Local uses: actions/download-artifact@v4 with: name: maven-local path: /tmp/react-native-tmp/maven-local - name: Download React Native Package uses: actions/download-artifact@v4 with: name: react-native-package path: /tmp/react-native-tmp - name: Print /tmp folder run: ls -lR /tmp/react-native-tmp - name: Prepare artifacts id: prepare-artifacts run: | REACT_NATIVE_PKG=$(find /tmp/react-native-tmp -type f -name "*.tgz") echo "React Native tgs is $REACT_NATIVE_PKG" MAVEN_LOCAL=/tmp/react-native-tmp/maven-local echo "Maven local path is $MAVEN_LOCAL" # For stable branches, we want to use the stable branch of the template # In all the other cases, we want to use "main" BRANCH=${{ github.ref_name }} if ! [[ $BRANCH == *-stable* ]]; then BRANCH=main fi node ./scripts/e2e/init-project-e2e.js --projectName RNTestProject --currentBranch $BRANCH --directory /tmp/RNTestProject --pathToLocalReactNative $REACT_NATIVE_PKG echo "Feed maven local to gradle.properties" cd /tmp/RNTestProject echo "react.internal.mavenLocalRepo=$MAVEN_LOCAL" >> android/gradle.properties # Build cd android CAPITALIZED_FLAVOR=$(echo "${{ matrix.flavor }}" | awk '{print toupper(substr($0, 1, 1)) substr($0, 2)}') ./gradlew assemble$CAPITALIZED_FLAVOR --no-daemon -PreactNativeArchitectures=x86 - name: Run E2E Tests uses: ./.github/actions/maestro-android with: app-path: /tmp/RNTestProject/android/app/build/outputs/apk/${{ matrix.flavor }}/app-${{ matrix.flavor }}.apk app-id: com.rntestproject jsengine: ${{ matrix.jsengine }} maestro-flow: ./scripts/e2e/.maestro/ install-java: 'false' flavor: ${{ matrix.flavor }} working-directory: /tmp/RNTestProject 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 - name: Build HermesC Linux uses: ./.github/actions/build-hermesc-linux with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} 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 - name: Build HermesC Windows uses: ./.github/actions/build-hermesc-windows with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} 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" ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} steps: - name: Checkout uses: actions/checkout@v4 - name: Build Android uses: ./.github/actions/build-android with: release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} run-e2e-tests: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }} test_e2e_android_rntester: if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }} runs-on: ubuntu-latest needs: [build_android] strategy: fail-fast: false matrix: jsengine: [hermes, jsc] flavor: [debug, release] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup node.js uses: ./.github/actions/setup-node - name: Install node dependencies uses: ./.github/actions/yarn-install-with-cache - name: Download APK uses: actions/download-artifact@v4 with: name: rntester-${{ matrix.jsengine }}-${{ matrix.flavor }} path: ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.jsengine }}/${{ matrix.flavor }}/ - name: Print folder structure run: ls -lR ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.jsengine }}/${{ matrix.flavor }}/ - name: Run E2E Tests uses: ./.github/actions/maestro-android with: app-path: ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.jsengine }}/${{ matrix.flavor }}/app-${{ matrix.jsengine }}-x86-${{ matrix.flavor }}.apk app-id: com.facebook.react.uiapp jsengine: ${{ matrix.jsengine }} maestro-flow: ./packages/rn-tester/.maestro flavor: ${{ matrix.flavor }} 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" env: HERMES_WS_DIR: /tmp/hermes steps: - name: Checkout uses: actions/checkout@v4 - name: Build NPM Package uses: ./.github/actions/build-npm-package with: hermes-ws-dir: ${{ env.HERMES_WS_DIR }} release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} test_android_helloworld: runs-on: 4-core-ubuntu needs: build_npm_package 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 - name: Setup git safe folders run: git config --global --add safe.directory '*' - name: Download npm package artifact uses: actions/download-artifact@v4.1.3 with: name: react-native-package path: build - name: Download maven-local artifact uses: actions/download-artifact@v4.1.3 with: name: maven-local path: /tmp/maven-local - name: Setup gradle uses: ./.github/actions/setup-gradle - name: Run yarn install uses: ./.github/actions/yarn-install-with-cache - name: Prepare the Helloworld application shell: bash run: node ./scripts/e2e/init-project-e2e.js --useHelloWorld --pathToLocalReactNative "$GITHUB_WORKSPACE/build/$(cat build/react-native-package-version)" - 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" -P react.internal.mavenLocalRepo="/tmp/maven-local" - name: Upload artifact uses: actions/upload-artifact@v4.3.4 with: name: helloworld-apk-${{ matrix.flavor }}-${{ matrix.architecture }}-${{ matrix.jsengine }} path: ./packages/helloworld/android/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 - 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 - 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 }} test_js: runs-on: ubuntu-latest strategy: fail-fast: false matrix: node-version: ["20", "18"] steps: - name: Checkout uses: actions/checkout@v4 - name: Test JS uses: ./.github/actions/test-js with: node-version: ${{ matrix.node-version }} lint: runs-on: ubuntu-latest env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout uses: actions/checkout@v4 - name: Run all the Linters uses: ./.github/actions/lint with: github-token: ${{ env.GH_TOKEN }}