mirror of
				https://gitcode.com/gh_mirrors/re/react-native-pushy.git
				synced 2025-10-31 21:33:12 +08:00 
			
		
		
		
	feat: project init
This commit is contained in:
		
							
								
								
									
										232
									
								
								.github/workflows/e2e_android.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								.github/workflows/e2e_android.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,232 @@ | ||||
| name: Testing E2E Android | ||||
|  | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|     inputs: | ||||
|       clearCaches: | ||||
|         description: "Clear workflow caches where possible" | ||||
|         required: false | ||||
|         type: string | ||||
|  | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - '**' | ||||
|     paths-ignore: | ||||
|       - 'docs/**' | ||||
|       - 'website/**' | ||||
|       - '.spellcheck.dict.txt' | ||||
|       # - '**/*.md' | ||||
|  | ||||
|   push: | ||||
|     branches: | ||||
|       - main | ||||
|       - v14-release | ||||
|     paths-ignore: | ||||
|       - 'docs/**' | ||||
|       - 'website/**' | ||||
|       - '.spellcheck.dict.txt' | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ github.workflow }}-${{ github.ref }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| jobs: | ||||
|   android: | ||||
|     name: Android | ||||
|     runs-on: macos-12 | ||||
|     timeout-minutes: 90 | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         # Refactor to make these dynamic with a low/high bracket only on schedule, not push | ||||
|         # For now this is just the fastest combo (api/arch/target/snapshot-warm-time) based on testing | ||||
|         api-level: [30] | ||||
|         arch: [x86_64] | ||||
|         target: [google_apis] | ||||
|         first-boot-delay: [600] | ||||
|         # This is useful for benchmarking, do 0, 1, 2, etc (up to 256 max job-per-matrix limit) for averages | ||||
|         iteration: [0] | ||||
|     env: | ||||
|       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | ||||
|       EMULATOR_COMMAND: "-avd TestingAVD -noaudio -gpu swiftshader_indirect -camera-back none -no-snapshot -no-window -no-boot-anim -nojni -memory 2048 -timezone 'Europe/London' -cores 2" | ||||
|       EMULATOR_EXECUTABLE: qemu-system-x86_64-headless | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|         with: | ||||
|           fetch-depth: 50 | ||||
|  | ||||
|       # Set up tool versions | ||||
|       - uses: actions/setup-node@v3 | ||||
|         with: | ||||
|           node-version: 16 | ||||
|  | ||||
|       - name: Configure JDK 1.11 | ||||
|         uses: actions/setup-java@v3 | ||||
|         with: | ||||
|           distribution: 'temurin' | ||||
|           java-version: '11' | ||||
|  | ||||
|       # Set path variables needed for caches | ||||
|       - name: Set workflow variables | ||||
|         id: workflow-variables | ||||
|         run: | | ||||
|           echo "metro-cache=$HOME/.metro" >> $GITHUB_OUTPUT | ||||
|           echo "yarn-cache-dir=$(yarn cache dir)" >> $GITHUB_OUTPUT | ||||
|           echo "tempdir=$TMPDIR" >> $GITHUB_OUTPUT | ||||
|  | ||||
|       - uses: actions/cache@v3 | ||||
|         name: Yarn Cache | ||||
|         id: yarn-cache | ||||
|         with: | ||||
|           path: ${{ steps.workflow-variables.outputs.yarn-cache-dir }} | ||||
|           key: ${{ runner.os }}-yarn-v1-${{ hashFiles('yarn.lock') }} | ||||
|           restore-keys: ${{ runner.os }}-yarn-v1 | ||||
|  | ||||
|       - name: Yarn Install | ||||
|         uses: nick-invision/retry@v2 | ||||
|         with: | ||||
|           timeout_minutes: 10 | ||||
|           retry_wait_seconds: 60 | ||||
|           max_attempts: 3 | ||||
|           command: DETOX_DISABLE_POSTINSTALL=1 yarn --no-audit --prefer-offline | ||||
|  | ||||
|       - name: Cache pushy Emulator | ||||
|         uses: actions/cache@v3 | ||||
|         with: | ||||
|           path: ~/.cache/pushy/emulators | ||||
|           key: pushy-emulators-v1-${{ github.run_id }} | ||||
|           restore-keys: pushy-emulators-v1 | ||||
|  | ||||
|       - name: Start pushy Emulator | ||||
|         run: yarn tests:emulator:start-ci | ||||
|  | ||||
|       - uses: actions/cache@v3 | ||||
|         name: Gradle Cache | ||||
|         with: | ||||
|           path: ~/.gradle/caches | ||||
|           key: ${{ runner.os }}-gradle-v1-${{ hashFiles('**/*.gradle*') }} | ||||
|           restore-keys: ${{ runner.os }}-gradle-v1 | ||||
|  | ||||
|         # This appears to be 'Cache Size: ~1230 MB (1290026823 B)' based on watching action logs | ||||
|         # Repo limit is 10GB; branch caches are independent; branches may read default branch cache. | ||||
|         # We don't want branches to evict main branch snapshot, so save on main, read-only all else | ||||
|       - name: AVD cache | ||||
|         uses: actions/cache@v3 | ||||
|         id: avd-cache | ||||
|         with: | ||||
|           path: | | ||||
|             ~/.android/avd/* | ||||
|             ~/.android/adb* | ||||
|           key: avd-${{ matrix.api-level }}-${{ matrix.arch }}-${{matrix.target}}-v1-${{ github.event.inputs.clearCaches }} | ||||
|           restore-keys: | | ||||
|             avd-${{ matrix.api-level }}-${{ matrix.arch }}-${{matrix.target}}-v1 | ||||
|  | ||||
|       - name: Clear Caches Optionally | ||||
|         if: "${{ github.event.inputs.clearCaches != '' }}" | ||||
|         shell: bash | ||||
|         run: | | ||||
|           du -sk ~/.gradle | ||||
|           du -sk ~/.android | ||||
|           rm -fr ~/.gradle | ||||
|           rm -fr ~/.android | ||||
|           du -sk ~/.gradle || echo ~/.gradle is gone | ||||
|           du -sk ~/.android || echo ~/.android is gone | ||||
|  | ||||
|       - name: Build Android App | ||||
|         uses: nick-invision/retry@v2 | ||||
|         with: | ||||
|           timeout_minutes: 25 | ||||
|           retry_wait_seconds: 60 | ||||
|           max_attempts: 3 | ||||
|           command: yarn build:android-release | ||||
|  | ||||
|       - name: Metro Bundler Cache | ||||
|         uses: actions/cache@v3 | ||||
|         with: | ||||
|           path: ${{ steps.workflow-variables.outputs.metro-cache }} | ||||
|           key: ${{ runner.os }}-metro-v1-${{ github.run_id }} | ||||
|           restore-keys: ${{ runner.os }}-metro-v1 | ||||
|  | ||||
|       - name: Pre-fetch Javascript bundle | ||||
|         # Prebuild the bundle so that's fast when the app starts. | ||||
|         run: | | ||||
|           nohup yarn tests:packager:jet-ci & | ||||
|           printf 'Waiting for packager to come online' | ||||
|           until curl --output /dev/null --silent --head --fail http://localhost:8081/status; do | ||||
|             printf '.' | ||||
|             sleep 2 | ||||
|           done | ||||
|           echo "Packager is online! Preparing javascript bundle..." | ||||
|           curl --output /dev/null --silent --head --fail "http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&inlineSourceMap=true" | ||||
|           echo "...javascript bundle ready." | ||||
|  | ||||
|       - name: AVD Boot and Snapshot Creation | ||||
|         # Only generate a snapshot with a cache miss | ||||
|         # Comment the if out to generate snapshots on branch for performance testing | ||||
|         if: "${{ github.event.inputs.clearCaches != '' || (steps.avd-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main') }}" | ||||
|         uses: reactivecircus/android-emulator-runner@v2 | ||||
|         with: | ||||
|           api-level: ${{ matrix.api-level }} | ||||
|           avd-name: TestingAVD | ||||
|           force-avd-creation: false | ||||
|           target: ${{ matrix.target }} | ||||
|           arch: ${{ matrix.arch }} | ||||
|           emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||||
|           sdcard-path-or-size: 100M | ||||
|           disable-animations: true | ||||
|           # Give the emulator a little time to run and do first boot stuff before taking snapshot | ||||
|           script: | | ||||
|             $ANDROID_HOME/platform-tools/adb logcat '*:D' -d > adb-snapshot-log.txt | ||||
|             $ANDROID_HOME/platform-tools/adb logcat --clear | ||||
|             echo "Generated AVD snapshot for caching." | ||||
|  | ||||
|         # This step is separate so pure install time may be calculated as a step | ||||
|       - name: Emulator Snapshot After Firstboot Warmup | ||||
|         # Only generate a snapshot for saving with a cache miss | ||||
|         # Switch the if statements via comment if generating snapshots for performance testing | ||||
|         # if: matrix.first-boot-delay != '0' | ||||
|         if: "${{ github.event.inputs.clearCaches != '' || (steps.avd-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main') }}" | ||||
|         env: | ||||
|           FIRST_BOOT_DELAY: ${{ matrix.first-boot-delay }} | ||||
|         uses: reactivecircus/android-emulator-runner@v2 | ||||
|         with: | ||||
|           api-level: ${{ matrix.api-level }} | ||||
|           avd-name: TestingAVD | ||||
|           force-avd-creation: false | ||||
|           target: ${{ matrix.target }} | ||||
|           arch: ${{ matrix.arch }} | ||||
|           emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||||
|           sdcard-path-or-size: 100M | ||||
|           disable-animations: true | ||||
|           # Give the emulator a little time to run and do first boot stuff before taking snapshot | ||||
|           # The zygote restart makes sure zygote has correct heap size as a workaround for android emulator init bug | ||||
|           script: | | ||||
|             $ANDROID_HOME/platform-tools/adb shell su root "setprop ctl.restart zygote" | ||||
|             sleep $FIRST_BOOT_DELAY | ||||
|             $ANDROID_HOME/platform-tools/adb logcat '*:D' -d > adb-warmup-log.txt | ||||
|             $ANDROID_HOME/platform-tools/adb logcat --clear | ||||
|             echo "First boot warmup completed." | ||||
|  | ||||
|       - name: Test Tapper | ||||
|         # Run this outside the emulator runner so the emulator runner does not wait on it for cleanup | ||||
|         run: | | ||||
|           nohup sh -c "until false; do $ANDROID_HOME/platform-tools/adb shell input tap 100 800; sleep 0.2; done" & | ||||
|         shell: bash | ||||
|  | ||||
|       - name: Detox Tests | ||||
|         uses: reactivecircus/android-emulator-runner@v2 | ||||
|         timeout-minutes: 40 | ||||
|         with: | ||||
|           api-level: ${{ matrix.api-level }} | ||||
|           avd-name: TestingAVD | ||||
|           force-avd-creation: false | ||||
|           target: ${{ matrix.target }} | ||||
|           arch: ${{ matrix.arch }} | ||||
|           emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||||
|           sdcard-path-or-size: 100M | ||||
|           disable-animations: true | ||||
|           # Detox uses Espresso to choreograph steps in reaction to UI events, so we need to send a stream of taps. | ||||
|           script: | | ||||
|             $ANDROID_HOME/platform-tools/adb devices | ||||
|             nohup sh -c "$ANDROID_HOME/platform-tools/adb logcat '*:D' > adb-log.txt" & | ||||
|             yarn test:android-release | ||||
							
								
								
									
										183
									
								
								.github/workflows/e2e_ios.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								.github/workflows/e2e_ios.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| name: Testing E2E iOS | ||||
|  | ||||
| on: | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - '**' | ||||
|     paths-ignore: | ||||
|       - 'docs/**' | ||||
|       - 'website/**' | ||||
|       - '.spellcheck.dict.txt' | ||||
|       - '**/*.md' | ||||
|  | ||||
|   push: | ||||
|     branches: | ||||
|       - main | ||||
|       - v14-release | ||||
|     paths-ignore: | ||||
|       - 'docs/**' | ||||
|       - 'website/**' | ||||
|       - '.spellcheck.dict.txt' | ||||
|         # - '**/*.md' | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ github.workflow }}-${{ github.ref }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| jobs: | ||||
|   ios: | ||||
|     name: iOS | ||||
|     runs-on: macos-12 | ||||
|     # TODO matrix across APIs, at least 11 and 15 (lowest to highest) | ||||
|     timeout-minutes: 60 | ||||
|     env: | ||||
|       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | ||||
|     steps: | ||||
|       # Set up tool versions | ||||
|       - uses: actions/setup-node@v3 | ||||
|         with: | ||||
|           node-version: 16 | ||||
|  | ||||
|       - name: Configure JDK 1.11 | ||||
|         uses: actions/setup-java@v3 | ||||
|         with: | ||||
|           distribution: 'temurin' | ||||
|           java-version: '11' | ||||
|  | ||||
|       - uses: maxim-lobanov/setup-xcode@v1 | ||||
|         with: | ||||
|           xcode-version: 'latest-stable' | ||||
|  | ||||
|       - uses: actions/checkout@v3 | ||||
|         with: | ||||
|           fetch-depth: 50 | ||||
|  | ||||
|       # Set path variables needed for caches | ||||
|       - name: Set workflow variables | ||||
|         id: workflow-variables | ||||
|         run: | | ||||
|           echo "metro-cache=$HOME/.metro" >> $GITHUB_OUTPUT | ||||
|           echo "xcode-version=$(xcodebuild -version|tail -1|cut -f3 -d' ')" >> $GITHUB_OUTPUT | ||||
|           echo "yarn-cache-dir=$(yarn cache dir)" >> $GITHUB_OUTPUT | ||||
|  | ||||
|       - uses: actions/cache@v3 | ||||
|         name: Yarn Cache | ||||
|         id: yarn-cache | ||||
|         with: | ||||
|           path: ${{ steps.workflow-variables.outputs.yarn-cache-dir }} | ||||
|           key: ${{ runner.os }}-yarn-v1-${{ hashFiles('yarn.lock') }} | ||||
|           restore-keys: ${{ runner.os }}-yarn-v1 | ||||
|  | ||||
|       - uses: actions/cache@v3 | ||||
|         name: Detox Framework Cache | ||||
|         id: detox-cache | ||||
|         with: | ||||
|           path: ~/Library/Detox/ios | ||||
|           key: ${{ runner.os }}-detox-framework-cache-${{ steps.workflow-variables.outputs.xcode-version }} | ||||
|  | ||||
|       # Detox is compiled during yarn install, using Xcode, set up cache first | ||||
|       - uses: hendrikmuhs/ccache-action@v1.2 | ||||
|         name: Xcode Compile Cache | ||||
|         with: | ||||
|           key: ${{ runner.os }}-v2 # makes a unique key w/related restore key internally | ||||
|           max-size: 1500M | ||||
|  | ||||
|       - name: Yarn Install | ||||
|         uses: nick-invision/retry@v2 | ||||
|         with: | ||||
|           timeout_minutes: 10 | ||||
|           retry_wait_seconds: 60 | ||||
|           max_attempts: 3 | ||||
|           command: yarn --no-audit --prefer-offline | ||||
|  | ||||
|       - name: Setup Ruby | ||||
|         uses: ruby/setup-ruby@v1 | ||||
|         with: | ||||
|           ruby-version: 3 | ||||
|  | ||||
|       - name: Update Ruby build tools | ||||
|         uses: nick-invision/retry@v2 | ||||
|         with: | ||||
|           timeout_minutes: 2 | ||||
|           retry_wait_seconds: 60 | ||||
|           max_attempts: 3 | ||||
|           command: gem update cocoapods xcodeproj | ||||
|  | ||||
|       - uses: actions/cache@v3 | ||||
|         name: Cache Pods | ||||
|         id: pods-cache | ||||
|         with: | ||||
|           path: tests/ios/Pods | ||||
|           key: ${{ runner.os }}-pods-v2-${{ hashFiles('tests/ios/Podfile.lock') }} | ||||
|           restore-keys: ${{ runner.os }}-pods-v2 | ||||
|  | ||||
|       - name: Pod Install | ||||
|         uses: nick-invision/retry@v2 | ||||
|         with: | ||||
|           timeout_minutes: 10 | ||||
|           retry_wait_seconds: 30 | ||||
|           max_attempts: 3 | ||||
|           command: yarn tests:ios:pod:install | ||||
|  | ||||
|       - name: Cache Firestore Emulator | ||||
|         uses: actions/cache@v3 | ||||
|         with: | ||||
|           path: ~/.cache/pushy/emulators | ||||
|           key: pushy-emulators-v1-${{ github.run_id }} | ||||
|           restore-keys: pushy-emulators-v1 | ||||
|  | ||||
|       - name: Start Firestore Emulator | ||||
|         run: yarn tests:emulator:start-ci | ||||
|  | ||||
|       - name: Install brew utilities | ||||
|         uses: nick-invision/retry@v2 | ||||
|         with: | ||||
|           timeout_minutes: 5 | ||||
|           retry_wait_seconds: 60 | ||||
|           max_attempts: 3 | ||||
|           command: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew && HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils xcbeautify && applesimutils --list | ||||
|  | ||||
|       - name: Build iOS App | ||||
|         run: | | ||||
|           export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" | ||||
|           export CCACHE_SLOPPINESS=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros | ||||
|           export CCACHE_FILECLONE=true | ||||
|           export CCACHE_DEPEND=true | ||||
|           export CCACHE_INODECACHE=true | ||||
|           export CCACHE_LIMIT_MULTIPLE=0.95 | ||||
|           ccache -s | ||||
|           export SKIP_BUNDLING=1 | ||||
|           export RCT_NO_LAUNCH_PACKAGER=1 | ||||
|           set -o pipefail | ||||
|           yarn build:ios-release | ||||
|           ccache -s | ||||
|         shell: bash | ||||
|  | ||||
|       - name: Metro Bundler Cache | ||||
|         uses: actions/cache@v3 | ||||
|         with: | ||||
|           path: ${{ steps.workflow-variables.outputs.metro-cache }} | ||||
|           key: ${{ runner.os }}-metro-v1-${{ github.run_id }} | ||||
|           restore-keys: ${{ runner.os }}-metro-v1 | ||||
|  | ||||
|       - name: Pre-fetch Javascript bundle | ||||
|         run: | | ||||
|           nohup yarn tests:packager:jet-ci & | ||||
|           printf 'Waiting for packager to come online' | ||||
|           until curl --output /dev/null --silent --head --fail http://localhost:8081/status; do | ||||
|             printf '.' | ||||
|             sleep 2 | ||||
|           done | ||||
|           echo "Packager is online! Preparing bundle..." | ||||
|           curl --output /dev/null --silent --head --fail "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&inlineSourceMap=true" | ||||
|           echo "...javascript bundle ready" | ||||
|  | ||||
|       - name: Create Simulator Log | ||||
|         # With a little delay so the detox test below has time to spawn it, missing the first part of boot is fine | ||||
|         # If you boot the simulator separately from detox, some other race fails and detox testee never sends ready to proxy | ||||
|         continue-on-error: true | ||||
|         run: nohup sh -c "sleep 30 && xcrun simctl spawn booted log stream --level debug --style compact > simulator.log 2>&1 &" | ||||
|  | ||||
|       - name: Detox Test | ||||
|         timeout-minutes: 30 | ||||
|         run: yarn test:ios-release | ||||
							
								
								
									
										10
									
								
								.github/workflows/scripts/adb_all_emulators.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/scripts/adb_all_emulators.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #!/bin/bash | ||||
| echo "Running $1 on all running emulators..." | ||||
| devices=`adb devices` | ||||
|  | ||||
| for device in $devices; do | ||||
|     if [[ "$device" =~ "emulator-" ]]; then | ||||
|       adb -s $device $1 | ||||
|     fi     | ||||
| done     | ||||
| echo "All Done." | ||||
							
								
								
									
										13
									
								
								.github/workflows/scripts/database.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.github/workflows/scripts/database.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| { | ||||
|   "rules": { | ||||
|     // Database in general is closed. Read/Write to anything but "tests/" will fail. | ||||
|     ".read": false, | ||||
|     ".write": false, | ||||
|  | ||||
|     // ..."tests" node will succeed | ||||
|      "tests": { | ||||
|         ".read": true, | ||||
|         ".write": true, | ||||
|      } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										39
									
								
								.github/workflows/scripts/firebase.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								.github/workflows/scripts/firebase.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| { | ||||
|   "firestore": { | ||||
|     "rules": "firestore.rules", | ||||
|     "indexes": "firestore.indexes.json" | ||||
|   }, | ||||
|   "functions": { | ||||
|     "predeploy": [ | ||||
|       "yarn", | ||||
|       "yarn --prefix \"$RESOURCE_DIR\" build" | ||||
|     ], | ||||
|     "source": "functions" | ||||
|   }, | ||||
|   "database": { | ||||
|     "rules": "database.rules" | ||||
|   }, | ||||
|   "storage": { | ||||
|     "rules": "storage.rules" | ||||
|   }, | ||||
|   "emulators": { | ||||
|     "auth": { | ||||
|       "port": 9099 | ||||
|     }, | ||||
|     "database": { | ||||
|       "port": 9000 | ||||
|     }, | ||||
|     "firestore": { | ||||
|       "port": 8080 | ||||
|     }, | ||||
|     "functions": { | ||||
|       "port": 5001 | ||||
|     }, | ||||
|     "storage": { | ||||
|       "port": 9199 | ||||
|     }, | ||||
|     "ui": { | ||||
|       "enabled": true | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										72
									
								
								.github/workflows/scripts/firestore.indexes.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								.github/workflows/scripts/firestore.indexes.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| { | ||||
|   "indexes": [ | ||||
|     { | ||||
|       "collectionGroup": "firestore", | ||||
|       "queryScope": "COLLECTION", | ||||
|       "fields": [ | ||||
|         { | ||||
|           "fieldPath": "a", | ||||
|           "order": "ASCENDING" | ||||
|         }, | ||||
|         { | ||||
|           "fieldPath": "b", | ||||
|           "order": "ASCENDING" | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "fieldOverrides": [ | ||||
|     { | ||||
|       "collectionGroup": "collectionGroup", | ||||
|       "fieldPath": "value", | ||||
|       "indexes": [ | ||||
|         { | ||||
|           "order": "ASCENDING", | ||||
|           "queryScope": "COLLECTION" | ||||
|         }, | ||||
|         { | ||||
|           "order": "DESCENDING", | ||||
|           "queryScope": "COLLECTION" | ||||
|         }, | ||||
|         { | ||||
|           "arrayConfig": "CONTAINS", | ||||
|           "queryScope": "COLLECTION" | ||||
|         }, | ||||
|         { | ||||
|           "order": "ASCENDING", | ||||
|           "queryScope": "COLLECTION_GROUP" | ||||
|         }, | ||||
|         { | ||||
|           "order": "DESCENDING", | ||||
|           "queryScope": "COLLECTION_GROUP" | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "collectionGroup": "collectionGroup", | ||||
|       "fieldPath": "number", | ||||
|       "indexes": [ | ||||
|         { | ||||
|           "order": "ASCENDING", | ||||
|           "queryScope": "COLLECTION" | ||||
|         }, | ||||
|         { | ||||
|           "order": "DESCENDING", | ||||
|           "queryScope": "COLLECTION" | ||||
|         }, | ||||
|         { | ||||
|           "arrayConfig": "CONTAINS", | ||||
|           "queryScope": "COLLECTION" | ||||
|         }, | ||||
|         { | ||||
|           "order": "ASCENDING", | ||||
|           "queryScope": "COLLECTION_GROUP" | ||||
|         }, | ||||
|         { | ||||
|           "order": "DESCENDING", | ||||
|           "queryScope": "COLLECTION_GROUP" | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										17
									
								
								.github/workflows/scripts/firestore.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/scripts/firestore.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| rules_version = '2'; | ||||
| service cloud.firestore { | ||||
|   match /databases/{database}/documents { | ||||
|   match /{document=**} { | ||||
|       allow read, write: if false; | ||||
|     } | ||||
|   match /firestore-bundle-tests/{document=**} { | ||||
|       allow read, write: if true; | ||||
|     } | ||||
|   match /firestore/{document=**} { | ||||
|       allow read, write: if true; | ||||
|     }  | ||||
|   match /{path=**}/collectionGroup/{documentId} { | ||||
|       allow read, write: if true; | ||||
|     }   | ||||
|   } | ||||
| } | ||||
							
								
								
									
										10
									
								
								.github/workflows/scripts/functions/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/scripts/functions/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| # Compiled JavaScript files | ||||
| lib/**/*.js | ||||
| lib/**/*.js.map | ||||
|  | ||||
| # TypeScript v1 declaration files | ||||
| typings/ | ||||
|  | ||||
| # Node.js dependency directory | ||||
| node_modules/ | ||||
| yarn.lock | ||||
							
								
								
									
										24
									
								
								.github/workflows/scripts/functions/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/scripts/functions/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| { | ||||
|   "name": "functions", | ||||
|   "scripts": { | ||||
|     "build": "tsc", | ||||
|     "serve": "npm run build && firebase emulators:start --only functions", | ||||
|     "shell": "npm run build && firebase functions:shell", | ||||
|     "start": "npm run shell", | ||||
|     "deploy": "firebase deploy --only functions", | ||||
|     "logs": "firebase functions:log" | ||||
|   }, | ||||
|   "engines": { | ||||
|     "node": "16" | ||||
|   }, | ||||
|   "main": "lib/index.js", | ||||
|   "dependencies": { | ||||
|     "firebase-admin": "^11.3.0", | ||||
|     "firebase-functions": "^4.2.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "firebase-functions-test": "^3.0.0", | ||||
|     "typescript": "^4.9.5" | ||||
|   }, | ||||
|   "private": true | ||||
| } | ||||
							
								
								
									
										13
									
								
								.github/workflows/scripts/functions/src/exports.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.github/workflows/scripts/functions/src/exports.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| /* | ||||
|  * | ||||
|  *  Testing tools for invertase/react-native-firebase use only. | ||||
|  * | ||||
|  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||
|  * | ||||
|  *  See License file for more information. | ||||
| */ | ||||
|  | ||||
| /* eslint-disable global-require */ | ||||
| module.exports = { | ||||
|   SAMPLE_DATA: require('./functions/sample-data'), | ||||
| }; | ||||
							
								
								
									
										12
									
								
								.github/workflows/scripts/functions/src/index.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/scripts/functions/src/index.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| import * as functions from 'firebase-functions'; | ||||
|  | ||||
| // // Start writing Firebase Functions | ||||
| // // https://firebase.google.com/docs/functions/typescript | ||||
| // | ||||
| export const helloWorld = functions.https.onRequest((request, response) => { | ||||
|   functions.logger.info('Hello logs!', { structuredData: true }); | ||||
|   response.send('{ "data": "Hello from Firebase!" }'); | ||||
| }); | ||||
|  | ||||
| export { testFunctionCustomRegion } from './testFunctionCustomRegion'; | ||||
| export { testFunctionDefaultRegion } from './testFunctionDefaultRegion'; | ||||
							
								
								
									
										80
									
								
								.github/workflows/scripts/functions/src/sample-data.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								.github/workflows/scripts/functions/src/sample-data.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* | ||||
|  *  Testing tools for invertase/react-native-firebase use only. | ||||
|  * | ||||
|  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||
|  * | ||||
|  *  See License file for more information. | ||||
|  */ | ||||
|  | ||||
| const SAMPLE_DATA: { [key: string]: any } = { | ||||
|   number: 1234, | ||||
|   string: 'acde', | ||||
|   boolean: true, | ||||
|   null: null, | ||||
|   object: { | ||||
|     number: 1234, | ||||
|     string: 'acde', | ||||
|     boolean: true, | ||||
|     null: null, | ||||
|   }, | ||||
|   array: [1234, 'acde', true, null], | ||||
|   deepObject: { | ||||
|     array: [1234, 'acde', false, null], | ||||
|     object: { | ||||
|       number: 1234, | ||||
|       string: 'acde', | ||||
|       boolean: true, | ||||
|       null: null, | ||||
|       array: [1234, 'acde', true, null], | ||||
|     }, | ||||
|     number: 1234, | ||||
|     string: 'acde', | ||||
|     boolean: true, | ||||
|     null: null, | ||||
|   }, | ||||
|   deepArray: [ | ||||
|     1234, | ||||
|     'acde', | ||||
|     true, | ||||
|     null, | ||||
|     [1234, 'acde', true, null], | ||||
|     { | ||||
|       number: 1234, | ||||
|       string: 'acde', | ||||
|       boolean: true, | ||||
|       null: null, | ||||
|       array: [1234, 'acde', true, null], | ||||
|     }, | ||||
|   ], | ||||
|   deepMap: { | ||||
|     number: 123, | ||||
|     string: 'foo', | ||||
|     booleanTrue: true, | ||||
|     booleanFalse: false, | ||||
|     null: null, | ||||
|     list: ['1', 2, true, false], | ||||
|     map: { | ||||
|       number: 123, | ||||
|       string: 'foo', | ||||
|       booleanTrue: true, | ||||
|       booleanFalse: false, | ||||
|       null: null, | ||||
|     }, | ||||
|   }, | ||||
|   deepList: [ | ||||
|     '1', | ||||
|     2, | ||||
|     true, | ||||
|     false, | ||||
|     ['1', 2, true, false], | ||||
|     { | ||||
|       number: 123, | ||||
|       string: 'foo', | ||||
|       booleanTrue: true, | ||||
|       booleanFalse: false, | ||||
|       null: null, | ||||
|     }, | ||||
|   ], | ||||
| }; | ||||
|  | ||||
| export default SAMPLE_DATA; | ||||
							
								
								
									
										14
									
								
								.github/workflows/scripts/functions/src/testFunctionCustomRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/scripts/functions/src/testFunctionCustomRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| /* | ||||
|  * | ||||
|  *  Testing tools for invertase/react-native-firebase use only. | ||||
|  * | ||||
|  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||
|  * | ||||
|  *  See License file for more information. | ||||
|  */ | ||||
|  | ||||
| import * as functions from 'firebase-functions'; | ||||
|  | ||||
| export const testFunctionCustomRegion = functions | ||||
|   .region('europe-west1') | ||||
|   .https.onCall(() => 'europe-west1'); | ||||
							
								
								
									
										70
									
								
								.github/workflows/scripts/functions/src/testFunctionDefaultRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								.github/workflows/scripts/functions/src/testFunctionDefaultRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| /* | ||||
|  * | ||||
|  *  Testing tools for invertase/react-native-firebase use only. | ||||
|  * | ||||
|  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||
|  * | ||||
|  *  See License file for more information. | ||||
|  */ | ||||
|  | ||||
| import * as assert from 'assert'; | ||||
| import { FirebaseError } from 'firebase-admin'; | ||||
| import * as functions from 'firebase-functions'; | ||||
| import SAMPLE_DATA from './sample-data'; | ||||
|  | ||||
| export const testFunctionDefaultRegion = functions.https.onCall(data => { | ||||
|   console.log(Date.now(), data); | ||||
|  | ||||
|   if (typeof data === 'undefined') { | ||||
|     return 'undefined'; | ||||
|   } | ||||
|  | ||||
|   if (typeof data === 'string') { | ||||
|     return 'string'; | ||||
|   } | ||||
|  | ||||
|   if (typeof data === 'number') { | ||||
|     return 'number'; | ||||
|   } | ||||
|  | ||||
|   if (typeof data === 'boolean') { | ||||
|     return 'boolean'; | ||||
|   } | ||||
|  | ||||
|   if (data === null) { | ||||
|     return 'null'; | ||||
|   } | ||||
|  | ||||
|   if (Array.isArray(data)) { | ||||
|     return 'array'; | ||||
|   } | ||||
|  | ||||
|   const { type, asError, inputData } = data; | ||||
|   if (!Object.hasOwnProperty.call(SAMPLE_DATA, type)) { | ||||
|     throw new functions.https.HttpsError('invalid-argument', 'Invalid test requested.'); | ||||
|   } | ||||
|  | ||||
|   const outputData = SAMPLE_DATA[type]; | ||||
|  | ||||
|   try { | ||||
|     assert.deepEqual(outputData, inputData); | ||||
|   } catch (e) { | ||||
|     console.error(e); | ||||
|     throw new functions.https.HttpsError( | ||||
|       'invalid-argument', | ||||
|       'Input and Output types did not match.', | ||||
|       (e as FirebaseError).message, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   // all good | ||||
|   if (asError) { | ||||
|     throw new functions.https.HttpsError( | ||||
|       'cancelled', | ||||
|       'Response data was requested to be sent as part of an Error payload, so here we are!', | ||||
|       outputData, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   return outputData; | ||||
| }); | ||||
							
								
								
									
										16
									
								
								.github/workflows/scripts/functions/tsconfig.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/scripts/functions/tsconfig.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "module": "commonjs", | ||||
|     "noImplicitReturns": true, | ||||
|     "noUnusedLocals": true, | ||||
|     "outDir": "lib", | ||||
|     "sourceMap": true, | ||||
|     "skipLibCheck": true, | ||||
|     "strict": true, | ||||
|     "target": "es2017" | ||||
|   }, | ||||
|   "compileOnSave": true, | ||||
|   "include": [ | ||||
|     "src" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										6
									
								
								.github/workflows/scripts/start-firebase-emulator.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/scripts/start-firebase-emulator.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| @REM this pushd is likely not needed, but just in case | ||||
| pushd "%~dp0" | ||||
| @REM this is just to see what our current directory is. Should be .github/workflow/scripts | ||||
| echo %cd% | ||||
| @REM strangely, unless you specify the config file as being right in the current directory, it won't find it, and everything fails | ||||
| yarn firebase emulators:start --config %cd%\firebase.json --only auth,database,firestore,functions,storage --project react-native-firebase-testing | ||||
							
								
								
									
										44
									
								
								.github/workflows/scripts/start-firebase-emulator.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										44
									
								
								.github/workflows/scripts/start-firebase-emulator.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| #!/bin/bash | ||||
| if ! [ -x "$(command -v firebase)" ]; then | ||||
|   echo "❌ Firebase-tools CLI is missing. Run 'npm i -g firebase-tools' or the equivalent" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| EMU_START_COMMAND="firebase emulators:start --only auth,database,firestore,functions,storage --project react-native-firebase-testing" | ||||
| #EMU_START_COMMAND="sleep 120" | ||||
| MAX_RETRIES=3 | ||||
| MAX_CHECKATTEMPTS=60 | ||||
| CHECKATTEMPTS_WAIT=1 | ||||
|  | ||||
| # Make sure functions are ready to go | ||||
| pushd "$(dirname "$0")/functions" && yarn && yarn build && popd | ||||
|  | ||||
|  | ||||
| RETRIES=1 | ||||
| while [ $RETRIES -le $MAX_RETRIES ]; do | ||||
|  | ||||
|   if [ "$1" == "--no-daemon" ]; then | ||||
|     echo "Starting Firebase Emulator Suite in foreground." | ||||
|     $EMU_START_COMMAND | ||||
|     exit 0 | ||||
|   else | ||||
|     echo "Starting Firebase Emulator Suite in background." | ||||
|     $EMU_START_COMMAND & | ||||
|     CHECKATTEMPTS=1 | ||||
|     while [ $CHECKATTEMPTS -le $MAX_CHECKATTEMPTS ]; do | ||||
|       sleep $CHECKATTEMPTS_WAIT | ||||
|       if curl --output /dev/null --silent --fail http://localhost:8080; then | ||||
|         echo "Firebase Emulator Suite is online!" | ||||
|         exit 0; | ||||
|       fi | ||||
|       echo "Waiting for Firebase Emulator Suite to come online, check $CHECKATTEMPTS of $MAX_CHECKATTEMPTS..." | ||||
|       ((CHECKATTEMPTS = CHECKATTEMPTS + 1)) | ||||
|     done | ||||
|   fi | ||||
|  | ||||
|   echo "Firebase Emulator Suite did not come online in $MAX_CHECKATTEMPTS checks. Try $RETRIES of $MAX_RETRIES." | ||||
|   ((RETRIES = RETRIES + 1)) | ||||
|  | ||||
| done | ||||
| echo "Firebase Emulator Suite did not come online after $MAX_RETRIES attempts." | ||||
| exit 1 | ||||
							
								
								
									
										21
									
								
								.github/workflows/scripts/storage.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.github/workflows/scripts/storage.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| rules_version = '2'; | ||||
| service firebase.storage { | ||||
|   match /b/{bucket}/o { | ||||
|     match /{document=**} { | ||||
|       allow read, write: if false; | ||||
|     } | ||||
|  | ||||
|     match /writeOnly.jpeg { | ||||
|       allow read: if false; | ||||
|       allow write: if true; | ||||
|     } | ||||
|  | ||||
|     match /playground/{document=**} { | ||||
|       allow read, write: if true; | ||||
|     } | ||||
|  | ||||
|     match /react-native-firebase-testing/{document=**} { | ||||
|       allow read, write: if true; | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 steven
					steven