React 기본 e2e 테스트 및 자동 배포(디톡스 + 급행열차 + CirclecI)

포인트 컨텍스트(생략 가능)


지난 몇 주 동안 저는 저희를 가리키는 임시 저장소의 PR마다 e2e 테스트를 자동으로 실행하고 통합된 PR마다 시험 비행 버전과 구글 내부 테스트 버전을 만들기 위해 파이프라인을 구축하려고 노력해 왔습니다.나의 경력은...어렵지만, 이것은 결코 너도 이렇게 해야 한다는 것을 의미하지 않는다.
tl;박사PAIN .

무엇이 필요합니까?


1. CI의 실적 계획을 표시한다.

Since we are going to use macs for building our apps. If you only need android builds, you can easily achieve this with github actions, seethis project for an example

2. Apple connect 계정 및 Google play 콘솔 계정

This will be needed for automatic deployments(2nd part).

3. 인내심

Trust me, you'll need it. CIs can smell fear.

시작해보도록 하겠습니다.


1. 디톡스를 react native 프로젝트에 추가합니다.

Please, follow this guide using JEST step by step in order to have it correctly configured in your project. Here is an example of a .detoxrc.json .
일단 로컬에서 e2e 테스트를 실행할 수 있다면 다음 단계를 시작할 수 있습니다.

2. Circleci를 설정합니다.


만약 당신이 Circleci가 없다면, 그것을 추가하는 방법을 배울 수 있습니다. here
구성 내용을 너무 걱정하지 마십시오.yml, 왜냐하면 우리는 그것을 완전히 수정해야 하기 때문이다.:)이 때 .circleci/ 라는 폴더와 config.yml 파일이 있어야 합니다.
우리 orbs로 마술을 합시다!/app/build.gradle에 추가합니다react-native-circleci-orb.
task downloadDependencies() {
  description 'Download all dependencies to the Gradle cache'
  doLast {
    configurations.findAll().each { config ->
      if (config.name.contains("minReactNative") && config.canBeResolved) {
        print config.name
        print '\n'
        config.files
      }
    }
  }
}

행운이라고 생각하세요?


React 로컬 커뮤니티에서 이 orb를 사용하는 방법의 예는 다음과 같습니다.
version: 2.1

orbs:
  rn: react-native-community/[email protected]
# Custom jobs which are not part of the Orb
jobs:
  checkout_code:
    executor: rn/linux_js
    steps:
      - checkout
      - persist_to_workspace:
          root: .
          paths: .
  analyse_js:
    executor: rn/linux_js
    steps:
      - attach_workspace:
          at: .
      - rn/yarn_install
      - run:
          name: Run ESLint
          command: yarn eslint
      - run:
          name: Flow
          command: yarn flow
      - run:
          name: Jest
          command: yarn jest

workflows:
  test:
    jobs:
      # Checkout the code and persist to the Workspace
      # Note: This is a job that is defined above and not part of the Orb
      - checkout_code

      # Analyze the Javascript using ESLint, Flow, and Jest
      # Note: This is a job that is defined above and not part of the Orb
      - analyse_js:
          requires:
            - checkout_code

      # Build the Android app in debug mode
      - rn/android_build:
          name: build_android_debug
          project_path: "android"
          build_type: debug
          requires:
            - analyse_js

      # Build and test the Android app in release mode
      # Note: We split these into separate jobs because we can build the Android app on a Linux machine and preserve the expensive MacOS executor minutes for when it's required
      - rn/android_build:
          name: build_android_release
          project_path: "android"
          build_type: release
          requires:
            - analyse_js
      - rn/android_test:
          detox_configuration: "android.emu.release"
          requires:
            - build_android_release

      # Build the iOS app in release mode and do not run tests
      - rn/ios_build:
          name: build_ios_release
          project_path: ios/Example.xcodeproj
          device: "iPhone X"
          build_configuration: Release
          scheme: Example
          requires:
            - analyse_js

      # Build and test the iOS app in release mode
      - rn/ios_build_and_test:
          project_path: "ios/Example.xcodeproj"
          device: "iPhone X"
          build_configuration: "Release"
          scheme: "Example"
          detox_configuration: "ios.sim.release"
          requires:
            - analyse_js
