react-native-macos/.circleci/config.yml

694 строки
20 KiB
YAML

version: 2.1
# -------------------------
# DEFAULTS
# -------------------------
defaults: &defaults
working_directory: ~/react-native
environment:
- GIT_COMMIT_DESC: git log --format=oneline -n 1 $CIRCLE_SHA1
# -------------------------
# EXECUTORS
# -------------------------
executors:
node8:
<<: *defaults
docker:
- image: circleci/node:8
nodelts:
<<: *defaults
docker:
- image: circleci/node:lts
reactnativeandroid:
<<: *defaults
docker:
- image: reactnativecommunity/react-native-android:2019-9-4
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
reactnativeios:
<<: *defaults
macos:
xcode: "10.3.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" }}
- v4-yarn-cache-{{ arch }}
- run:
name: Run Yarn
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" }}}
- v3-buck-v2019.01.10.01-
- 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" }}
brew_install:
parameters:
package:
description: Homebrew package to install
type: string
steps:
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install << parameters.package >> >/dev/null
with_brew_cache_span:
parameters:
steps:
type: steps
steps:
- restore_cache:
keys:
- v2-brew
- steps: << parameters.steps >>
- save_cache:
paths:
- /usr/local/Homebrew
- ~/Library/Caches/Homebrew
key: v2-brew
with_pods_cache_span:
parameters:
steps:
type: steps
steps:
- run:
name: Setup CocoaPods cache
# Copy RNTester/Podfile.lock since it can be changed by pod install
command: cp RNTester/Podfile.lock RNTester/Podfile.lock.bak
- restore_cache:
keys:
- v1-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "RNTester/Podfile.lock.bak" }}
- v1-pods-{{ .Environment.CIRCLE_JOB }}-
- steps: << parameters.steps >>
- save_cache:
paths:
- RNTester/Pods
key: v1-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "RNTester/Podfile.lock.bak" }}
download_gradle_dependencies:
steps:
- restore_cache:
keys:
- v1-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }}
- v1-gradle-
- 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
# -------------------------
# COMMANDS: Disabled Tests
# -------------------------
run_podspec_tests:
steps:
- run:
name: Test CocoaPods
command: ./scripts/process-podspecs.sh
run_e2e_tests:
steps:
- run:
name: Full End-to-End Test Suite
command: node ./scripts/run-ci-e2e-tests.js --android --ios --js --retries 3;
run_android_e2e_tests:
steps:
- run:
name: Android End-to-End Test Suite
command: node ./scripts/run-ci-e2e-tests.js --android --retries 3;
# -------------------------
# JOBS
# -------------------------
jobs:
setup:
parameters:
executor:
type: executor
default: node8
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: nodelts
# The public github tokens are publicly visible by design
environment:
- PUBLIC_PULLBOT_GITHUB_TOKEN_A: "a6edf8e8d40ce4e8b11a"
- PUBLIC_PULLBOT_GITHUB_TOKEN_B: "150e1341f4dd9c944d2a"
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: "78a72af35445ca3f8180"
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: "b1a98e0bbd56ff1ccba1"
steps:
- restore_cache_checkout:
checkout_type: node
- run_yarn
- run:
name: Install dependencies
command: |
sudo apt update && sudo apt install -y shellcheck jq
cd bots && yarn install --non-interactive --cache-folder ~/.cache/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
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: node8
steps:
- restore_cache_checkout:
checkout_type: node
- 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: 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
# -------------------------
# Runs JavaScript tests
test_js:
parameters:
executor:
type: executor
default: node8
executor: << parameters.executor >>
steps:
- restore_cache_checkout:
checkout_type: node
- setup_artifacts
- run_yarn
- run:
name: JavaScript Test Suite
command: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2
- store_test_results:
path: ~/reports/junit
# -------------------------
# JOBS: Test iOS
# -------------------------
# Runs unit tests on iOS devices
test_ios:
executor: reactnativeios
parameters:
use_frameworks:
type: boolean
default: false
environment:
- REPORTS_DIR: "./reports"
steps:
- restore_cache_checkout:
checkout_type: ios
- setup_artifacts
- run_yarn
- run: |
cd RNTester
bundle check || bundle install
- run:
name: Boot iPhone Simulator
command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true
- run:
name: Fetch CocoaPods Specs
command: |
curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf
- when:
condition: << parameters.use_frameworks >>
steps:
- run:
name: Set USE_FRAMEWORKS=1
command: echo "export USE_FRAMEWORKS=1" >> $BASH_ENV
- with_pods_cache_span:
steps:
- run:
name: Generate RNTesterPods Workspace
command: cd RNTester && pod install --verbose
- with_brew_cache_span:
steps:
- brew_install:
package: watchman
- run: touch .watchmanconfig
- run: yarn test-ios
- store_test_results:
path: ~/reports/junit
# Runs iOS end-to-end tests
test_ios_e2e:
executor: reactnativeios
steps:
- restore_cache_checkout:
checkout_type: ios
- setup_artifacts
- run_yarn
- 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@8/bin:$PATH' >> $BASH_ENV
source $BASH_ENV
# Brew
- with_brew_cache_span:
steps:
- brew_install:
package: node@8
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
- brew_install:
package: applesimutils
- brew_install:
package: watchman
# Configure Watchman
- run: touch .watchmanconfig
- restore_cache:
keys:
- v1-cocoapods-{{ checksum "template/ios/Podfile" }}
- v1-cocoapods-
- run: pod setup
- run:
name: Generate RNTesterPods Workspace
command: pushd RNTester && pod install --verbose && popd
- run:
name: Run Detox iOS End-to-End Tests
command: yarn run build-ios-e2e && yarn run test-ios-e2e
when: always
- run:
name: Run 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
node ./scripts/run-ci-e2e-tests.js --ios --retries 3;
when: always
- save_cache:
paths:
- ~/.cocoapods/repos
key: v1-cocoapods-{{ checksum "template/ios/Podfile" }}
test_js_e2e:
executor: node8
steps:
- restore_cache_checkout:
checkout_type: node
- setup_artifacts
- run_yarn
- run: sudo apt-get install rsync
- run:
name: Run JavaScript End-to-End Tests
command: node ./scripts/run-ci-e2e-tests.js --js --retries 3
- store_test_results:
path: ~/reports/junit
# -------------------------
# JOBS: Test Android
# -------------------------
# Run Android tests
test_android:
executor: reactnativeandroid
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
# 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
# Test Suite
- run:
name: Run Unit Tests
command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ~/reports/buck/all-results-raw.xml
- run:
name: Run Instrumentation Tests
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 install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=$BUILD_THREADS
- run:
name: Build Android RNTester App
command: ./gradlew RNTester:android:app:assembleRelease
# Collect Results
- 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
./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/all-results-junit.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
npx envinfo@latest
yarn run docker-setup-android
yarn run docker-build-android
# -------------------------
# JOBS: Coverage
# -------------------------
# Collect JavaScript test coverage
js_coverage:
executor: node8
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: Test coverage
command: |
yarn test --coverage --maxWorkers=2
cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
when: always
- store_artifacts:
path: ~/react-native/coverage/
# -------------------------
# JOBS: Releases
# -------------------------
# Publishes new version onto npm
# Only works on stable branches when a properly tagged commit is pushed
publish_npm_package:
executor: reactnativeandroid
steps:
- 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
# -------------------------
# WORK FLOWS
# -------------------------
workflows:
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:
requires:
- setup_js
- test_js_e2e:
requires:
- setup_js
- test_js
- test_android:
requires:
- setup_android
- test_ios:
requires:
- setup_ios
- test_ios:
name: test_ios_frameworks
use_frameworks: true
requires:
- setup_ios
- test_ios_e2e:
requires:
- setup_ios
- test_js
- test_js:
name: test_js_lts
executor: nodelts
requires:
- setup_js
- test_docker:
filters:
branches:
ignore: gh-pages
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
# Run lints on every commit other than those to the gh-pages branch
- analyze_code:
requires:
- setup
filters:
branches:
ignore: gh-pages
# Run code checks on PRs from forks
- analyze_pr:
requires:
- setup
filters:
branches:
only: /^pull\/.*$/
# Gather coverage
- js_coverage:
requires:
- setup