feat(ios): add SPM dependency resolution support alongside CocoaPods #4590
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Testing E2E iOS | |
| on: | |
| workflow_call: | |
| inputs: | |
| record_screens: | |
| description: 'Record host screencapture and simulator video artifacts' | |
| type: boolean | |
| default: false | |
| workflow_dispatch: | |
| inputs: | |
| iterations: | |
| description: 'Number of iterations to run. Default 1. Max 122.' | |
| required: true | |
| default: 1 | |
| type: number | |
| record_screens: | |
| description: 'Record host screencapture and simulator video artifacts' | |
| type: boolean | |
| default: false | |
| pull_request: | |
| branches: | |
| - '**' | |
| paths-ignore: | |
| - 'docs/**' | |
| - 'website/**' | |
| - '.spellcheck.dict.txt' | |
| - '**/*.md' | |
| push: | |
| branches: | |
| - main | |
| - release-v* | |
| paths-ignore: | |
| - 'docs/**' | |
| - 'website/**' | |
| - '.spellcheck.dict.txt' | |
| - '**/*.md' | |
| permissions: | |
| contents: read | |
| actions: write | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # We want to generate our matrix dynamically | |
| # Initial job generates the matrix as a JSON, and following job will use deserialize and use the result | |
| matrix_prep: | |
| # Do not run the scheduled jobs on forks | |
| if: (github.event_name == 'schedule' && github.repository == 'invertase/react-native-firebase') || (github.event_name != 'schedule') | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.build-matrix.outputs.result }} | |
| steps: | |
| - id: build-matrix | |
| # https://github.com/actions/github-script/releases | |
| uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0 | |
| with: | |
| script: | | |
| // by default, we will run one iteration | |
| let iterationArray = [0] | |
| // workflow dispatch will be a drop-down of different options | |
| if (context.eventName === "workflow_dispatch") { | |
| const inputs = ${{ toJSON(inputs) }} | |
| console.log('inputs is: ' + JSON.stringify(inputs)) | |
| const iterationInput = inputs.iterations | |
| console.log('iterations input is: ' + iterationInput) | |
| // this will expand for example with input 5 => [0, 1, 2, 3, 4] | |
| iterationArray = [] | |
| for (let i = 0; i < iterationInput; i++) { | |
| iterationArray.push(i); | |
| } | |
| console.log('iterationArray is: ' + iterationArray) | |
| } | |
| // If we are running on a schedule it's our periodic passive scan for flakes | |
| // Goal is to run enough iterations on all systems that we have confidence there are no flakes | |
| if (context.eventName === "schedule") { | |
| const iterationCount = 15 | |
| for (let i = 0; i < iterationCount; i++) { | |
| iterationArray.push(i); | |
| } | |
| } | |
| // we want to test debug and release - they generate different code | |
| let buildmode = ['debug', 'release']; | |
| // Test both SPM and CocoaPods dependency resolution modes | |
| let depResolution = ['spm', 'cocoapods']; | |
| return { | |
| "iteration": iterationArray, | |
| "buildmode": buildmode, | |
| "dep-resolution": depResolution | |
| } | |
| - name: Debug Output | |
| run: echo "${{ steps.build-matrix.outputs.result }}" | |
| # This uses the matrix generated from the matrix-prep stage | |
| # it will run unit tests on whatever OS combinations are desired | |
| ios: | |
| name: iOS (${{ matrix.buildmode }}, ${{ matrix.dep-resolution }}, ${{ matrix.iteration }}) | |
| runs-on: macos-26 | |
| needs: matrix_prep | |
| # TODO matrix across APIs, at least 11 and 15 (lowest to highest) | |
| timeout-minutes: 107 | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| RNFB_RECORD_SCREENS: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.record_screens && '1' || '0' }} | |
| CCACHE_SLOPPINESS: clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros | |
| CCACHE_FILECLONE: true | |
| CCACHE_DEPEND: true | |
| CCACHE_INODECACHE: true | |
| CCACHE_LIMIT_MULTIPLE: 0.95 | |
| # macos-26 + latest-stable matches local Xcode 26.5; firebase-ios-sdk requires Xcode 26.2+ | |
| XCODE_VERSION: latest-stable | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}} | |
| steps: | |
| - name: Setup Environment for Screen Recording | |
| # https://github.com/guidepup/setup-action/releases | |
| uses: guidepup/setup-action@5ab89fbb6641406f6f6c91057225f3fb397c2eea # v0.20.0 | |
| continue-on-error: true | |
| if: env.RNFB_RECORD_SCREENS == '1' | |
| with: | |
| record: true | |
| - name: Upload Screen Recording Environment Setup | |
| # https://github.com/actions/upload-artifact/releases | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() && env.RNFB_RECORD_SCREENS == '1' | |
| with: | |
| name: screenrecording-setup-${{ matrix.buildmode }}-${{ matrix.iteration }}.mov | |
| path: ./recordings/ | |
| # Set up tool versions | |
| # https://github.com/actions/setup-node/releases | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 22 | |
| - name: Configure JDK | |
| # https://github.com/actions/setup-java/releases | |
| uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '21' | |
| # https://github.com/maxim-lobanov/setup-xcode/releases | |
| - uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 | |
| with: | |
| xcode-version: ${{ env.XCODE_VERSION }} | |
| - name: Workaround Simulator Availability issues | |
| run: | | |
| # If using `latest-stable` xcode-version above, this is likely not needed. | |
| # If you use *anything* but latest-stable, you may inadvertently be using a SimRuntime that is no longer installed. | |
| # This will install the needed SimRuntime if it is missing. | |
| if [[ "$XCODE_VERSION" != "latest-stable" ]] && ! xcrun simctl list | grep "^iOS $XCODE_VERSION"; then | |
| # note if you specify the build version to be exactly same as xcode version | |
| # you may see "iOS <version> is not available for download" | |
| #xcodebuild -downloadPlatform iOS -buildVersion "$XCODE_VERSION" | |
| xcodebuild -downloadPlatform iOS | |
| fi | |
| # Apparently just listing the installed simulators fixes availability inconsistency | |
| # Without this, runs fail *intermittently* with build target not available because simulators not available | |
| # See https://github.com/actions/runner-images/issues/13459#issuecomment-3681674842 | |
| xcrun simctl list | |
| # https://github.com/actions/checkout/releases | |
| - uses: actions/checkout@9f698171ed81b15d1823a05fc7211befd50c8ae0 # v6.0.3 | |
| 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 | |
| - name: Yarn Cache Restore | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| id: yarn-cache | |
| continue-on-error: true | |
| with: | |
| path: .yarn/cache | |
| key: ${{ runner.os }}-ios-yarn-v1-${{ hashFiles('yarn.lock') }} | |
| restore-keys: ${{ runner.os }}-ios-yarn-v1 | |
| - name: Detox Framework Cache Restore | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| id: detox-cache | |
| continue-on-error: true | |
| 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 | |
| # https://github.com/hendrikmuhs/ccache-action/releases | |
| - uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23 | |
| name: Xcode Compile Cache | |
| with: | |
| key: ${{ runner.os }}-${{ matrix.buildmode }}-${{ matrix.dep-resolution }}-ios-v3 # makes a unique key w/related restore key internally | |
| save: "${{ github.ref == 'refs/heads/main' }}" | |
| create-symlink: true | |
| max-size: 1500M | |
| - name: Yarn Install | |
| # https://github.com/nick-fields/retry/releases | |
| uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 | |
| with: | |
| timeout_minutes: 15 | |
| retry_wait_seconds: 60 | |
| max_attempts: 3 | |
| command: yarn | |
| - name: Setup Ruby | |
| # https://github.com/ruby/setup-ruby/releases | |
| uses: ruby/setup-ruby@89f90524b88a01fe6e0b732220432cc6142926af # v1.313.0 | |
| with: | |
| ruby-version: 3 | |
| - name: Update Ruby build tools | |
| # https://github.com/nick-fields/retry/releases | |
| uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 | |
| with: | |
| timeout_minutes: 2 | |
| retry_wait_seconds: 60 | |
| max_attempts: 3 | |
| command: gem update cocoapods xcodeproj | |
| - name: Pods Cache Restore | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| id: pods-cache | |
| continue-on-error: true | |
| with: | |
| path: tests/ios/Pods | |
| key: ${{ runner.os }}-${{ matrix.dep-resolution }}-ios-pods-v3-${{ hashFiles('tests/ios/Podfile.lock') }} | |
| restore-keys: ${{ runner.os }}-${{ matrix.dep-resolution }}-ios-pods-v3 | |
| - name: Configure Dependency Resolution Mode | |
| run: | | |
| if [[ "${{ matrix.dep-resolution }}" == "cocoapods" ]]; then | |
| echo "Configuring CocoaPods-only mode (disabling SPM)" | |
| cd tests/ios | |
| sed -i '' "s/^linkage = 'dynamic'/linkage = 'static'/" Podfile | |
| printf '%s\n' '$RNFirebaseDisableSPM = true' | cat - Podfile > Podfile.tmp && mv Podfile.tmp Podfile | |
| sed -i '' "/SWIFT_ENABLE_EXPLICIT_MODULES/d" Podfile | |
| echo "Podfile configured for CocoaPods-only mode" | |
| else | |
| echo "Using default SPM mode (dynamic linkage)" | |
| fi | |
| - name: Pod Install | |
| # https://github.com/nick-fields/retry/releases | |
| uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 | |
| with: | |
| timeout_minutes: 20 | |
| retry_wait_seconds: 30 | |
| max_attempts: 3 | |
| command: yarn tests:ios:pod:install | |
| - name: Firestore Emulator Restore | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| id: firestore-emulator-cache | |
| continue-on-error: true | |
| with: | |
| # The firebase emulators are pure javascript and java, OS-independent | |
| enableCrossOsArchive: true | |
| path: ~/.cache/firebase/emulators | |
| key: firebase-emulators-v1-${{ github.run_id }} | |
| restore-keys: firebase-emulators-v1 | |
| - name: Start Firestore Emulator | |
| run: yarn tests:emulator:start-ci | |
| # https://bitrise.io/blog/post/xcode-15-performance-regressions | |
| # https://developer.apple.com/forums/thread/805625?answerId=865340022#865340022 | |
| - name: Install yeetd and fix iOS perf issues | |
| run: | | |
| wget https://github.com/biscuitehh/yeetd/releases/download/1.0/yeetd-normal.pkg | |
| sudo installer -pkg yeetd-normal.pkg -target / | |
| yeetd & | |
| launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist | |
| sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist | |
| # Vendored Homebrew formulae — pin/update: okf-bundle/ci-workflows/ios.md#pinned-homebrew-utilities | |
| - name: Install brew utilities | |
| # https://github.com/nick-fields/retry/releases | |
| uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 | |
| with: | |
| timeout_minutes: 5 | |
| retry_wait_seconds: 60 | |
| max_attempts: 3 | |
| command: bash .github/workflows/scripts/install-homebrew-rnfb.sh applesimutils xcbeautify | |
| - name: Build iOS App Debug | |
| if: contains(matrix.buildmode, 'debug') | |
| run: | | |
| ccache -s | |
| export SKIP_BUNDLING=1 | |
| export RCT_NO_LAUNCH_PACKAGER=1 | |
| set -o pipefail | |
| echo $PATH | |
| which clang | |
| yarn tests:ios:build | |
| ccache -s | |
| shell: bash | |
| - name: Build iOS App Release | |
| if: contains(matrix.buildmode, 'release') | |
| run: | | |
| ccache -s | |
| export RCT_NO_LAUNCH_PACKAGER=1 | |
| set -o pipefail | |
| echo $PATH | |
| which clang | |
| yarn tests:ios:build:release | |
| ccache -s | |
| shell: bash | |
| - name: Metro Bundler Cache Restore | |
| if: contains(matrix.buildmode, 'debug') | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| id: metro-bundler-cache | |
| continue-on-error: true | |
| with: | |
| path: ${{ steps.workflow-variables.outputs.metro-cache }} | |
| key: ${{ runner.os }}-ios-metro-v1-${{ github.run_id }} | |
| restore-keys: ${{ runner.os }}-ios-metro-v1 | |
| - name: Pre-fetch Javascript bundle | |
| if: contains(matrix.buildmode, 'debug') | |
| run: | | |
| nohup yarn tests:packager:jet-ci > metro.log 2>&1 & | |
| 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: Start host screen recording | |
| if: env.RNFB_RECORD_SCREENS == '1' | |
| continue-on-error: true | |
| run: | | |
| nohup sh -c "sleep 314159265 | screencapture -v -C -k -T0 -g screenrecording.mov > screenrecording.log 2>&1 &" | |
| - name: Pre-Boot Simulator | |
| # Separate Simulator boot from Detox run. boot-simulator.sh polls bootstatus and logs | |
| # migration progress so long first-boot waits are visible in the step log. | |
| # https://github.com/nick-fields/retry/releases | |
| uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 | |
| with: | |
| timeout_minutes: 12 | |
| retry_wait_seconds: 60 | |
| max_attempts: 3 | |
| command: RNFB_START_SIM_LOGS=0 ./.github/workflows/scripts/boot-simulator.sh | |
| - name: Start Simulator App Log | |
| # One filtered sim log stream (testing + SpringBoard/invertase + Storage); optional sim video when record_screens. | |
| # RNFB_SIM_LOG_STDOUT=1 surfaces sim-app.log lines in the step log for iOS Storage diagnosis (B3.1). | |
| continue-on-error: true | |
| run: | | |
| chmod +x ./.github/workflows/scripts/boot-simulator.sh | |
| RNFB_RECORD_SCREENS="${RNFB_RECORD_SCREENS}" RNFB_SIM_BOOT_MODE=logs RNFB_SIM_LOG_STDOUT=1 ./.github/workflows/scripts/boot-simulator.sh | |
| - name: Wait for host load to settle | |
| continue-on-error: true | |
| run: | | |
| chmod +x ./.github/workflows/scripts/wait-for-load-settle.sh | |
| ./.github/workflows/scripts/wait-for-load-settle.sh | |
| - name: Detox Test Debug | |
| if: contains(matrix.buildmode, 'debug') | |
| timeout-minutes: 82 | |
| run: | | |
| yarn tests:ios:test-cover 2>&1 | tee detox-step.log | |
| exit ${PIPESTATUS[0]} | |
| - name: Process iOS native coverage | |
| if: always() && contains(matrix.buildmode, 'debug') | |
| continue-on-error: true | |
| run: yarn tests:ios:test:process-coverage | |
| - name: Detox Test Release | |
| if: contains(matrix.buildmode, 'release') | |
| timeout-minutes: 82 | |
| run: | | |
| yarn tests:ios:test:release 2>&1 | tee detox-step.log | |
| exit ${PIPESTATUS[0]} | |
| - name: Write flake summary | |
| if: always() | |
| continue-on-error: true | |
| run: | | |
| chmod +x ./.github/workflows/scripts/flake-summary.sh | |
| RNFB_DETOX_LOG=detox-step.log ./.github/workflows/scripts/flake-summary.sh | |
| - name: Stop Screen and App Video and System Logging | |
| if: always() | |
| continue-on-error: true | |
| run: | | |
| killall -int simctl | |
| if [[ "${RNFB_RECORD_SCREENS}" == "1" ]]; then | |
| killall -int screencapture | |
| fi | |
| pkill -f resource-monitor.sh || true | |
| - name: Upload App Video | |
| # https://github.com/actions/upload-artifact/releases | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() && env.RNFB_RECORD_SCREENS == '1' | |
| with: | |
| name: simulator-${{ matrix.buildmode }}-${{ matrix.iteration }}_video | |
| path: simulator.mp4 | |
| - name: Upload Simulator App Log | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() | |
| with: | |
| name: sim-app-${{ matrix.buildmode }}-${{ matrix.iteration }}_log | |
| path: sim-app.log | |
| - name: Upload resource monitor log | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() | |
| with: | |
| name: resource-monitor-${{ matrix.buildmode }}-${{ matrix.iteration }}_log | |
| path: resource-monitor.log | |
| - name: Upload flake summary | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() | |
| with: | |
| name: flake-summary-${{ matrix.buildmode }}-${{ matrix.iteration }} | |
| path: flake-summary.txt | |
| - name: Upload Detox step log | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() | |
| with: | |
| name: detox-step-${{ matrix.buildmode }}-${{ matrix.iteration }}_log | |
| path: detox-step.log | |
| - name: Upload Metro log | |
| # https://github.com/actions/upload-artifact/releases | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() && contains(matrix.buildmode, 'debug') | |
| with: | |
| name: metro-${{ matrix.buildmode }}-${{ matrix.iteration }}_log | |
| path: metro.log | |
| - name: Upload Screen Recording | |
| # https://github.com/actions/upload-artifact/releases | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() && env.RNFB_RECORD_SCREENS == '1' | |
| with: | |
| name: screenrecording-${{ matrix.buildmode }}-${{ matrix.iteration }} | |
| path: screenrecording.* | |
| - name: Upload Firebase emulator script logs | |
| # https://github.com/actions/upload-artifact/releases | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| continue-on-error: true | |
| if: always() | |
| with: | |
| name: emulator-scripts-logs-${{ matrix.buildmode }}-${{ matrix.iteration }} | |
| path: .github/workflows/scripts/*.log | |
| # https://github.com/codecov/codecov-action/releases | |
| - name: Upload Codecov e2e TS (iOS) | |
| uses: codecov/codecov-action@e53489f4d376d79066609109e7a95a29eb3740b1 # v7.0.0 | |
| if: contains(matrix.buildmode, 'debug') | |
| continue-on-error: true | |
| with: | |
| files: coverage/lcov.info | |
| flags: e2e-ts-ios | |
| verbose: true | |
| - name: Upload Codecov iOS native | |
| uses: codecov/codecov-action@e53489f4d376d79066609109e7a95a29eb3740b1 # v7.0.0 | |
| if: contains(matrix.buildmode, 'debug') | |
| continue-on-error: true | |
| with: | |
| files: coverage/ios-native/lcov.info | |
| flags: ios-native | |
| verbose: true | |
| - name: Yarn Cache Save | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| if: "${{ github.ref == 'refs/heads/main' }}" | |
| continue-on-error: true | |
| with: | |
| path: .yarn/cache | |
| key: ${{ steps.yarn-cache.outputs.cache-primary-key }} | |
| - name: Detox Framework Cache Save | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| if: "${{ github.ref == 'refs/heads/main' }}" | |
| continue-on-error: true | |
| with: | |
| path: ~/Library/Detox/ios | |
| key: ${{ steps.detox-cache.outputs.cache-primary-key }} | |
| - name: Pods Cache Save | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| if: "${{ github.ref == 'refs/heads/main' }}" | |
| continue-on-error: true | |
| with: | |
| path: tests/ios/Pods | |
| key: ${{ steps.pods-cache.outputs.cache-primary-key }} | |
| - name: Firestore Emulator Cache Save | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| if: "${{ github.ref == 'refs/heads/main' }}" | |
| continue-on-error: true | |
| with: | |
| # The firebase emulators are pure javascript and java, OS-independent | |
| enableCrossOsArchive: true | |
| path: ~/.cache/firebase/emulators | |
| key: ${{ steps.firestore-emulator-cache.outputs.cache-primary-key }} | |
| - name: Metro Bundler Cache Save | |
| # https://github.com/actions/cache/releases | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| if: "${{ contains(matrix.buildmode, 'debug') && github.ref == 'refs/heads/main' }}" | |
| continue-on-error: true | |
| with: | |
| path: ${{ steps.workflow-variables.outputs.metro-cache }} | |
| key: ${{ steps.metro-bundler-cache.outputs.cache-primary-key }} |