react-native-macos/.circleci/configurations/jobs.yml

1282 строки
48 KiB
YAML

# -------------------------
# JOBS
# -------------------------
jobs:
# -------------------------
# JOBS: Analyze PR
# -------------------------
# Analyze pull request and raise any lint/flow issues.
# Issues will be posted to the PR itself via GitHub bots.
# This workflow should only fail if the bots fail to run.
analyze_pr:
executor: node-browsers-medium
steps:
- checkout
- run_yarn
- run:
name: Run linters against modified files (analysis-bot)
command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" yarn lint-ci
# -------------------------
# JOBS: Analyze Code
# -------------------------
analyze_code:
executor: node-browsers-small
steps:
- checkout
- run_yarn
- run:
name: Lint code
command: scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ./reports/junit/eslint/results.xml
when: always
- run:
name: Lint Java
command: scripts/circleci/exec_swallow_error.sh yarn lint-java --check
when: always
- run:
name: Set server.max_workers=1 in .flowconfig
command: |
sed -i '/\[options\]/a server.max_workers=1' .flowconfig
when: always
- run:
name: Check for errors in code using Flow (iOS)
command: yarn flow-check
when: always
- run:
name: Check for errors in code using Flow (Android)
command: yarn flow-check
when: always
- run:
name: Run TypeScript tests
command: yarn test-typescript
when: always
- run:
name: Sanity checks
command: |
./scripts/circleci/check_license.sh
./scripts/circleci/validate_yarn_lockfile.sh
when: always
- run:
name: Check formatting
command: yarn run format-check
when: always
- store_test_results:
path: ./reports/junit
# -------------------------
# JOBS: Test JavaScript
# -------------------------
test_js:
parameters:
executor:
type: executor
default: nodelts
run_disabled_tests:
type: boolean
default: false
executor: << parameters.executor >>
steps:
- checkout
- run_yarn
- run:
name: Install rsync
command: sudo apt update && sudo apt install rsync
# -------------------------
# Run JavaScript tests
- run:
name: "Run Tests: JavaScript Tests"
command: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2
- run_e2e:
platform: js
# Optionally, run disabled tests
- when:
condition: << parameters.run_disabled_tests >>
steps:
- run: echo "Failing tests may be moved here temporarily."
# -------------------------
- store_test_results:
path: ./reports/junit
# -------------------------
# JOBS: iOS E2E Tests
# -------------------------
test_e2e_ios:
executor: reactnativeios
parameters:
ruby_version:
default: "2.7.7"
description: The version of ruby that must be used
type: string
steps:
- checkout_code_with_cache
- run_yarn
- setup_hermes_version
- run:
name: Install appium
command: npm install appium@2.0.0 -g
- run:
name: Install appium drivers
command: |
appium driver install uiautomator2
appium driver install xcuitest
- run:
name: Start Appium server
command: appium --base-path /wd/hub
background: true
- run:
name: Start Metro
command: |
cd packages/rn-tester
yarn start
background: true
- brew_install:
package: cmake
- setup_ruby:
ruby_version: << parameters.ruby_version >>
- run:
name: Boot iOS Simulator
command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true
- with_xcodebuild_cache:
steps:
- run:
name: Install Bundler
command: |
cd packages/rn-tester
bundle check || bundle install
bundle exec pod setup
RCT_NEW_ARCH_ENABLED=1 bundle exec pod install --verbose
- run:
name: Build app
command: |
xcodebuild build \
-workspace packages/rn-tester/RNTesterPods.xcworkspace \
-configuration Debug \
-scheme RNTester \
-sdk iphonesimulator \
-derivedDataPath /tmp/e2e/
- run:
name: Move app to correct directory
command: mv /tmp/e2e/Build/Products/Debug-iphonesimulator/RNTester.app packages/rn-tester-e2e/apps/rn-tester.app
- run:
name: Check Appium server status
command: scripts/circleci/check_appium_server_status.sh
- run:
name: Run E2E tests
no_output_timeout: 30m
command: |
cd packages/rn-tester-e2e
(yarn test-e2e ios 2>&1 | tee /tmp/test_log) || true
- store_artifacts:
path: /tmp/test_log
# -------------------------
# JOBS: Android E2E Tests
# -------------------------
test_e2e_android:
executor:
name: android/android-machine
tag: 2023.07.1
steps:
- checkout_code_with_cache
- run_yarn
- android/create-avd:
avd-name: e2e_emulator
system-image: system-images;android-34;google_apis;x86_64
install: true
- android/start-emulator:
avd-name: e2e_emulator
no-window: true
restore-gradle-cache-prefix: v1a
post-emulator-launch-assemble-command: ""
- run:
name: Install appium
command: npm install appium@2.0.0 -g
- run:
name: Install appium drivers
command: |
appium driver install uiautomator2@2.29.1
appium driver install xcuitest@4.32.10
- run:
name: Start Appium server
command: appium --base-path /wd/hub
background: true
- run:
name: Start Metro
command: |
cd packages/rn-tester
yarn start
background: true
- with_gradle_cache:
steps:
- run:
name: Build app
command: |
./gradlew :packages:rn-tester:android:app:assembleHermesDebug -PreactNativeArchitectures=x86_64
- run:
name: Move app to correct directory
command: mv packages/rn-tester/android/app/build/outputs/apk/hermes/debug/app-hermes-x86_64-debug.apk packages/rn-tester-e2e/apps/rn-tester.apk
- run:
name: Check Appium server status
command: |
if ! nc -z 127.0.0.1 4723; then
echo Could not find Appium server
exit 1
fi
- run:
name: Run E2E tests
no_output_timeout: 30m
command: |
cd packages/rn-tester-e2e
(yarn test-e2e android 2>&1 | tee /tmp/test_log) || true
- store_artifacts:
path: /tmp/test_log
# -------------------------
# JOBS: Build Android
# -------------------------
build_android:
executor: reactnativeandroid-xlarge
parameters:
release_type:
description: The type of release to build. Must be one of "nightly", "release", "dry-run", "prealpha".
type: enum
enum: ["nightly", "release", "dry-run", "prealpha"]
default: "dry-run"
steps:
- checkout
- run_yarn
- run:
name: Set React Native Version
command: node ./scripts/releases/set-rn-version.js --build-type << parameters.release_type >>
- with_gradle_cache:
steps:
- run:
name: Build and publish all the Android Artifacts to /tmp/maven-local
command: |
if [[ << parameters.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
- persist_to_workspace:
root: /root/react-native/
paths:
- build/
- .gradle/
- packages/rn-tester/android/app/.cxx/
- packages/rn-tester/android/app/build/
- packages/react-native/sdks/download/
- packages/react-native/sdks/hermes/
- packages/react-native/ReactAndroid/.cxx/
- packages/react-native/ReactAndroid/build/
- packages/react-native/ReactAndroid/hermes-engine/.cxx/
- packages/react-native/ReactAndroid/hermes-engine/build/
- packages/react-native/ReactAndroid/src/main/jni/prebuilt/
- packages/react-native-gradle-plugin/.gradle/
- packages/react-native-gradle-plugin/build/
- packages/react-native-codegen/lib/
# -------------------------
# JOBS: Test Android
# -------------------------
test_android:
executor: reactnativeandroid-xlarge
steps:
- checkout
- run_yarn
- run:
name: Set React Native Version to "dry-run"
# test_android executes only for dry-run builds. We need to bump the version for caching
# reasons otherwise we won't reuse the artifacts from the build_android job.
command: node ./scripts/releases/set-rn-version.js --build-type "dry-run"
- attach_workspace:
at: .
- with_gradle_cache:
steps:
- run:
name: Build & Test React Native using Gradle
command: ./gradlew build -PenableWarningsAsErrors=true
- report_bundle_size:
platform: android
- store_test_results:
path: ~/react-native/packages/react-native-gradle-plugin/build/test-results
- store_test_results:
path: ~/react-native/packages/react-native/ReactAndroid/build/test-results
- store_artifacts:
path: ~/react-native/packages/rn-tester/android/app/build/outputs/apk/
destination: rntester-apk
# -------------------------
# JOBS: Test Android Template
# -------------------------
test_android_template:
executor: reactnativeandroid-large
parameters:
flavor:
default: "Debug"
description: The Android build type. Must be one of "Debug", "Release".
type: enum
enum: ["Debug", "Release"]
architecture:
default: "OldArch"
description: Which React Native architecture to use. Must be one of "NewArch", "OldArch".
type: enum
enum: [ "NewArch", "OldArch" ]
jsengine:
default: "Hermes"
description: Which JavaScript engine to use. Must be one of "Hermes", "JSC".
type: enum
enum: ["Hermes", "JSC"]
environment:
- PROJECT_NAME: "AndroidTemplateProject"
- YARN_ENABLE_IMMUTABLE_INSTALLS: false
steps:
- checkout_code_with_cache
- run_yarn
- attach_workspace:
at: .
- run:
name: Create Android template project
command: |
REPO_ROOT=$(pwd)
node ./scripts/releases/update-template-package.js "{\"react-native\":\"file:$REPO_ROOT/build/$(cat build/react-native-package-version)\"}"
node ./scripts/e2e/init-template-e2e.js --projectName $PROJECT_NAME --templatePath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME" --verbose
- with_gradle_cache:
steps:
- run:
name: Build the template application for << parameters.flavor >> with Architecture set to << parameters.architecture >>, and using the << parameters.jsengine>> JS engine.
command: |
cd /tmp/$PROJECT_NAME/android/
if [[ << parameters.architecture >> == "NewArch" ]]; then
export ORG_GRADLE_PROJECT_newArchEnabled=true
else
export ORG_GRADLE_PROJECT_newArchEnabled=false
fi
if [[ << parameters.jsengine >> == "Hermes" ]]; then
export ORG_GRADLE_PROJECT_hermesEnabled=true
else
export ORG_GRADLE_PROJECT_hermesEnabled=false
fi
./gradlew assemble<< parameters.flavor >> -Preact.internal.mavenLocalRepo=/root/react-native/maven-local
- store_artifacts:
path: /tmp/AndroidTemplateProject/android/app/build/outputs/apk/
destination: template-apk
# -------------------------
# JOBS: Test iOS HelloWorld
# -------------------------
test_ios_helloworld:
parameters:
flavor:
default: "Debug"
description: The Xcode build type. Must be one of "Debug", "Release".
type: enum
enum: ["Debug", "Release"]
architecture:
default: "OldArch"
description: Which React Native architecture to use. Must be one of "NewArch", "OldArch".
type: enum
enum: ["NewArch", "OldArch"]
jsengine:
default: "Hermes"
description: Which JavaScript engine to use. Must be one of "Hermes", "JSC".
type: enum
enum: ["Hermes", "JSC"]
use_frameworks:
default: "StaticLibraries"
description: Which kind of option we want to use for `use_frameworks!`
type: enum
enum: ["StaticLibraries", "DynamicFrameworks"]
ruby_version:
default: "2.6.10"
description: The version of ruby that must be used
type: string
podfile_lock_cache_key:
type: string
default: *helloworld_podfile_lock_cache_key
cocoapods_cache_key:
type: string
default: *helloworld_cocoapods_cache_key
executor:
description: The executor to use
default: reactnativeios
type: string
executor: << parameters.executor >>
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- YARN_ENABLE_IMMUTABLE_INSTALLS: false
steps:
- checkout_code_with_cache
- run_yarn
- attach_workspace:
at: .
- *attach_hermes_workspace
- setup_ruby:
ruby_version: << parameters.ruby_version >>
- when:
condition:
equal: ["Hermes", << parameters.jsengine >>]
steps:
- run:
name: Set HERMES_ENGINE_TARBALL_PATH
command: |
BUILD_TYPE="<< parameters.flavor >>"
TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
echo "export HERMES_ENGINE_TARBALL_PATH=$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME" >> $BASH_ENV
- with_xcodebuild_cache:
podfile_lock_path: packages/helloworld/ios/Podfile.lock
pods_build_folder: packages/helloworld/ios/Pods
cocoapods_cache_key: << parameters.cocoapods_cache_key >>
podfile_lock_cache_key: << parameters.podfile_lock_cache_key >>
steps:
- run:
name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>>
command: |
cd packages/helloworld
args=()
if [[ << parameters.architecture >> == "OldArch" ]]; then
args+=(--arch old)
fi
if [[ << parameters.jsengine >> == "JSC" ]]; then
args+=(--jsvm jsc)
fi
if [[ << parameters.use_frameworks >> == "DynamicFrameworks" ]]; then
args+=(--frameworks dynamic)
fi
yarn bootstrap ios "${args[@]}" | cat
- run:
name: Build helloworld project
command: |
cd packages/helloworld
args=()
if [[ << parameters.flavor >> == "Release" ]]; then
args+=(--prod)
fi
yarn build ios "${args[@]}" | cat
yarn bundle ios "${args[@]}" | cat
# -------------------------
# JOBS: Test iOS RNTester
# -------------------------
test_ios_rntester:
parameters:
jsengine:
default: "Hermes"
description: Which JavaScript engine to use. Must be one of "Hermes", "JSC".
type: enum
enum: ["Hermes", "JSC"]
use_frameworks:
default: "StaticLibraries"
description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks"
type: enum
enum: ["StaticLibraries", "DynamicFrameworks"]
architecture:
default: "NewArch"
description: "The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup"
type: enum
enum: ["OldArch", "NewArch"]
ruby_version:
default: "2.6.10"
description: The version of ruby that must be used
type: string
run_unit_tests:
description: whether unit tests should run or not.
default: false
type: boolean
executor:
description: The executor to use
default: reactnativeios
type: string
executor: << parameters.executor >>
steps:
- checkout_code_with_cache
- run_yarn
- *attach_hermes_workspace
# The macOS machine can run out of storage if Hermes is enabled and built from source.
# Since this job does not use the iOS Simulator, deleting it provides a quick way to
# free up space.
- run:
name: Delete iOS Simulators
background: true
command: sudo rm -rf /Library/Developer/CoreSimulator/Profiles/Runtimes/
- setup_ruby:
ruby_version: << parameters.ruby_version >>
- when:
condition: << parameters.run_unit_tests >>
steps:
- prepare_ios_tests
- with_hermes_tarball_cache_span:
set_tarball_path: True
steps:
- with_xcodebuild_cache:
steps:
- run:
name: Install CocoaPods dependencies
command: |
if [[ << parameters.jsengine >> == "JSC" ]]; then
export USE_HERMES=0
fi
if [[ << parameters.use_frameworks >> == "DynamicFrameworks" ]]; then
export USE_FRAMEWORKS=dynamic
fi
if [[ << parameters.architecture >> == "NewArch" ]]; then
export RCT_NEW_ARCH_ENABLED=1
fi
cd packages/rn-tester
bundle install
bundle exec pod install
- when:
condition:
# The run_ios_test will also build RNTester so we don't nee to build it
# here if we run tests
equal: [ false, << parameters.run_unit_tests >> ]
steps:
- run:
name: Build RNTester
command: |
xcodebuild build \
-workspace packages/rn-tester/RNTesterPods.xcworkspace \
-scheme RNTester \
-sdk iphonesimulator
- when:
condition: << parameters.run_unit_tests >>
steps:
- run_ios_tests
# -------------------------
# JOBS: Build Hermes
# -------------------------
prepare_hermes_workspace:
docker:
- image: debian:bullseye
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- HERMES_VERSION_FILE: "packages/react-native/sdks/.hermesversion"
- RCT_BUILD_HERMES_FROM_SOURCE: true
steps:
- run:
name: Install dependencies
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
- setup_hermes_version
- get_react_native_version
- restore_cache:
key: *hermes_workspace_cache_key
- run_yarn
- run:
name: Download Hermes tarball
command: |
node packages/react-native/scripts/hermes/prepare-hermes-for-build $CIRCLE_PULL_REQUEST
cp packages/react-native/sdks/download/* $HERMES_WS_DIR/download/.
cp -r packages/react-native/sdks/hermes/* $HERMES_WS_DIR/hermes/.
cat /tmp/hermes/hermesversion
- save_cache:
key: *hermes_workspace_cache_key
paths:
- /tmp/hermes/download/
- /tmp/hermes/hermes/
# Check if we already built the tarball
# if yes, we can skip the building and we can skip some jobs building
- restore_cache:
keys:
- *hermes_tarball_release_cache_key
- check_if_tarball_is_present:
flavor: Release
- restore_cache:
keys:
- *hermes_tarball_debug_cache_key
- check_if_tarball_is_present:
flavor: Debug
- restore_cache:
keys:
- *hermes_macosx_bin_release_cache_key
- check_if_osx_bin_is_present:
flavor: Release
- restore_cache:
keys:
- *hermes_macosx_bin_debug_cache_key
- check_if_osx_bin_is_present:
flavor: Debug
- restore_cache:
keys:
- *hermes_dsym_debug_cache_key
- check_if_dsym_are_present:
flavor: Debug
- restore_cache:
keys:
- *hermes_dsym_release_cache_key
- check_if_dsym_are_present:
flavor: Release
- persist_to_workspace:
root: *hermes_workspace_root
paths:
- download
- hermes
- hermes-runtime-darwin
- osx-bin
- dSYM
- hermesversion
- Release_tarball_present
- Debug_tarball_present
- Release_osx_bin
- Debug_osx_bin
- Release_dSYM
- Debug_dSYM
- persist_to_workspace:
root: /tmp
paths:
- react-native-version
build_hermesc_linux:
docker:
- image: debian:bullseye
resource_class: "large"
steps:
- checkout_code_with_cache
- run:
name: Install dependencies
command: |
apt update
apt install -y git openssh-client cmake build-essential \
libreadline-dev libicu-dev jq zip python3
- *attach_hermes_workspace
- get_react_native_version
- restore_cache:
key: *hermes_linux_cache_key
- run:
name: Set up workspace
command: |
mkdir -p /tmp/hermes/linux64-bin
- run:
name: Build HermesC for Linux
command: |
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
- save_cache:
key: *hermes_linux_cache_key
paths:
- /tmp/hermes/linux64-bin/
- /tmp/hermes/hermes/destroot/
- store_artifacts_if_needed:
path: /tmp/hermes/linux64-bin/
- persist_to_workspace:
root: /tmp/hermes/
paths:
- linux64-bin
build_hermesc_apple:
executor: reactnativeios
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- HERMES_TARBALL_ARTIFACTS_DIR: *hermes_tarball_artifacts_dir
steps:
- *attach_hermes_workspace
- stop_job_if_apple_artifacts_are_there:
flavor: "All"
- checkout_code_with_cache
- get_react_native_version
- setup_hermes_workspace
- restore_cache:
key: *hermesc_apple_cache_key
- brew_install:
package: cmake
- run:
name: "Build HermesC Apple"
command: |
cd ./packages/react-native/sdks/hermes || exit 1
. ./utils/build-apple-framework.sh
build_host_hermesc_if_needed
- save_cache:
key: *hermesc_apple_cache_key
paths:
- ./packages/react-native/sdks/hermes/build_host_hermesc
- persist_to_workspace:
root: ./packages/react-native/sdks/hermes/
paths:
- build_host_hermesc
build_apple_slices_hermes:
parameters:
slice_base_cache_key:
default: *hermes_apple_slices_cache_key
type: string
flavor:
default: "Debug"
description: The Hermes build type. Must be one of "Debug", "Release".
type: enum
enum: ["Debug", "Release"]
slice:
default: "iphoneos"
description: The Hermes Slice that this job has to build
type: enum
enum: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"]
executor: reactnativeios
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- HERMES_TARBALL_ARTIFACTS_DIR: *hermes_tarball_artifacts_dir
- HERMES_OSXBIN_ARTIFACTS_DIR: *hermes_osxbin_artifacts_dir
steps:
- *attach_hermes_workspace
- stop_job_if_apple_artifacts_are_there:
flavor: << parameters.flavor >>
- checkout_code_with_cache
- get_react_native_version
- setup_hermes_workspace
- restore_cache:
key: *hermesc_apple_cache_key
- brew_install:
package: cmake
- restore_cache:
key: << parameters.slice_base_cache_key >>-<< parameters.slice >>-<< parameters.flavor >>
- run:
name: Build the Hermes << parameters.slice >> frameworks
command: |
cd ./packages/react-native/sdks/hermes || exit 1
SLICE=<< parameters.slice >>
FLAVOR=<< parameters.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
export RELEASE_VERSION=$(cat /tmp/react-native-version)
if [[ "$SLICE" == "macosx" ]]; then
echo "[HERMES] Building Hermes for MacOS"
export MAC_DEPLOYMENT_TARGET=10.13
BUILD_TYPE="<< parameters.flavor >>" ./utils/build-mac-framework.sh
unset MAC_DEPLOYMENT_TARGET
else
echo "[HERMES] Building Hermes for iOS: $SLICE"
export IOS_DEPLOYMENT_TARGET=13.4
BUILD_TYPE="<< parameters.flavor >>" ./utils/build-ios-framework.sh "$SLICE"
unset IOS_DEPLOYMENT_TARGET
fi
unset RELEASE_VERSION
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
- save_cache:
key: << parameters.slice_base_cache_key >>-<< parameters.slice >>-<< parameters.flavor >>
paths:
- ./packages/react-native/sdks/hermes/build_<< parameters.slice >>_<< parameters.flavor >>
build_hermes_macos:
parameters:
slice_base_cache_key:
default: *hermes_apple_slices_cache_key
type: string
flavor:
default: "Debug"
description: The Hermes build type. Must be one of "Debug", "Release".
type: enum
enum: ["Debug", "Release"]
executor: reactnativeios
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- HERMES_TARBALL_ARTIFACTS_DIR: *hermes_tarball_artifacts_dir
steps:
- *attach_hermes_workspace
# Try to store the artifacts if they are already in the workspace
- store_hermes_apple_artifacts:
flavor: << parameters.flavor >>
- stop_job_if_apple_artifacts_are_there:
flavor: << parameters.flavor >>
- checkout_code_with_cache
- run_yarn
- get_react_native_version
- brew_install:
package: cmake
- setup_hermes_workspace
- restore_cache:
key: << parameters.slice_base_cache_key >>-macosx-<< parameters.flavor >>
- restore_cache:
key: << parameters.slice_base_cache_key >>-iphoneos-<< parameters.flavor >>
- restore_cache:
key: << parameters.slice_base_cache_key >>-iphonesimulator-<< parameters.flavor >>
- restore_cache:
key: << parameters.slice_base_cache_key >>-catalyst-<< parameters.flavor >>
- restore_cache:
key: << parameters.slice_base_cache_key >>-xros-<< parameters.flavor >>
- restore_cache:
key: << parameters.slice_base_cache_key >>-xrsimulator-<< parameters.flavor >>
- run:
name: "Move back build folders"
command: |
cd ./packages/react-native/sdks/hermes || exit 1
mv build_macosx_<< parameters.flavor >> build_macosx
mv build_iphoneos_<< parameters.flavor >> build_iphoneos
mv build_iphonesimulator_<< parameters.flavor >> build_iphonesimulator
mv build_catalyst_<< parameters.flavor >> build_catalyst
mv build_xros_<< parameters.flavor >> build_xros
mv build_xrsimulator_<< parameters.flavor >> build_xrsimulator
- run:
name: "Prepare destroot folder"
command: |
cd ./packages/react-native/sdks/hermes || exit 1
. ./utils/build-apple-framework.sh
prepare_dest_root_for_ci
- run:
name: "Create fat framework for iOS"
command: |
cd ./packages/react-native/sdks/hermes || exit 1
echo "[HERMES] Creating the universal framework"
export IOS_DEPLOYMENT_TARGET=13.4
export RELEASE_VERSION=$(cat /tmp/react-native-version)
./utils/build-ios-framework.sh build_framework
unset RELEASE_VERSION
unset IOS_DEPLOYMENT_TARGET
- run:
name: Package the Hermes Apple frameworks
command: |
BUILD_TYPE="<< parameters.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/<< parameters.flavor >>
cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/<< parameters.flavor >>
- run:
name: Create dSYM archive
command: |
FLAVOR=<< parameters.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_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/"
cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/"
DEST_DIR="/tmp/hermes/dSYM/$FLAVOR"
tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" .
mkdir -p "$DEST_DIR"
mv "hermes.framework.dSYM" "$DEST_DIR"
- when:
condition:
equal: [ << parameters.flavor >>, "Debug"]
steps:
- save_cache:
key: *hermes_tarball_debug_cache_key
paths: *hermes_tarball_cache_paths
- save_cache:
key: *hermes_macosx_bin_debug_cache_key
paths: /tmp/hermes/osx-bin/Debug
- save_cache:
key: *hermes_dsym_debug_cache_key
paths: /tmp/hermes/dSYM/Debug
- when:
condition:
equal: [ << parameters.flavor >>, "Release"]
steps:
- save_cache:
key: *hermes_tarball_release_cache_key
paths: *hermes_tarball_cache_paths
- save_cache:
key: *hermes_macosx_bin_release_cache_key
paths: /tmp/hermes/osx-bin/Release
- save_cache:
key: *hermes_dsym_release_cache_key
paths: /tmp/hermes/dSYM/Release
- store_hermes_apple_artifacts:
flavor: << parameters.flavor >>
- when:
condition:
equal: [ << parameters.flavor >>, "Release" ]
steps:
- persist_to_workspace:
root: /tmp/hermes/
paths:
- hermes-runtime-darwin/hermes-ios-release.tar.gz
- when:
condition:
equal: [ << parameters.flavor >>, "Debug" ]
steps:
- persist_to_workspace:
root: /tmp/hermes/
paths:
- hermes-runtime-darwin/hermes-ios-debug.tar.gz
- persist_to_workspace:
root: /tmp/hermes/
paths:
- osx-bin/<< parameters.flavor >>
- dSYM/<< parameters.flavor >>
build_hermesc_windows:
executor:
name: win/default
shell: powershell.exe
environment:
- HERMES_WS_DIR: 'C:\tmp\hermes'
- 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:
- checkout_code_with_cache
- *attach_hermes_workspace
- get_react_native_version_windows
- restore_cache:
key: *hermes_windows_cache_key
- run:
name: Set up workspace
command: |
New-Item -ItemType Directory $Env:HERMES_WS_DIR
New-Item -ItemType Directory $Env:HERMES_WS_DIR\icu
New-Item -ItemType Directory $Env:HERMES_WS_DIR\deps
New-Item -ItemType Directory $Env:HERMES_WS_DIR\win64-bin
New-Item -ItemType SymbolicLink -Target tmp\hermes\hermes -Path $Env:HERMES_WS_DIR -Name hermes
- run:
name: Build HermesC for Windows
command: |
if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) {
choco install --no-progress cmake -y
if (-not $?) { throw "Failed to install CMake" }
cd $Env:HERMES_WS_DIR\icu
# If Invoke-WebRequest shows a progress bar, it will fail with
# Win32 internal error "Access is denied" 0x5 occurred [...]
$progressPreference = 'silentlyContinue'
Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip"
Expand-Archive -Path "icu.zip" -DestinationPath "."
cd $Env:HERMES_WS_DIR
Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps"
# Include MSVC++ 2015 redistributables
Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps"
Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps"
$Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR"
$Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu"
cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF
if (-not $?) { throw "Failed to configure Hermes" }
cd build_release
cmake --build . --target hermesc --config Release
if (-not $?) { throw "Failed to build Hermes" }
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."
}
- save_cache:
key: *hermes_windows_cache_key
paths:
- C:\tmp\hermes\win64-bin\
- C:\tmp\hermes\hermes\icu\
- C:\tmp\hermes\hermes\deps\
- C:\tmp\hermes\hermes\build_release\
- store_artifacts_if_needed:
path: C:\tmp\hermes\win64-bin\
- persist_to_workspace:
root: C:\tmp\hermes\
paths:
- win64-bin
# -------------------------
# JOBS: Releases
# -------------------------
# Writes a new commit and tag(s), which will trigger the `publish_release`
# and `publish_bumped_packages` workflows.
prepare_release:
parameters:
version:
type: string
# TODO(T182538198): Required for 0.74.x, where workspace packages are out
# of sync with react-native. This will be removed for 0.75+.
monorepo_packages_version:
type: string
tag:
type: string
dry_run:
type: boolean
default: false
executor: reactnativeios
steps:
- checkout_code_with_cache
- run_yarn
- add_ssh_keys:
fingerprints:
- "1f:c7:61:c4:e2:ff:77:e3:cc:ca:a7:34:c2:79:e3:3c"
- brew_install:
package: cmake
- run:
name: Versioning workspace packages
command: |
node scripts/releases/set-version "<< parameters.monorepo_packages_version >>" --skip-react-native-version
- run:
name: Versioning react-native package
command: |
node scripts/releases/set-rn-version.js -v "<< parameters.version >>" --build-type "release"
- run:
name: Creating release commit
command: |
git commit -a -m "Release << parameters.version >>" -m "#publish-packages-to-npm&<< parameters.tag >>"
git tag -a "v<< parameters.version >>" -m "v<< parameters.version >>"
GIT_PAGER=cat git show HEAD
- when:
condition:
equal: ["latest", << parameters.tag >>]
steps:
- run:
name: Updating "latest" tag
command: |
git tag -d "latest"
git push origin :latest
git tag -a "latest" -m "latest"
- unless:
condition: << parameters.dry_run >>
steps:
run:
name: Pushing release commit
command: |
git push origin $CIRCLE_BRANCH --follow-tags
build_npm_package:
parameters:
release_type:
description: The type of release to build. Must be one of "nightly", "release", "dry-run", or "prealpha".
type: enum
enum: ["nightly", "release", "dry-run", "prealpha"]
default: "dry-run"
executor: reactnativeandroid-xlarge
environment:
- HERMES_WS_DIR: *hermes_workspace_root
steps:
- run:
name: Add github.com to SSH known hosts
command: |
mkdir -p ~/.ssh
echo '|1|If6MU203eXTaaWL678YEfWkVMrw=|kqLeIAyTy8pzpj8x8Ae4Fr8Mtlc= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
- checkout
- *attach_hermes_workspace
- run:
name: Copy Hermes binaries
command: |
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
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/.
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
- run_yarn
- build_packages
- attach_workspace:
at: .
# START: Stables, nightlies and prealphas
# This conditional step sets up the necessary credentials for publishing react-native to npm.
- when:
condition:
or:
- equal: [ "release", << parameters.release_type >> ]
- equal: [ "nightly", << parameters.release_type >> ]
steps:
- run: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc
# END: Stables, prealpha and nightlies
- with_gradle_cache:
steps:
- run:
name: Publish NPM
command: |
# 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 [[ << parameters.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 << parameters.release_type >>
- run:
name: Zip Maven Artifacts from /tmp/maven-local
command: zip -r /tmp/maven-local.zip /tmp/maven-local
- store_artifacts:
path: /tmp/maven-local.zip
- store_artifacts:
path: /root/.npm/_logs
- persist_to_workspace:
root: /tmp
paths:
- maven-local
# START: Dry-run
# Provide a react-native package for this commit as a Circle CI release artifact.
- when:
condition:
equal: [ "dry-run", << parameters.release_type >> ]
steps:
- run:
name: Build release package as a job artifact
command: |
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
- store_artifacts:
path: ~/react-native/build/
destination: build
- persist_to_workspace:
root: .
paths:
- build/*
# END: Dry-run
# START: Stable releases
- when:
condition:
equal: [ "release", << parameters.release_type >> ]
steps:
- run:
name: Update rn-diff-purge to generate upgrade-support diff
command: |
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\": \"${CIRCLE_TAG:1}\" }}"
# END: Stable releases
poll_maven:
docker:
- image: cimg/node:current
resource_class: small
steps:
- checkout_code_with_cache
- run_yarn
- run:
name: Poll Maven for Artifacts
command: |
node scripts/circleci/poll-maven.js
find_and_publish_bumped_packages:
executor: nodelts
steps:
- checkout
- run_yarn
- build_packages
- run:
name: Set NPM auth token
command: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc
- run:
name: Find and publish all bumped packages
command: node ./scripts/releases-ci/publish-updated-packages.js