Reuse local EAS builds for nightly E2E
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
---
|
||||||
|
name: Local EAS Build
|
||||||
|
description: Build an Expo app locally with a selected EAS profile.
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
platform:
|
||||||
|
description: EAS platform to build (ios or android)
|
||||||
|
required: true
|
||||||
|
profile:
|
||||||
|
description: EAS build profile
|
||||||
|
required: true
|
||||||
|
output:
|
||||||
|
description: Output path for the local build artifact
|
||||||
|
required: true
|
||||||
|
log-path:
|
||||||
|
description: Optional path to tee build output into
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
bump-build-number:
|
||||||
|
description: Run the build through use-build-number-with-bump
|
||||||
|
required: false
|
||||||
|
default: "false"
|
||||||
|
sentry-auth-token:
|
||||||
|
description: Optional Sentry authentication token
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
sentry-release:
|
||||||
|
description: Optional Sentry release
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
sentry-dist:
|
||||||
|
description: Optional Sentry distribution
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Build locally with EAS
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
PLATFORM: ${{ inputs.platform }}
|
||||||
|
PROFILE: ${{ inputs.profile }}
|
||||||
|
OUTPUT: ${{ inputs.output }}
|
||||||
|
LOG_PATH: ${{ inputs.log-path }}
|
||||||
|
BUMP_BUILD_NUMBER: ${{ inputs.bump-build-number }}
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ inputs.sentry-auth-token }}
|
||||||
|
SENTRY_RELEASE: ${{ inputs.sentry-release }}
|
||||||
|
SENTRY_DIST: ${{ inputs.sentry-dist }}
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
build_command=(
|
||||||
|
pnpm eas build
|
||||||
|
--platform "$PLATFORM"
|
||||||
|
--profile "$PROFILE"
|
||||||
|
--local
|
||||||
|
--output "$OUTPUT"
|
||||||
|
--non-interactive
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ -n "$LOG_PATH" ]; then
|
||||||
|
mkdir -p "$(dirname "$LOG_PATH")"
|
||||||
|
if [ "$BUMP_BUILD_NUMBER" = "true" ]; then
|
||||||
|
pnpm use-build-number-with-bump "${build_command[@]}" 2>&1 | tee "$LOG_PATH"
|
||||||
|
else
|
||||||
|
"${build_command[@]}" 2>&1 | tee "$LOG_PATH"
|
||||||
|
fi
|
||||||
|
elif [ "$BUMP_BUILD_NUMBER" = "true" ]; then
|
||||||
|
pnpm use-build-number-with-bump "${build_command[@]}"
|
||||||
|
else
|
||||||
|
"${build_command[@]}"
|
||||||
|
fi
|
||||||
@@ -142,32 +142,6 @@ if [[ "$platform" == "android" ]]; then
|
|||||||
adb -s "$device_id" reverse tcp:8081 tcp:8081
|
adb -s "$device_id" reverse tcp:8081 tcp:8081
|
||||||
fi
|
fi
|
||||||
|
|
||||||
phase "Building and installing the development client"
|
|
||||||
if [[ "$platform" == "ios" ]]; then
|
|
||||||
# Passing --device makes this Expo version merge simulator and devicectl
|
|
||||||
# results. On Xcode 26.4, devicectl can misclassify the simulator as a
|
|
||||||
# physical device and incorrectly require signing. Exactly one simulator is
|
|
||||||
# booted above, so Expo's default simulator-only resolver selects it.
|
|
||||||
echo "Building for already booted iOS simulator $device_id"
|
|
||||||
EXPO_PUBLIC_ENV=e2e \
|
|
||||||
NODE_ENV=test \
|
|
||||||
RN_SRC_EXT=e2e.ts,e2e.tsx \
|
|
||||||
pnpm exec expo run:ios --no-bundler \
|
|
||||||
2>&1 | tee "$artifact_dir/build.log"
|
|
||||||
else
|
|
||||||
expo_device_name="$(adb -s "$device_id" emu avd name | sed -n '1p' | tr -d '\r')"
|
|
||||||
if [[ -z "$expo_device_name" ]]; then
|
|
||||||
echo "Could not resolve the AVD name for $device_id" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Building for Android AVD $expo_device_name ($device_id)"
|
|
||||||
EXPO_PUBLIC_ENV=e2e \
|
|
||||||
NODE_ENV=test \
|
|
||||||
RN_SRC_EXT=e2e.ts,e2e.tsx \
|
|
||||||
pnpm exec expo run:android --device "$expo_device_name" --no-bundler \
|
|
||||||
2>&1 | tee "$artifact_dir/build.log"
|
|
||||||
fi
|
|
||||||
|
|
||||||
phase "Running Maestro flows"
|
phase "Running Maestro flows"
|
||||||
set +e
|
set +e
|
||||||
maestro test \
|
maestro test \
|
||||||
|
|||||||
@@ -108,16 +108,15 @@ jobs:
|
|||||||
google-services-token: ${{ secrets.GOOGLE_SERVICES_TOKEN }}
|
google-services-token: ${{ secrets.GOOGLE_SERVICES_TOKEN }}
|
||||||
|
|
||||||
- name: 🏗️ EAS Build
|
- name: 🏗️ EAS Build
|
||||||
env:
|
uses: ./.github/actions/eas-local-build
|
||||||
PROFILE: ${{ inputs.profile || 'testflight-android' }}
|
with:
|
||||||
run: >
|
platform: android
|
||||||
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
|
profile: ${{ inputs.profile || 'testflight-android' }}
|
||||||
SENTRY_RELEASE=${{ steps.env.outputs.release-version }}
|
output: build.aab
|
||||||
SENTRY_DIST=${{ steps.env.outputs.bundle-identifier }}
|
bump-build-number: "true"
|
||||||
pnpm use-build-number-with-bump
|
sentry-auth-token: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
pnpm eas build -p android
|
sentry-release: ${{ steps.env.outputs.release-version }}
|
||||||
--profile $PROFILE
|
sentry-dist: ${{ steps.env.outputs.bundle-identifier }}
|
||||||
--local --output build.aab --non-interactive
|
|
||||||
|
|
||||||
- name: 📚 Get version from package.json
|
- name: 📚 Get version from package.json
|
||||||
id: get-build-info
|
id: get-build-info
|
||||||
|
|||||||
@@ -129,16 +129,15 @@ jobs:
|
|||||||
google-services-token: ${{ secrets.GOOGLE_SERVICES_TOKEN }}
|
google-services-token: ${{ secrets.GOOGLE_SERVICES_TOKEN }}
|
||||||
|
|
||||||
- name: 🏗️ EAS Build
|
- name: 🏗️ EAS Build
|
||||||
env:
|
uses: ./.github/actions/eas-local-build
|
||||||
PROFILE: ${{ inputs.profile || 'testflight' }}
|
with:
|
||||||
run: >
|
platform: ios
|
||||||
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
|
profile: ${{ inputs.profile || 'testflight' }}
|
||||||
SENTRY_RELEASE=${{ steps.env.outputs.release-version }}
|
output: build.tar.gz
|
||||||
SENTRY_DIST=${{ steps.env.outputs.bundle-identifier }}
|
bump-build-number: "true"
|
||||||
pnpm use-build-number-with-bump
|
sentry-auth-token: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
pnpm eas build -p ios
|
sentry-release: ${{ steps.env.outputs.release-version }}
|
||||||
--profile $PROFILE
|
sentry-dist: ${{ steps.env.outputs.bundle-identifier }}
|
||||||
--local --output build.tar.gz --non-interactive
|
|
||||||
|
|
||||||
- name: 📂 Extract build artifact
|
- name: 📂 Extract build artifact
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -117,6 +117,29 @@ jobs:
|
|||||||
xcrun simctl bootstatus "$udid" -b
|
xcrun simctl bootstatus "$udid" -b
|
||||||
echo "Using $device_name on $runtime_name ($udid)"
|
echo "Using $device_name on $runtime_name ($udid)"
|
||||||
|
|
||||||
|
- name: Mark iOS development client build phase
|
||||||
|
run: echo "Building the iOS development client" > artifacts/ios/phase.txt
|
||||||
|
|
||||||
|
- name: Build iOS development client
|
||||||
|
uses: ./.github/actions/eas-local-build
|
||||||
|
with:
|
||||||
|
platform: ios
|
||||||
|
profile: e2e
|
||||||
|
output: ${{ runner.temp }}/nightly-e2e-ios.tar.gz
|
||||||
|
log-path: artifacts/ios/build.log
|
||||||
|
|
||||||
|
- name: Install iOS development client
|
||||||
|
run: |
|
||||||
|
build_contents="$RUNNER_TEMP/nightly-e2e-ios-build"
|
||||||
|
mkdir -p "$build_contents"
|
||||||
|
tar -xzf "$RUNNER_TEMP/nightly-e2e-ios.tar.gz" -C "$build_contents"
|
||||||
|
app_path=$(find "$build_contents" -type d -name '*.app' -print -quit)
|
||||||
|
if [ -z "$app_path" ]; then
|
||||||
|
echo "The local EAS build did not contain an iOS simulator app" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
xcrun simctl install "$IOS_UDID" "$app_path" 2>&1 | tee -a artifacts/ios/build.log
|
||||||
|
|
||||||
- name: Run iOS Maestro suite
|
- name: Run iOS Maestro suite
|
||||||
run: .github/scripts/run-nightly-e2e.sh ios "$IOS_UDID"
|
run: .github/scripts/run-nightly-e2e.sh ios "$IOS_UDID"
|
||||||
|
|
||||||
@@ -252,6 +275,22 @@ jobs:
|
|||||||
adb -s emulator-5554 shell settings put global transition_animation_scale 0
|
adb -s emulator-5554 shell settings put global transition_animation_scale 0
|
||||||
adb -s emulator-5554 shell settings put global animator_duration_scale 0
|
adb -s emulator-5554 shell settings put global animator_duration_scale 0
|
||||||
|
|
||||||
|
- name: Mark Android development client build phase
|
||||||
|
run: echo "Building the Android development client" > artifacts/android/phase.txt
|
||||||
|
|
||||||
|
- name: Build Android development client
|
||||||
|
uses: ./.github/actions/eas-local-build
|
||||||
|
with:
|
||||||
|
platform: android
|
||||||
|
profile: e2e
|
||||||
|
output: ${{ runner.temp }}/nightly-e2e-android.apk
|
||||||
|
log-path: artifacts/android/build.log
|
||||||
|
|
||||||
|
- name: Install Android development client
|
||||||
|
run: |
|
||||||
|
adb -s emulator-5554 install -r "$RUNNER_TEMP/nightly-e2e-android.apk" \
|
||||||
|
2>&1 | tee -a artifacts/android/build.log
|
||||||
|
|
||||||
- name: Run Android Maestro suite
|
- name: Run Android Maestro suite
|
||||||
run: .github/scripts/run-nightly-e2e.sh android emulator-5554
|
run: .github/scripts/run-nightly-e2e.sh android emulator-5554
|
||||||
|
|
||||||
|
|||||||
@@ -19,13 +19,17 @@ appId: xyz.blueskyweb.app
|
|||||||
when:
|
when:
|
||||||
platform: Android
|
platform: Android
|
||||||
commands:
|
commands:
|
||||||
- tapOn: 'http://localhost:8081'
|
- openLink: "exp+bluesky://expo-development-client/?url=http%3A%2F%2Flocalhost%3A8081"
|
||||||
- runFlow:
|
- runFlow:
|
||||||
label: "Dismiss Expo dev menu"
|
label: "Dismiss Expo dev menu"
|
||||||
when:
|
when:
|
||||||
visible: "Continue"
|
visible: "Continue"
|
||||||
commands:
|
commands:
|
||||||
- back
|
- back
|
||||||
|
- extendedWaitUntil:
|
||||||
|
visible:
|
||||||
|
id: e2eProxyHeaderInput
|
||||||
|
timeout: 60000
|
||||||
- tapOn:
|
- tapOn:
|
||||||
id: e2eProxyHeaderInput
|
id: e2eProxyHeaderInput
|
||||||
- inputText: ${output.result}
|
- inputText: ${output.result}
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ used. iOS runs on `macos-26-xlarge` with Xcode 26.4. Android runs on
|
|||||||
`Linux-x64-32core`. Both use Java 17 and the Node and pnpm versions declared in
|
`Linux-x64-32core`. Both use Java 17 and the Node and pnpm versions declared in
|
||||||
`package.json`. The iOS job selects an iPhone 17 simulator running iOS 26.5;
|
`package.json`. The iOS job selects an iPhone 17 simulator running iOS 26.5;
|
||||||
Android uses a Pixel 6 AVD with the API 35 Google APIs x86_64 image.
|
Android uses a Pixel 6 AVD with the API 35 Google APIs x86_64 image.
|
||||||
|
Both development clients use the `e2e` EAS profile and the same reusable local
|
||||||
|
EAS build action as the release build workflows; the resulting simulator app
|
||||||
|
and APK are installed directly on the selected devices.
|
||||||
|
|
||||||
The mock-server manager listens on host port 1986 and creates test services on
|
The mock-server manager listens on host port 1986 and creates test services on
|
||||||
port 3000. Metro listens on 8081. Android reverses ports 3000 and 8081 into the
|
port 3000. Metro listens on 8081. Android reverses ports 3000 and 8081 into the
|
||||||
|
|||||||
@@ -21,6 +21,17 @@
|
|||||||
"EXPO_PUBLIC_ENV": "production"
|
"EXPO_PUBLIC_ENV": "production"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"e2e": {
|
||||||
|
"extends": "development",
|
||||||
|
"android": {
|
||||||
|
"buildType": "apk"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"EXPO_PUBLIC_ENV": "e2e",
|
||||||
|
"NODE_ENV": "test",
|
||||||
|
"RN_SRC_EXT": "e2e.ts,e2e.tsx"
|
||||||
|
}
|
||||||
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"extends": "base",
|
"extends": "base",
|
||||||
"distribution": "internal",
|
"distribution": "internal",
|
||||||
|
|||||||
Reference in New Issue
Block a user