DEV Community

React Native e2e tests and Automatic Deploys (Detox + Fastlane + CircleCI)

Roberto Junior Amarante Calderón on April 17, 2021

A little bit of context (skippable) These past weeks I've been struggling trying to set up a pipeline where for every PR pointing to our...
Collapse
 
kierano547 profile image
Kieran Osgood • Edited

When you chose the macos executor instead of the linux_android for the android e2e tests: "Note that all of this can be achieved using the rn/linux_android executor." was there any reason for that choice? The macos minutes are more expensive AFAIK, and you chose to mention both would work, so just curious if it was more difficult to do or something?

p.s. I found that the rn/ios_build_and_test command worked just fine when used like this:

      - rn/ios_build_and_test:
          yarn_cache: false
          xcodebuild_cache: false
          homebrew_cache: false
          project_type: "workspace"
          project_path: "ios/punchline.xcworkspace"
          device: "iPhone 11"
          build_configuration: "Release"
          scheme: "punchline"
          detox_configuration: "ios.sim.release"
          requires:
            - checkout_code
            - analyse_js
            - update_homebrew
Enter fullscreen mode Exit fullscreen mode

Currently trying to decide how I can most efficiently configure the e2e tests on release, and ideally use the same build artifacts from that to release through fastlane or something

Collapse
 
kyonru profile image
Roberto Junior Amarante Calderón

In the beginning, I tried with the linux_executor. I don't remember exactly why I changed, I think it was related to all the detox dependencies and setting up the environment. (But later other issues came up, so I had to do all of that... At this point, it should be that hard to change the executor, but idk since I need to try it again).

Thanks for the suggestion! I'll make an update with your suggestion with iOS.

Collapse
 
kyonru profile image
Roberto Junior Amarante Calderón

That definitely would save some time. I'm not sure of the implications of publishing the detox build for android. But It would definitely help for ios.

Collapse
 
krishnag09 profile image
Krishna Gaurav

@ Kieran Osgood - Were you able to find a way to reduce the ios build time for detox, using macos or linux as env?

Collapse
 
kyonru profile image
Roberto Junior Amarante Calderón

Yeah.... Mayor update, you can get the same result with:

version: 2.1

orbs:
  rn: react-native-community/react-native@5.5.0

jobs:
  checkout_code:
    executor:
      name: rn/linux_js
      node_version: '12'
    steps:
      - checkout
      - persist_to_workspace:
          paths: .
          root: .
  analyse_js:
    executor:
      name: rn/linux_js
      node_version: '12'
    steps:
      - attach_workspace:
          at: .
      - rn/yarn_install
      - run:
          command: yarn lint
          name: Run Linter
      - run:
          command: yarn jest
          name: Run Tests

  # submit app to playstore for internal test
  fastlane_android_internal:
    executor: rn/linux_android
    steps:
      - attach_workspace:
          at: .
      - rn/yarn_install
      - run:
          command: bash create_staging_env_files.sh
          name: Create env files
      - run:
          command: cat .env
          name: Print env files
      - run:
          command: gem install bundler
          name: Install bundler
      - run:
          command: gem install fastlane
          name: Install Fastlane
      - run:
          command: cd android && fastlane googleplay
          name: Upload to google play via Fastlane
  # submit app to apple connect testflight
  fastlane_ios_testflight:
    executor:
      name: rn/macos
    steps:
      - attach_workspace:
          at: .
      - rn/yarn_install:
          cache: false
      - run:
          command: bash create_staging_env_files.sh
          name: Create env files
      - run:
          command: cat .env
          name: Print env files
      - run:
          working_directory: ios
          command: pod install
      - run:
          command: gem install bundler
          name: Install bundler
      - run:
          command: gem install fastlane
          name: Install Fastlane
      - run:
          command:
            git config --global --add url."git@github.com:".insteadOf
            "https://github.com/"
          name: Use SSH
      - run:
          working_directory: ios
          command: fastlane beta
          env:
            MATCH_GIT_BASIC_AUTHORIZATION: $MATCH_GIT_BASIC_AUTHORIZATION
          name: Upload to Testflight via Fastlane

  # submit app to playstore for beta, ready to release to prod
  fastlane_android_beta:
    executor: rn/linux_android
    steps:
      - attach_workspace:
          at: .
      - rn/yarn_install
      - run:
          command: bash create_prod_env_files.sh
          name: Create env files
      - run:
          command: cat .env
          name: Print env files
      - run:
          command: gem install bundler
          name: Install bundler
      - run:
          command: gem install fastlane
          name: Install Fastlane
      - run:
          command: cd android && fastlane googleplaymanualprod
          name: Upload to google play via Fastlane
  # submit app to apple connect ready for review
  fastlane_ios_app_store:
    executor:
      name: rn/macos
    steps:
      - attach_workspace:
          at: .
      - rn/yarn_install:
          cache: false
      - run:
          command: bash create_prod_env_files.sh
          name: Create env files
      - run:
          command: cat .env
          name: Print env files
      - run:
          working_directory: ios
          command: pod install
      - run:
          command: gem install bundler
          name: Install bundler
      - run:
          command: gem install fastlane
          name: Install Fastlane
      - run:
          command:
            git config --global --add url."git@github.com:".insteadOf
            "https://github.com/"
          name: Use SSH
      - run:
          working_directory: ios
          command: fastlane prod
          env:
            MATCH_GIT_BASIC_AUTHORIZATION: $MATCH_GIT_BASIC_AUTHORIZATION
            SENTRY_AUTH_TOKEN: $SENTRY_AUTH_TOKEN
            ASCAPI_KEY_ID: $ASCAPI_KEY_ID
            ASCAPI_ISSUER_ID: $ASCAPI_ISSUER_ID
            ASCAPI_KEY_CONTENT: $ASCAPI_KEY_CONTENT
          name: Upload to Testflight via Fastlane
