Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/large-aliens-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
7 changes: 0 additions & 7 deletions .github/workflows/actions.lock
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ workflows:
- 'actions/checkout@v4.4.0'
- 'actions/setup-java@v4.9.1'
- 'actions/setup-node@v4.4.0'
- 'actions/upload-artifact@v4.6.2'
- 'gradle/actions@v6.3.0'
- 'pnpm/action-setup@v4.3.0'
- 'reactivecircus/android-emulator-runner@v2.38.0'
'.github/workflows/labeler-apply.yml':
- 'actions/checkout@v4.4.0'
- 'actions/download-artifact@v4.3.0'
Expand Down Expand Up @@ -202,11 +200,6 @@ dependencies:
commit: 'sha1-4ed28566c2bdcdaee6dca2b46b9666d01b4ed8a4'
owner_id: 56475783
repo_id: 280818415
'reactivecircus/android-emulator-runner@v2.38.0':
ref: 'v2.38.0'
commit: 'sha1-a421e43855164a8197daf9d8d40fe71c6996bb0d'
owner_id: 51352484
repo_id: 219782401
'slackapi/slack-github-action@v1.27.1':
ref: 'v1.27.1'
commit: 'sha1-fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3'
Expand Down
192 changes: 8 additions & 184 deletions .github/workflows/expo-native-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ on:
- 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/**'
Expand All @@ -25,22 +23,15 @@ concurrency:

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 }})
name: Native 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 }}_
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
Expand All @@ -54,11 +45,9 @@ jobs:
- expo-sdk: 58
platform: android
runner: blacksmith-8vcpu-ubuntu-2204
run-e2e: true
- expo-sdk: 58
platform: ios
runner: blacksmith-6vcpu-macos-26
run-e2e: true

steps:
- name: Checkout repo
Expand Down Expand Up @@ -103,18 +92,18 @@ jobs:
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 }}
key: expo-native-build-v1-${{ runner.os }}-${{ matrix.expo-sdk }}-${{ matrix.platform }}-${{ steps.native-build-key.outputs.hash }}

- if: steps.native-build-cache.outputs.cache-hit != 'true' || matrix.run-e2e == true
- if: steps.native-build-cache.outputs.cache-hit != 'true'
uses: pnpm/action-setup@v4.3.0
- if: steps.native-build-cache.outputs.cache-hit != 'true' || matrix.run-e2e == true
- if: steps.native-build-cache.outputs.cache-hit != 'true'
uses: actions/setup-node@v4.4.0
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
if: steps.native-build-cache.outputs.cache-hit != 'true'
run: pnpm install --frozen-lockfile

- name: Build and pack Clerk packages
Expand All @@ -132,7 +121,6 @@ jobs:
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
Expand All @@ -142,49 +130,13 @@ jobs:
NATIVE_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-native-components-*.tgz)"
BIOMETRICS_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-biometrics-*.tgz)"
pnpm add "$SDK_TARBALL" "$GOOGLE_SIGNIN_TARBALL" "$NATIVE_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"
pnpm expo install expo-auth-session expo-constants expo-crypto expo-dev-client expo-secure-store expo-web-browser

- 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
echo "EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=$FIXTURE_PUBLISHABLE_KEY" > .env

- name: Set up JDK 17
if: matrix.platform == 'android'
Expand Down Expand Up @@ -237,131 +189,3 @@ jobs:
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@v4.3.0
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@v4.3.0
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@v2.38.0
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@v2.38.0
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@v4.6.2
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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ packages/*/examples/*/package-lock.json
packages/*/examples/*/yarn.lock
/test-results/
/playwright-report/
/integration/.e2e/
/playwright/.cache/

# integration testing
Expand Down
15 changes: 0 additions & 15 deletions integration/e2e.expo-native.config.ts

This file was deleted.

Loading
Loading