version: 2.1 # ------------------------- # ORBS # ------------------------- orbs: win: circleci/windows@2.4.0 # ------------------------- # DEFAULTS # ------------------------- 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_PULLBOT_GITHUB_TOKEN_A: &github_pullbot_token_a "a6edf8e8d40ce4e8b11a" - PUBLIC_PULLBOT_GITHUB_TOKEN_B: &github_pullbot_token_b "150e1341f4dd9c944d2a" - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: &github_analysisbot_token_a "312d354b5c36f082cfe9" - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: &github_analysisbot_token_b "07973d757026bdd9f196" # ------------------------- # EXECUTORS # ------------------------- executors: nodelts: <<: *defaults docker: # Note: Version set separately for Windows builds, see below. - image: circleci/node:14 nodeprevlts: <<: *defaults docker: - image: circleci/node:12 reactnativeandroid: <<: *defaults docker: - image: reactnativecommunity/react-native-android:3.2 resource_class: "large" environment: - TERM: "dumb" - ADB_INSTALL_TIMEOUT: 10 - _JAVA_OPTIONS: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap" - GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-XX:+HeapDumpOnOutOfMemoryError"' - BUILD_THREADS: 2 # 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 - PUBLIC_PULLBOT_GITHUB_TOKEN_A: *github_pullbot_token_a - PUBLIC_PULLBOT_GITHUB_TOKEN_B: *github_pullbot_token_b reactnativeios: <<: *defaults macos: xcode: &_XCODE_VERSION "12.5.0" # ------------------------- # COMMANDS # ------------------------- commands: restore_cache_checkout: parameters: checkout_type: type: string default: node steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }}-<< parameters.checkout_type >> setup_artifacts: steps: - run: name: Initial Setup command: mkdir -p ./reports/{buck,build,junit,outputs} run_yarn: steps: - restore_cache: keys: - v4-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} - 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: v4-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} install_buck_tooling: steps: - restore_cache: keys: - v3-buck-v2019.01.10.01-{{ checksum "scripts/circleci/buck_fetch.sh" }}} - run: name: Install BUCK command: | buck --version # Install related tooling if [[ ! -e ~/okbuck ]]; then git clone https://github.com/uber/okbuck.git ~/okbuck --depth=1 fi - save_cache: paths: - ~/buck - ~/okbuck key: v3-buck-v2019.01.10.01-{{ checksum "scripts/circleci/buck_fetch.sh" }} install_github_bot_deps: steps: - run: name: "Yarn: Install dependencies (GitHub bots)" command: cd bots && yarn install --non-interactive --cache-folder ~/.cache/yarn brew_install: parameters: package: description: Homebrew package to install type: string steps: - run: name: "Brew: Install << parameters.package >>" command: HOMEBREW_NO_AUTO_UPDATE=1 brew install << parameters.package >> >/dev/null with_brew_cache_span: parameters: steps: type: steps steps: - restore_cache: keys: - v4-brew - steps: << parameters.steps >> - save_cache: paths: - /usr/local/Homebrew - ~/Library/Caches/Homebrew key: v4-brew 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 USE_FRAMEWORKS=0 and USE_HERMES=0 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. - v3-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }} - steps: << parameters.steps >> - save_cache: paths: - packages/rn-tester/Pods key: v3-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }} download_gradle_dependencies: steps: - restore_cache: keys: - v1-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }} - run: name: Download Dependencies Using Gradle command: ./scripts/circleci/gradle_download_deps.sh - save_cache: paths: - ~/.gradle - ReactAndroid/build/downloads - ReactAndroid/build/third-party-ndk key: v1-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }} download_buck_dependencies: steps: - run: name: Download Dependencies Using Buck command: ./scripts/circleci/buck_fetch.sh 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/run-ci-e2e-tests.js --<< parameters.platform >> --retries << parameters.retries >> report_bundle_size: parameters: platform: description: Target platform type: enum enum: ["android", "ios"] steps: - install_github_bot_deps - 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 >> # ------------------------- # JOBS # ------------------------- jobs: setup: parameters: executor: type: executor default: nodelts checkout_type: type: string default: node executor: << parameters.executor >> steps: - checkout - save_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }}-<< parameters.checkout_type >> paths: - ~/react-native # ------------------------- # 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: reactnativeandroid steps: - restore_cache_checkout: checkout_type: android - run_yarn - install_github_bot_deps # Note: The yarn gpg key needs to be refreshed to work around https://github.com/yarnpkg/yarn/issues/7866 - run: name: Install additional GitHub bot dependencies command: | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - apt update && apt install -y shellcheck jq - 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 when: always - run: name: Analyze Pull Request (pull-bot) command: | cd bots DANGER_GITHUB_API_TOKEN="$PUBLIC_PULLBOT_GITHUB_TOKEN_A""$PUBLIC_PULLBOT_GITHUB_TOKEN_B" yarn danger ci --use-github-checks when: always # ------------------------- # JOBS: Analyze Code # ------------------------- analyze_code: executor: reactnativeandroid steps: - restore_cache_checkout: checkout_type: android - setup_artifacts - 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: Check for errors in code using Flow (iOS) command: yarn flow-check-ios when: always - run: name: Check for errors in code using Flow (Android) command: yarn flow-check-android 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: - restore_cache_checkout: checkout_type: node - setup_artifacts - run_yarn - run: name: Install rsync command: sudo apt-get 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: Test iOS # ------------------------- test_ios: executor: reactnativeios parameters: use_frameworks: type: boolean default: false use_hermes: type: boolean default: false run_unit_tests: description: Specifies whether unit tests should run. type: boolean default: false run_detox_tests: description: Specifies whether Detox e2e tests should run. type: boolean default: false run_disabled_tests: description: Specifies whether disabled tests should run. Set this to true to debug failing tests. type: boolean default: false environment: - REPORTS_DIR: "./reports/junit" steps: - restore_cache_checkout: checkout_type: ios - setup_artifacts - run_yarn - run: | cd packages/rn-tester bundle check || bundle install - 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@12/bin:$PATH' >> $BASH_ENV source $BASH_ENV - with_brew_cache_span: steps: - brew_install: package: watchman - brew_install: package: node@12 - run: name: "Brew: Tap wix/brew" command: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null - brew_install: package: applesimutils - run: name: Configure Watchman command: touch .watchmanconfig - when: condition: << parameters.use_frameworks >> steps: - run: name: Set USE_FRAMEWORKS=1 command: echo "export USE_FRAMEWORKS=1" >> $BASH_ENV - when: condition: << parameters.use_hermes >> steps: - run: name: Set USE_HERMES=1 command: echo "export USE_HERMES=1" >> $BASH_ENV - run: name: Setup the CocoaPods environment command: pod setup - with_rntester_pods_cache_span: steps: - run: name: Generate RNTesterPods Workspace command: cd packages/rn-tester && USE_FABRIC=1 bundle exec pod install --verbose # ------------------------- # Runs iOS unit tests - when: condition: << parameters.run_unit_tests >> steps: - run: name: "Run Tests: iOS Unit and Integration Tests" command: yarn test-ios # Runs iOS Detox e2e tests - when: condition: << parameters.run_detox_tests >> steps: - run: name: "Run Tests: Detox iOS End-to-End Tests" command: yarn run build-ios-e2e && yarn run test-ios-e2e # Optionally, run disabled tests - when: condition: << parameters.run_disabled_tests >> steps: - run: echo "Failing tests may be moved here temporarily." - run: name: "Run Tests: CocoaPods" command: ./scripts/process-podspecs.sh - run: name: Free up port 8081 for iOS End-to-End Tests command: | # free up port 8081 for the packager before running tests set +eo pipefail lsof -i tcp:8081 | awk 'NR!=1 {print $2}' | xargs kill set -eo pipefail - run_e2e: platform: ios # ------------------------- # Collect Results - report_bundle_size: platform: ios - store_test_results: path: ./reports/junit # ------------------------- # JOBS: Test Android # ------------------------- test_android: executor: reactnativeandroid parameters: run_disabled_tests: type: boolean default: false steps: - restore_cache_checkout: checkout_type: android - setup_artifacts - run_yarn # Validate Android SDK installation and packages - run: name: Validate Android SDK Install command: ./scripts/validate-android-sdk.sh # Starting emulator in advance as it takes some time to boot. - run: name: Create Android Virtual Device command: source scripts/android-setup.sh && createAVD - run: name: Launch Android Virtual Device in Background command: source scripts/android-setup.sh && launchAVD background: true # Keep configuring Android dependencies while AVD boots up # Note: The yarn gpg key needs to be refreshed to work around https://github.com/yarnpkg/yarn/issues/7866 - run: name: Install rsync, zip command: | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - apt-get update -y && apt-get install patch rsync zip -y # Install Buck - install_buck_tooling # Validate Android test environment (including Buck) - run: name: Validate Android Test Environment command: ./scripts/validate-android-test-env.sh - download_buck_dependencies - download_gradle_dependencies # Build and compile - run: name: Build Android App command: | buck build ReactAndroid/src/main/java/com/facebook/react buck build ReactAndroid/src/main/java/com/facebook/react/shell - run: name: Compile Native Libs for Unit and Integration Tests command: ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=$BUILD_THREADS no_output_timeout: 6m # Build JavaScript Bundle for instrumentation tests - run: name: Build JavaScript Bundle command: node cli.js bundle --max-workers 2 --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js # Wait for AVD to finish booting before running tests - run: name: Wait for Android Virtual Device command: source scripts/android-setup.sh && waitForAVD - run: name: Assemble RNTester App command: ./gradlew packages:rn-tester:android:app:assembleRelease # ------------------------- # Run Android tests - run: name: "Run Tests: Android Unit Tests" command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ./reports/buck/all-results-raw.xml - run: name: "Build Tests: Android Instrumentation Tests" # Here, just build the instrumentation tests. There is a known issue with installing the APK to android-21+ emulator. command: | if [[ ! -e ReactAndroid/src/androidTest/assets/AndroidTestBundle.js ]]; then echo "JavaScript bundle missing, cannot run instrumentation tests. Verify Build JavaScript Bundle step completed successfully."; exit 1; fi source scripts/android-setup.sh && NO_BUCKD=1 retry3 timeout 300 buck build ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=$BUILD_THREADS # Optionally, run disabled tests - when: condition: << parameters.run_disabled_tests >> steps: - run: echo "Failing tests may be moved here temporarily." - run_e2e: platform: android # ------------------------- # Collect Results - report_bundle_size: platform: android - run: name: Collect Test Results command: | find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} ./reports/build/ \; find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ./reports/outputs/ \; find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} ./reports/buck/ \; if [ -f ~/react-native/reports/buck/all-results-raw.xml ]; then cd ~/okbuck ./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml fi when: always - store_test_results: path: ./reports/junit # ------------------------- # JOBS: Test Docker # ------------------------- test_docker: machine: true steps: - checkout - run: name: Build Docker container for Android RNTester App command: | source ~/.bashrc nvm i node npm i -g yarn echo y | npx envinfo@latest yarn run docker-setup-android yarn run docker-build-android # ------------------------- # JOBS: Windows # ------------------------- test_windows: executor: name: win/default parameters: run_disabled_tests: type: boolean default: false environment: - ANDROID_HOME: "C:\\Android\\android-sdk" - ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944" - ANDROID_BUILD_VERSION: 30 - ANDROID_TOOLS_VERSION: 30.0.2 - GRADLE_OPTS: -Dorg.gradle.daemon=false - NDK_VERSION: 21.4.7075529 steps: - checkout - run: name: Install Node # Note: Version set separately for non-Windows builds, see above. command: | nvm install 14.17.0 nvm use 14.17.0 # Setup Dependencies - run: name: Install Yarn command: choco install yarn - run: name: Display Environment info command: npx envinfo@latest - restore_cache: keys: - v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} - run: name: "Yarn: Install Dependencies" command: yarn install --frozen-lockfile --non-interactive - save_cache: key: v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} paths: - C:\Users\circleci\AppData\Local\Yarn # Try to install the SDK up to 3 times, since network flakiness can cause install failures # Using a timeout of 9 mins, as circle ci will timeout if there is no output for 10 mins - run: name: Install Android SDK Tools command: choco install android-sdk --timeout 540; if (!$?) { choco install android-sdk --timeout 540 --force --forcedependencies}; if (!$?) { choco install android-sdk --force --forcedependencies} - run: name: Setup Android SDKs command: | sdkmanager --licenses sdkmanager "system-images;android-21;google_apis;armeabi-v7a" sdkmanager "platforms;android-%ANDROID_BUILD_VERSION%" sdkmanager "build-tools;%ANDROID_TOOLS_VERSION%" sdkmanager "add-ons;addon-google_apis-google-23" sdkmanager "extras;android;m2repository" sdkmanager "ndk;%NDK_VERSION%" # ------------------------- # Run Tests - run: name: "Flow: Check Android" command: yarn flow-check-android - run: name: "Flow: Check iOS" command: yarn flow-check-ios - run: name: "Run Tests: JavaScript Tests" command: yarn test # Optionally, run disabled tests - when: condition: << parameters.run_disabled_tests >> steps: - run: echo "Failing tests may be moved here temporarily." - run: name: Android Build command: ./gradlew.bat packages:rn-tester:android:app:assembleRelease # ------------------------- # JOBS: Coverage # ------------------------- # Collect JavaScript test coverage js_coverage: executor: nodelts environment: - CI_BRANCH: $CIRCLE_BRANCH - CI_PULL_REQUEST: $CIRCLE_PULL_REQUEST - CI_BUILD_NUMBER: $CIRCLE_BUILD_NUM - CI_BUILD_URL: $CIRCLE_BUILD_URL steps: - restore_cache_checkout: checkout_type: node - setup_artifacts - run_yarn - run: name: Collect test coverage information command: | scripts/circleci/exec_swallow_error.sh yarn test --coverage --maxWorkers=2 if [[ -e ./coverage/lcov.info ]]; then cat ./coverage/lcov.info | scripts/circleci/exec_swallow_error.sh ./node_modules/.bin/coveralls fi - store_artifacts: path: ~/react-native/coverage/ # ------------------------- # JOBS: Releases # ------------------------- # Publishes a new version onto npm publish_npm_package: parameters: publish_npm_args: type: string default: --nonightly executor: reactnativeandroid 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 - restore_cache_checkout: checkout_type: android - run_yarn - install_buck_tooling - download_buck_dependencies - download_gradle_dependencies - run: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc - run: | git config --global user.email "react-native-bot@users.noreply.github.com" git config --global user.name "npm Deployment Script" echo "machine github.com login react-native-bot password $GITHUB_TOKEN" > ~/.netrc - run: node ./scripts/publish-npm.js << parameters.publish_npm_args >> # ------------------------- # JOBS: Nightly # ------------------------- nightly_job: machine: true steps: - run: name: Nightly command: | echo "Nightly build run" # ------------------------- # WORK FLOWS # ------------------------- workflows: version: 2 tests: jobs: - setup: name: setup_js filters: branches: ignore: gh-pages - setup: name: setup_ios checkout_type: ios executor: reactnativeios filters: branches: ignore: gh-pages - setup: name: setup_android checkout_type: android executor: reactnativeandroid filters: branches: ignore: gh-pages - test_js: run_disabled_tests: false requires: - setup_js - test_android: run_disabled_tests: false requires: - setup_android - test_ios: name: test_ios_unit_jsc run_unit_tests: true requires: - setup_ios # DISABLED: USE_FRAMEWORKS=1 not supported by Flipper # - test_ios: # name: test_ios_unit_frameworks_jsc # use_frameworks: true # run_unit_tests: true # requires: # - setup_ios - test_ios: name: test_ios_unit_hermes use_hermes: true run_unit_tests: true requires: - setup_ios # DISABLED: USE_FRAMEWORKS=1 not supported by Flipper # - test_ios: # name: test_ios_unit_frameworks_hermes # use_hermes: true # use_frameworks: true # run_unit_tests: true # requires: # - setup_ios # DISABLED: Detox tests need to be fixed # - test_ios: # name: test_ios_detox # run_detox_tests: true # requires: # - setup_ios # DISABLED: USE_FRAMEWORKS=1 not supported by Flipper # - test_ios: # name: test_ios_detox_frameworks # use_frameworks: true # run_detox_tests: true # requires: # - setup_ios - test_js: name: test_js_prev_lts executor: nodeprevlts requires: - setup_js - test_docker: filters: branches: ignore: gh-pages - test_windows: filters: branches: ignore: gh-pages run_disabled_tests: false releases: jobs: - setup: name: setup_android checkout_type: android executor: reactnativeandroid filters: # 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]+)?)?/ - publish_npm_package: requires: - setup_android filters: # 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]+)?)?/ analysis: jobs: - setup: name: setup_js - setup: name: setup_android checkout_type: android executor: reactnativeandroid # Run lints on every commit other than those to the gh-pages branch - analyze_code: requires: - setup_android filters: branches: ignore: gh-pages # Run code checks on PRs from forks - analyze_pr: requires: - setup_android filters: branches: only: /^pull\/.*$/ # Gather coverage - js_coverage: requires: - setup_js nightly: triggers: - schedule: cron: "0 0 * * *" filters: branches: only: - master jobs: - nightly_job - setup: name: setup_android checkout_type: android executor: reactnativeandroid - publish_npm_package: publish_npm_args: --nightly requires: - setup_android