Repository navigation
chore(expo): bump clerk-ios to 1.6.0 #1115
Workflow file for this run
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: Expo | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| branches: | |
| - main | |
| paths: | |
| - '.github/workflows/expo-native-build.yml' | |
| - 'integration/e2e.expo-native.config.ts' | |
| - 'integration/templates/expo-native/**' | |
| - 'integration/tests/expo-native/**' | |
| - 'packages/expo/**' | |
| - 'packages/expo-biometrics/**' | |
| - 'packages/expo-google-signin/**' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: expo-native-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| FIXTURE_DIR: integration/templates/expo-native | |
| E2E_DIR: integration/tests/expo-native | |
| FIXTURE_PUBLISHABLE_KEY: pk_test_ZHVtbXkuY2xlcmsuYWNjb3VudHMuZGV2JA | |
| SDK_PACK_DIR: /tmp/clerk-expo-pack | |
| E2E_INSTANCE_NAME: clerkstage-with-native-components | |
| BAPI_URL: https://api.clerkstage.dev | |
| IOS_SIMULATORS: '2' | |
| E2E_TELEMETRY_DISABLED: '1' | |
| jobs: | |
| native-build: | |
| if: ${{ github.head_ref != 'changeset-release/main' && (github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false) }} | |
| name: Native ${{ matrix.run-e2e == true && 'E2E' || 'Build' }} (${{ matrix.platform }}, sdk ${{ matrix.expo-sdk }}) | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: ${{ matrix.run-e2e == true && 60 || 45 }} | |
| env: | |
| CLERK_TEST_USERNAME_PREFIX: e2e_${{ github.run_id }}_${{ matrix.platform }}_ | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - expo-sdk: 54 | |
| platform: android | |
| runner: blacksmith-8vcpu-ubuntu-2204 | |
| - expo-sdk: 54 | |
| platform: ios | |
| runner: blacksmith-6vcpu-macos-26 | |
| - expo-sdk: 55 | |
| platform: android | |
| runner: blacksmith-8vcpu-ubuntu-2204 | |
| - expo-sdk: 55 | |
| platform: ios | |
| runner: blacksmith-6vcpu-macos-26 | |
| - expo-sdk: 57 | |
| platform: android | |
| runner: blacksmith-8vcpu-ubuntu-2204 | |
| run-e2e: true | |
| - expo-sdk: 57 | |
| platform: ios | |
| runner: blacksmith-6vcpu-macos-26 | |
| run-e2e: true | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| persist-credentials: false | |
| - name: Compute native build cache key | |
| id: native-build-key | |
| env: | |
| PLATFORM: ${{ matrix.platform }} | |
| run: | | |
| build_hash="$( | |
| git ls-files -s -- \ | |
| .npmrc \ | |
| package.json \ | |
| pnpm-lock.yaml \ | |
| pnpm-workspace.yaml \ | |
| tsconfig.json \ | |
| turbo.json \ | |
| packages/clerk-js \ | |
| packages/expo \ | |
| packages/expo-biometrics \ | |
| packages/expo-google-signin \ | |
| packages/react \ | |
| packages/shared \ | |
| "$FIXTURE_DIR" | | |
| git hash-object --stdin | |
| )" | |
| if [ "$PLATFORM" = "android" ]; then | |
| artifact="$FIXTURE_DIR/android/app/build/outputs/apk/release/app-release.apk" | |
| else | |
| artifact="$FIXTURE_DIR/ios/build/Build/Products/Release-iphonesimulator/ClerkExpoNativeBuildFixture.app" | |
| fi | |
| echo "hash=$build_hash" >> "$GITHUB_OUTPUT" | |
| echo "artifact=$artifact" >> "$GITHUB_OUTPUT" | |
| - name: Restore native build | |
| id: native-build-cache | |
| uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ${{ steps.native-build-key.outputs.artifact }} | |
| # Bump the version when native build commands change. | |
| key: expo-native-build-v1-${{ runner.os }}-${{ matrix.expo-sdk }}-${{ matrix.platform }}-${{ matrix.run-e2e == true && 'e2e' || 'build' }}-${{ env.E2E_INSTANCE_NAME }}-${{ steps.native-build-key.outputs.hash }} | |
| - if: steps.native-build-cache.outputs.cache-hit != 'true' || matrix.run-e2e == true | |
| uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 | |
| - if: steps.native-build-cache.outputs.cache-hit != 'true' || matrix.run-e2e == true | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: 24.15.0 | |
| cache: pnpm | |
| - name: Install monorepo dependencies | |
| if: steps.native-build-cache.outputs.cache-hit != 'true' || matrix.run-e2e == true | |
| run: pnpm install --frozen-lockfile | |
| - name: Build and pack Clerk packages | |
| if: steps.native-build-cache.outputs.cache-hit != 'true' | |
| run: | | |
| pnpm --filter @clerk/expo... --filter @clerk/expo-biometrics build | |
| mkdir -p "$SDK_PACK_DIR" | |
| pnpm --filter @clerk/expo pack --pack-destination "$SDK_PACK_DIR" | |
| pnpm --filter @clerk/expo-google-signin pack --pack-destination "$SDK_PACK_DIR" | |
| pnpm --filter @clerk/expo-biometrics pack --pack-destination "$SDK_PACK_DIR" | |
| - name: Install fixture dependencies | |
| if: steps.native-build-cache.outputs.cache-hit != 'true' | |
| working-directory: ${{ env.FIXTURE_DIR }} | |
| env: | |
| EXPO_SDK: ${{ matrix.expo-sdk }} | |
| RUN_E2E: ${{ matrix.run-e2e == true && 'true' || 'false' }} | |
| run: | | |
| cp "package.sdk-$EXPO_SDK.json" package.json | |
| pnpm install --no-frozen-lockfile | |
| # [0-9] keeps this glob off the clerk-expo-google-signin tarball. | |
| SDK_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-[0-9]*.tgz)" | |
| GOOGLE_SIGNIN_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-google-signin-*.tgz)" | |
| BIOMETRICS_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-biometrics-*.tgz)" | |
| pnpm add "$SDK_TARBALL" "$GOOGLE_SIGNIN_TARBALL" "$BIOMETRICS_TARBALL" -w | |
| # expo-dev-client makes even release builds boot into the dev | |
| # launcher (unreachable Metro in CI), which stalls every e2e | |
| # flow on a blank screen. Skip it on e2e jobs only. | |
| DEV_CLIENT="expo-dev-client" | |
| if [ "$RUN_E2E" = "true" ]; then DEV_CLIENT=""; fi | |
| pnpm expo install expo-auth-session expo-constants expo-crypto $DEV_CLIENT expo-secure-store expo-web-browser | |
| if [ "$RUN_E2E" = "true" ]; then | |
| REACT_VERSION=$(node -p 'require("react/package.json").version') | |
| REACT_DOM_VERSION=$(node -p 'require("react-dom/package.json").version') | |
| if [ "$REACT_VERSION" != "$REACT_DOM_VERSION" ]; then | |
| echo "::error::React version mismatch: react@$REACT_VERSION, react-dom@$REACT_DOM_VERSION" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Check e2e secret availability | |
| id: gate | |
| if: matrix.run-e2e == true | |
| env: | |
| KEYS: ${{ secrets.INTEGRATION_STAGING_INSTANCE_KEYS }} | |
| run: | | |
| if [ -n "$KEYS" ]; then | |
| echo "ok=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "ok=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice::INTEGRATION_STAGING_INSTANCE_KEYS unavailable (fork PR?); running build-only." | |
| fi | |
| - name: Resolve Clerk instance keys | |
| id: keys | |
| if: steps.gate.outputs.ok == 'true' | |
| continue-on-error: true | |
| env: | |
| INTEGRATION_STAGING_INSTANCE_KEYS: ${{ secrets.INTEGRATION_STAGING_INSTANCE_KEYS }} | |
| run: node scripts/resolve-instance-keys.mjs INTEGRATION_STAGING_INSTANCE_KEYS "$E2E_INSTANCE_NAME" | |
| - name: Write fixture .env | |
| if: steps.native-build-cache.outputs.cache-hit != 'true' | |
| working-directory: ${{ env.FIXTURE_DIR }} | |
| env: | |
| E2E_PK: ${{ steps.keys.outputs.pk }} | |
| run: | | |
| echo "EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=${E2E_PK:-$FIXTURE_PUBLISHABLE_KEY}" > .env | |
| - name: Set up JDK 17 | |
| if: matrix.platform == 'android' | |
| uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| - name: Set up Gradle cache | |
| if: matrix.platform == 'android' && steps.native-build-cache.outputs.cache-hit != 'true' | |
| uses: gradle/actions/setup-gradle@4733eaac7c1b0da527e4206b7671e0061de1ce37 # v6.3.0 | |
| with: | |
| # This workflow never runs on main, so the default (write from main | |
| # only) would never seed the cache. | |
| cache-read-only: false | |
| add-job-summary: on-failure | |
| - name: Prebuild Android fixture | |
| if: matrix.platform == 'android' && steps.native-build-cache.outputs.cache-hit != 'true' | |
| working-directory: ${{ env.FIXTURE_DIR }} | |
| run: pnpm expo prebuild --clean --platform android | |
| - name: Build Android fixture | |
| if: matrix.platform == 'android' && steps.native-build-cache.outputs.cache-hit != 'true' | |
| working-directory: ${{ env.FIXTURE_DIR }} | |
| run: pnpm build:android | |
| # The module's Robolectric tests need an Expo host project for expo-modules-core, so they run in the fixture. | |
| # The packed module leaves out its tests, so they are copied in from the repo. | |
| - name: Test expo-biometrics Android module | |
| if: matrix.platform == 'android' && steps.native-build-cache.outputs.cache-hit != 'true' | |
| working-directory: ${{ env.FIXTURE_DIR }}/android | |
| run: | | |
| cp -R "$GITHUB_WORKSPACE/packages/expo-biometrics/android/src/test" "$(readlink -f ../node_modules/@clerk/expo-biometrics)/android/src/" | |
| ./gradlew :clerk-expo-biometrics:testDebugUnitTest | |
| - name: Prebuild iOS fixture | |
| if: matrix.platform == 'ios' && steps.native-build-cache.outputs.cache-hit != 'true' | |
| working-directory: ${{ env.FIXTURE_DIR }} | |
| run: pnpm expo prebuild --clean --platform ios | |
| - name: Build iOS fixture | |
| if: matrix.platform == 'ios' && steps.native-build-cache.outputs.cache-hit != 'true' | |
| working-directory: ${{ env.FIXTURE_DIR }} | |
| run: pnpm build:ios | |
| - name: Save native build | |
| if: steps.native-build-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ${{ steps.native-build-key.outputs.artifact }} | |
| key: ${{ steps.native-build-cache.outputs.cache-primary-key }} | |
| - name: Boot iOS simulators | |
| if: matrix.platform == 'ios' && matrix.run-e2e == true && steps.keys.outputs.pk != '' | |
| run: ${{ env.E2E_DIR }}/boot-ios-simulators.sh boot "$IOS_SIMULATORS" | |
| - name: Cache iOS automation runner | |
| if: matrix.platform == 'ios' && steps.keys.outputs.pk != '' | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.agent-device | |
| key: agent-device-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| restore-keys: agent-device-${{ runner.os }}- | |
| - name: Run iOS e2e | |
| id: run_e2e_ios | |
| if: matrix.platform == 'ios' && steps.keys.outputs.sk != '' | |
| env: | |
| CLERK_SECRET_KEY: ${{ steps.keys.outputs.sk }} | |
| CLERK_API_URL: ${{ env.BAPI_URL }} | |
| run: | | |
| "$E2E_DIR/boot-ios-simulators.sh" wait | |
| mkdir -p "$RUNNER_TEMP/e2e-device-logs" | |
| log_pids=() | |
| trap 'kill "${log_pids[@]}" 2>/dev/null || true; wait "${log_pids[@]}" 2>/dev/null || true' EXIT | |
| for udid in ${CLERK_TEST_DEVICES//,/ }; do | |
| xcrun simctl install "$udid" "$FIXTURE_DIR/ios/build/Build/Products/Release-iphonesimulator/ClerkExpoNativeBuildFixture.app" | |
| xcrun simctl spawn "$udid" log stream --style compact \ | |
| --predicate 'processImagePath CONTAINS "ClerkExpoNativeBuildFixture"' \ | |
| > "$RUNNER_TEMP/e2e-device-logs/$udid-console.log" 2>&1 & | |
| log_pids+=($!) | |
| done | |
| pnpm test:integration:expo-native:ios --reporter list,junit,markdown | |
| - name: Enable KVM | |
| if: matrix.platform == 'android' && steps.keys.outputs.sk != '' | |
| run: | | |
| echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules | |
| sudo udevadm control --reload-rules | |
| sudo udevadm trigger --name-match=kvm | |
| - name: AVD cache | |
| id: avd-cache | |
| if: matrix.platform == 'android' && steps.keys.outputs.sk != '' | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: | | |
| ~/.android/avd/* | |
| ~/.android/adb* | |
| key: avd-34-google_apis-x86_64-v1 | |
| - name: Create AVD snapshot | |
| if: matrix.platform == 'android' && steps.keys.outputs.sk != '' && steps.avd-cache.outputs.cache-hit != 'true' | |
| uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2 | |
| with: | |
| api-level: 34 | |
| target: google_apis | |
| arch: x86_64 | |
| force-avd-creation: false | |
| emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim | |
| disable-animations: false | |
| script: echo "Generated AVD snapshot for caching." | |
| - name: Run Android e2e | |
| id: run_e2e_android | |
| if: matrix.platform == 'android' && steps.keys.outputs.sk != '' | |
| uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2 | |
| env: | |
| CLERK_SECRET_KEY: ${{ steps.keys.outputs.sk }} | |
| CLERK_API_URL: ${{ env.BAPI_URL }} | |
| with: | |
| api-level: 34 | |
| target: google_apis | |
| arch: x86_64 | |
| force-avd-creation: false | |
| emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim | |
| disable-animations: true | |
| # The action runs each script line in a separate sh -c; the folded | |
| # scalar (>-) plus && keeps everything in one shell invocation. | |
| script: >- | |
| mkdir -p "$RUNNER_TEMP/e2e-device-logs" && | |
| adb install -r "$FIXTURE_DIR/android/app/build/outputs/apk/release/app-release.apk" && | |
| (adb logcat -v threadtime > "$RUNNER_TEMP/e2e-device-logs/logcat.log" 2>&1 &) && | |
| pnpm test:integration:expo-native:android --reporter list,junit,markdown | |
| - name: Delete leftover test users | |
| if: always() && steps.keys.outputs.sk != '' | |
| env: | |
| CLERK_SECRET_KEY: ${{ steps.keys.outputs.sk }} | |
| run: | | |
| curl -fsS -G "$BAPI_URL/v1/users" --data-urlencode "limit=100" --data-urlencode "query=$CLERK_TEST_USERNAME_PREFIX" -H "Authorization: Bearer $CLERK_SECRET_KEY" | | |
| jq -r --arg p "$CLERK_TEST_USERNAME_PREFIX" '.[] | select((.username // "") | startswith($p)) | .id' | | |
| while read -r user_id; do | |
| curl -fsS --retry 3 --retry-delay 1 -o /dev/null -X DELETE "$BAPI_URL/v1/users/$user_id" -H "Authorization: Bearer $CLERK_SECRET_KEY" || | |
| echo "::warning::Could not delete leftover test user $user_id" | |
| done | |
| - name: Upload e2e artifacts | |
| if: always() && steps.keys.outputs.sk != '' | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: e2e-${{ matrix.platform }} | |
| include-hidden-files: true | |
| path: | | |
| integration/.e2e | |
| ${{ runner.temp }}/e2e-device-logs | |
| if-no-files-found: warn | |
| retention-days: 7 | |
| - name: Report e2e outcome | |
| if: always() && steps.keys.outputs.sk != '' | |
| env: | |
| IOS_OUTCOME: ${{ steps.run_e2e_ios.outcome }} | |
| ANDROID_OUTCOME: ${{ steps.run_e2e_android.outcome }} | |
| run: | | |
| outcome="$IOS_OUTCOME" | |
| [ "$outcome" = "skipped" ] && outcome="$ANDROID_OUTCOME" | |
| echo "## Native e2e (${{ matrix.platform }}): $outcome" >> "$GITHUB_STEP_SUMMARY" | |
| if [ -f integration/.e2e/summary.md ]; then | |
| cat integration/.e2e/summary.md >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| if [ "$outcome" = "failure" ]; then | |
| echo "::error::Native e2e failed. See the e2e-${{ matrix.platform }} artifact." | |
| fi | |
| flaky=$(jq -r '[.run.results[] | select(.status == "flaky") | .file] | join(", ")' integration/.e2e/report.json 2>/dev/null || true) | |
| if [ -n "$flaky" ]; then | |
| echo "::error::Flaky flow(s), failed then passed on the retry: $flaky" | |
| exit 1 | |
| fi |