그러나 내 경험에 따르면 한 가지 문제는 그것이 작용하지 않는다는 것이다.Here are the docs의 모든 보조 함수.

다음은요?


Welp는 한 걸음 한 걸음 유용한 것들을 만들어 보자;)

둥근 공


version: 2.1
orbs:
  rn: react-native-community/[email protected]
이것은 rn 라고 부릅니다. 이 이름은 당신이 원하는 모든 이름일 수 있습니다. 이것은 작업이 언제 orb에서 오는지 지정하는 데 사용됩니다.예rn/yarn_install

잡스



코드 체크 아웃
프로젝트 루트 디렉터리에서 작업을 수행하는 데 필요한 코드를 서명하고 작업 영역으로 영구화합니다.
checkout_code:
  executor:
    name: rn/linux_js
    node_version: "12"
  steps:
    - checkout
    - persist_to_workspace:
        paths: .
        root: .

분석하다.
Linux에서 jest 테스트를 실행합니다.orb의 executor를 어떻게 사용하고 프로젝트에 node 버전을 정의하는지 주의하십시오.
analyse_js:
  executor:
    name: rn/linux_js
    node_version: "12"
  steps:
    - attach_workspace:
        at: .
    - rn/yarn_install
    - run:
        command: yarn test
        name: Run Tests

안드로이드
완벽한 세계에서 문서의 예는 바로 당신이 필요로 하는 것이다.그러나 이 프로그래밍은 React native에 대해 논의 중이며 예는 다음과 같습니다.
- rn/android_build:
    build_type: debug
    name: build_android_debug
    project_path: android
    requires:
      - analyse_js
- rn/android_build:
    build_type: release
    name: build_android_release
    project_path: android
    requires:
      - analyse_js