workflows:
  test:
    jobs:
      - checkout_code
      - analyse_js:
          requires:
            - checkout_code
      - rn/android_build:
          name: build_android_release
          project_path: 'android'
          build_type: release
          on_after_initialize: |
            bash create_env_files.sh
          requires:
            - analyse_js
      - rn/android_test:
          name: android_e2e_test
          detox_configuration:
            'android.emu.release --take-screenshots failing --artifacts-location
            /tmp/detox_artifacts --cleanup --record-logs failing'
          device_name: Pixel_2_API_29
          platform_version: android-29
          build_tools_version: '29.0.3'
          yarn_cache: false
          requires:
            - build_android_release
          detox_loglevel: 'verbose'
          store_artifact_path: '/tmp/detox_artifacts'
          should_on_after_initialize: true
          on_after_initialize: |
            HOMEBREW_NO_AUTO_UPDATE=1 brew tap adoptopenjdk/openjdk
            HOMEBREW_NO_AUTO_UPDATE=1 brew install --cask adoptopenjdk/openjdk/adoptopenjdk8
            echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)' >> $BASH_ENV

        # Build and test the iOS app in release mode
      - rn/ios_build_and_test:
          name: ios_e2e_test
          checkout: true
          project_path: 'ios/mobileApp.xcworkspace'
          project_type: workspace
          device: 'iPhone 11'
          pod_install_directory: ios
          on_after_initialize: |
            bash create_env_files.sh
          build_configuration: 'Release'
          scheme: 'appScheme'
          detox_configuration:
            'ios.sim.release --take-screenshots failing --artifacts-location
            /tmp/detox_artifacts --cleanup --record-logs failing'
          detox_loglevel: 'verbose'
          store_artifact_path: '/tmp/detox_artifacts'
          yarn_cache: false
          xcodebuild_cache: false
          requires:
            - analyse_js
      # Release apps to stores for testing
      - fastlane_android_internal:
          filters:
            branches:
              only:
                - staging
          requires:
            - android_e2e_test
      - fastlane_ios_testflight:
          filters:
            branches:
              only:
                - staging
          requires:
            - ios_e2e_test
      # Release apps to stores for release [manual]
      - fastlane_android_beta:
          filters:
            branches:
              only:
                - main
          requires:
            - android_e2e_test
      - fastlane_ios_app_store:
          filters:
            branches:
              only:
                - main
          requires:
            - ios_e2e_test

Enter fullscreen mode Exit fullscreen mode
Collapse
 
kyonru profile image
Roberto Junior Amarante Calderón

I'll make sure to update this post when I get some time ToT

Collapse
 
acro5piano profile image
Kay Gosho

Thanks for the great article! Do you have any experience in GitHub actions? I tried it before and not works as well as CircleCI.

Collapse
 
kyonru profile image
Roberto Junior Amarante Calderón

Sadly I have just use github actions to test detox, but I'm planning on doing this workflow sooner than later for this app in github actions. github.com/Kyonru/just-a-review-app

Collapse
 
acro5piano profile image
Kay Gosho • Edited

Thanks! I think maybe there is a problem running iOS build on GitHub actions, whereas CircleCI works much better thanks to the ORB. Looking forward to the GitHub Actions version!

Collapse
 
onlyhasbi profile image
Muhammad Hasbi

If you want to try the free plan of CircleCI, I have shared the configuration in this post

Integrate React Native CLI Detox to CircleCi

Collapse
 
blashadow_62 profile image
Luis

sounds good to automate some react-native dev-ops things, also reading the documentation from react-native-circleci-orb really makes sure you know how hard is what you're about to do.

Collapse
 
krishnag09 profile image
Krishna Gaurav

Thanks for the post, very well detailed.
Could i ask what was the build time for this rn/ios_build step? And if you have thought of ways to reduce it?