이런 방법의 주요 문제는 rn/android build이 프로그램을 디톡스 구축이 아니라 정상적으로 구축하는 것이다. 이것은 이상한 문제와 e2e 테스트의 가음성을 초래할 수 있다.
그래서...네, 우리는 반드시 수동으로 이 절차를 다시 집행해야 하지만, 마음대로 시도해 보십시오.너한테 도움이 된다면
여기서 무슨 일이 일어났는지 평론을 읽으세요.
android_e2e_test:
  # Using a mac (:
  executor:
    name: rn/macos
  steps:
    - attach_workspace:
        at: .
    - rn/setup_macos_executor:
        homebrew_cache: true
        node_version: "12"
    - rn/yarn_install:
        # basically because of this https://github.com/react-native-community/react-native-circleci-orb/issues/66
        cache: false
    - run:
        # For my app and react native in general java8 is needed. The default version on this executor was default to java10 for some reason, so this kinda solve that issue.
        # just installing java, android sdk, and needed tools.
        command: >
          java -version

          brew tap adoptopenjdk/openjdk

          brew install --cask adoptopenjdk/openjdk/adoptopenjdk8

          java -version

          export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)

          mkdir -p ~/.android && touch ~/.android/repositories.cfg

          java -version

          yes | sdkmanager "platform-tools" "tools" >/dev/null

          yes | sdkmanager "platforms;android-29"
          "system-images;android-29;default;x86_64" >/dev/null

          yes | sdkmanager "emulator" --channel=3 >/dev/null

          yes | sdkmanager "build-tools;29.0.2" >/dev/null

          yes | sdkmanager --licenses >/dev/null

          yes | sdkmanager --list
        name: Install Android Emulator
        shell: /bin/bash -e
    - run:
        command: |
          adb start-server
          adb devices
          adb kill-server
          ls -la ~/.android
        name: ADB Start Stop
    - run:
        # Note we are using a pixel_xl as the test device, feel free to change it for one better fits your app
        command: |
          export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
          avdmanager create avd --force --name Pixel_2_API_29 --package "system-images;android-29;default;x86_64" --tag default --device pixel_xl
        name: Create Android Emulator
    - run:
        background: true
        command: |
          export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
          $ANDROID_HOME/emulator/emulator @Pixel_2_API_29 -version
          $ANDROID_HOME/emulator/emulator @Pixel_2_API_29 -cores 2 -gpu auto
          -accel on -memory 2048 -no-audio -no-snapshot -no-boot-anim
          -no-window -logcat *:W | grep -i
          'ReactNative\|com.reactnativecommunity'
        name: Start Android Emulator (background)
    - run:
        command: >
          # export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)

          export BOOT=""

          echo "Waiting for AVD to finish booting"

          export PATH=$(dirname $(dirname $(command -v
          android)))/platform-tools:$PATH

          until [[ "$BOOT" =~ "1" ]]; do
            sleep 5
            export BOOT=$(adb -e shell getprop sys.boot_completed 2>&1)
          done

          sleep 15

          adb shell settings put global window_animation_scale 0

          adb shell settings put global transition_animation_scale 0

          adb shell settings put global animator_duration_scale 0

          echo "Android Virtual Device is now ready."
        name: Wait for AVD to be ready
        no_output_timeout: 5m
    # Creates the detox build using the orb job
    - rn/detox_build:
        configuration: "android.emu.release"
    # Tests the app, you can use rn/detox_test, but I wanted to take screenshots when test fails so I can have a better idea of why did they fail.
    - run:
        command: >-
          detox test -c android.emu.release -l warn --headless
          --take-screenshots failing --artifacts-location /tmp/detox_artifacts
        name: Detox Test
    # Save the screenshots as artifacts, you can see then in the artifact tab for the job in CircleCI
    - store_artifacts:
        path: /tmp/detox_artifacts
이 모든 것은 rn/linux_android 실행기로 실현할 수 있음을 주의하십시오.

iOS e2e
완벽한 세계에서 문서의 예는 바로 당신이 필요로 하는 것이다.이것은 나에게 주는 것이다...없을 때까지. 다음 방법을 시도해 보세요. 도움이 된다면.
# Build and test the iOS app in release mode
- rn/ios_build_and_test:
    project_path: "ios/Example.xcodeproj"
    device: "iPhone X"
    build_configuration: "Release"
    scheme: "Example"
    detox_configuration: "ios.sim.release"
    requires:
      - analyse_js
다행히도 안드로이드보다 OS가 더 좋아요.그래, 내가 말했어...적어도 발전 면에서는 그렇다.ios 구축 및 테스트를 다시 만들기 위해서는 다음이 필요합니다.
# Build and test the iOS app in release mode
ios_e2e_test:
  executor: rn/macos
  steps:
    - checkout
    - attach_workspace:
        at: .
    - rn/setup_macos_executor:
        homebrew_cache: true
        node_version: "12"
    - rn/ios_simulator_start:
        device: "iPhone 11"
    - rn/yarn_install:
        # basically because of this https://github.com/react-native-community/react-native-circleci-orb/issues/66
        cache: false
    - rn/pod_install:
        pod_install_directory: ios
    # Yep, it doesn't really matter if you don't run detox build for ios, it works like a charm. But if you prefer, you can replace this step with a custom one.
    - rn/ios_build:
        build_configuration: "Release"
        cache: false
        derived_data_path: "ios/build"
        device: "iPhone 11"
        project_path: "ios/example.xcworkspace"
        project_type: workspace
        scheme: "example"
    - run:
        command: >-
          detox test -c ios.sim.release -l warn --headless --take-screenshots
          failing --artifacts-location /tmp/detox_artifacts
        name: Detox Test
    - store_artifacts:
        path: /tmp/detox_artifacts
축하합니다!응용 프로그램에서 e2e 테스트를 실행하고 있습니다!자신의 등을 두드리고 한 잔 하러 가자. 급행열차가 곧 오기 때문이다.
가장 어려운 일은 당신의 프로젝트를 배치하는 것입니다.마음대로 댓글로 질문해 주세요. 하지만 fastlane documentation 다음 단계를 준비하기에 충분할 거예요.
시작할 곳이 필요하면 다음을 확인하십시오.
  • fastlane + react native
  • react native tutorial
  • match


  • 급행열차 안드로이드
    이것은 네가 이미 한 것보다 쉽다.Linux에 Fastlane을 설치하고 Fastlane를 실행하기만 하면 됩니다.
    fastlane_android_internal:
      executor: rn/linux_android
      steps:
        - attach_workspace:
            at: .
        - rn/yarn_install
        - run:
            command: gem install bundler
            name: Install bundler
        - run:
            command: gem install fastlane
            name: Install Fastlane
        # Note that my lane is name upload_to_googleplay replaced for yours
        - run:
            # can be fancier and use working_directory
            command: cd android && fastlane upload_to_googleplay
            name: Upload to google play via Fastlane
    

    Fastlane ios
    Fastlane을 ios에 추가하는 것은 결코 쉬운 일이 아니라는 것을 나는 확신한다.그래서...진사를 축하합니다!ios를 제외하고 이 절차들은 기본적으로 같다.
    # submit app to apple connect testflight
    fastlane_ios_testflight:
      executor:
        name: rn/macos
      steps:
        - attach_workspace:
            at: .
        - rn/yarn_install:
            cache: false
        - run:
            working_directory: ios
            command: pod install
        - run:
            command: gem install bundler
            name: Install bundler
        - run:
            command: gem install fastlane
            name: Install Fastlane
        - run:
            working_directory: ios
            command: fastlane beta
            name: Upload to Testflight via Fastlane
    
    그래서...급행열차 팁.

  • Fastlane Docs .

  • .

  • CircleCI Docs .
  • 일자를 빌드 번호로 사용합니다.(더 많은 버전 번호를 얻는 방법도 있습니다. 시도하고 싶으면 어떤 방법도 추천하지 마십시오. 왜냐하면ci에서 어떤 방법도 사용하지 않았기 때문입니다.
  • 안드로이드:
    건설 중입니다.그라델(int)(date.getTime() / 10000)
  • ios:
    fastlane/Fastfilebuild_number: DateTime.now.strftime("%Y%m%d%H%M")에서
  • 그리고 하나 더 있어요.


    모든 것이 순조롭게 진행되기 위해서, 우리는 절차의 순서를 정의하는 작업 흐름을 만들어야 한다.
    그래서...다음과 같은 권장 사항이 있습니다.
    workflows:
      # name of the workflow
      main:
        jobs:
          - checkout_code
          # Do jest tests
          - analyse_js:
              requires:
                - checkout_code
          # Build and test the android app in release mode
          - android_e2e_test:
              requires:
                - analyse_js
          # Build and test the iOS app in release mode
          - ios_e2e_test:
              requires:
                - analyse_js
          # Release apps to stores for testing
          - fastlane_android_internal:
              # We only want to deploy to google play when things get merged into the main branch
              filters:
                branches:
                  only:
                    - main
              # Note that e2e need to pass in order to release
              requires:
                - android_e2e_test
          - fastlane_ios_testflight:
              # We only want to deploy to google play when things get merged into the main branch
              filters:
                branches:
                  only:
                    - main
              # Note that e2e need to pass in order to release
              requires:
                - ios_e2e_test
    
    만약 react native, Detoxit,Circleci,Fastlane가 오늘 쉴 수 있다고 결정한다면, 파이프에서 비슷한 것을 보아야 한다.

    좋은 웹페이지 즐겨찾기