Skip to content

E2E Migration (iOS) #93

E2E Migration (iOS)

E2E Migration (iOS) #93

Workflow file for this run

name: E2E Migration (iOS)
on:
workflow_dispatch:
inputs:
e2e_branch:
description: "Branch of synonymdev/bitkit-e2e-tests to use (main | default-feature-branch | custom branch name)"
required: false
default: "default-feature-branch"
schedule:
- cron: "0 3 * * *"
env:
TERM: xterm-256color
FORCE_COLOR: 1
SIMULATOR_NAME: "iPhone 17"
IOS_VERSION: "26.2"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
if: github.event.pull_request.draft == false
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "26.2"
- name: System Information
run: |
echo "=== System Information ==="
echo "macOS Version:"
sw_vers
echo ""
echo "Xcode Version:"
xcodebuild -version
- name: Install xcbeautify
run: |
brew install xcbeautify
- name: Cache Swift Package Manager
uses: actions/cache@v5
with:
path: |
~/Library/Caches/org.swift.swiftpm
~/Library/org.swift.swiftpm
Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
- name: Install dependencies
run: |
echo "⏱️ Starting dependency resolution at $(date)"
xcodebuild -resolvePackageDependencies -onlyUsePackageVersionsFromResolvedFile | xcbeautify
echo "✅ Dependencies resolved at $(date)"
- name: Pre-start simulator
run: |
echo "⏱️ Starting simulator at $(date)"
xcrun simctl boot "${{ env.SIMULATOR_NAME }}" || true
echo "✅ Simulator started at $(date)"
- name: Build iOS app (regtest)
env:
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CHATWOOT_API: ${{ secrets.CHATWOOT_API }}
GEO: false
E2E_BACKEND: network
E2E_NETWORK: regtest
run: |
echo "=== Building iOS app (regtest) ==="
echo "Using simulator: ${{ env.SIMULATOR_NAME }} (iOS ${{ env.IOS_VERSION }})"
if xcodebuild -showsdks | grep -q "iOS Simulator"; then
echo "✅ iOS Simulator platform already installed"
else
echo "⚙️ iOS Simulator platform not found — downloading..."
xcodebuild -downloadPlatform iOS
fi
xcodebuild -workspace Bitkit.xcodeproj/project.xcworkspace \
-scheme Bitkit \
-configuration Debug \
-destination "platform=iOS Simulator,name=${{ env.SIMULATOR_NAME }},OS=${{ env.IOS_VERSION }}" \
-derivedDataPath DerivedData \
SWIFT_ACTIVE_COMPILATION_CONDITIONS='$(inherited) E2E_BUILD' \
-allowProvisioningUpdates \
build
- name: Prepare app for E2E tests (regtest)
run: |
# Copy the .app bundle to the expected location and name
mkdir -p e2e-app
cp -r DerivedData/Build/Products/Debug-iphonesimulator/Bitkit.app e2e-app/bitkit.app
- name: Upload iOS app (regtest)
uses: actions/upload-artifact@v6
with:
name: bitkit-e2e-ios_${{ github.run_number }}
path: e2e-app/
e2e-branch:
if: github.event.pull_request.draft == false
uses: synonymdev/bitkit-e2e-tests/.github/workflows/determine-e2e-branch.yml@main
with:
app_branch: ${{ github.head_ref || github.ref_name }}
e2e_branch_input: ${{ github.event.inputs.e2e_branch || 'default-feature-branch' }}
prepare-wallets:
if: github.event.pull_request.draft == false
uses: synonymdev/bitkit-e2e-tests/.github/workflows/migration-wallet-setup.yml@main
needs: [e2e-branch]
strategy:
fail-fast: false
matrix:
rn_version:
- v1.1.6
scenario:
- { name: migration_1-restore, setup_type: standard }
- { name: migration_2-migration, setup_type: standard }
- { name: migration_3-with-passphrase, setup_type: passphrase }
- { name: migration_4-with-sweep, setup_type: sweep }
with:
e2e_branch: ${{ needs.e2e-branch.outputs.branch }}
rn_version: ${{ matrix.rn_version }}
setup_type: ${{ matrix.scenario.setup_type }}
scenario_name: ${{ matrix.scenario.name }}
e2e-tests:
if: github.event.pull_request.draft == false
runs-on: macos-latest
needs: [build, e2e-branch, prepare-wallets]
strategy:
fail-fast: false
matrix:
rn_version:
- v1.1.6
scenario:
- { name: migration_1-restore, setup_type: standard, grep: "@migration_1" }
- { name: migration_2-migration, setup_type: standard, grep: "@migration_2" }
- { name: migration_3-with-passphrase, setup_type: passphrase, grep: "@migration_3" }
- { name: migration_4-with-sweep, setup_type: sweep, grep: "@migration_4" }
name: e2e-tests - ${{ matrix.rn_version }} - ${{ matrix.scenario.name }}
env:
BACKEND: regtest
steps:
- name: Show selected E2E branch
env:
E2E_BRANCH: ${{ needs.e2e-branch.outputs.branch }}
run: echo $E2E_BRANCH
- name: Clone E2E tests
uses: actions/checkout@v6
with:
repository: synonymdev/bitkit-e2e-tests
path: bitkit-e2e-tests
ref: ${{ needs.e2e-branch.outputs.branch }}
- name: Download iOS app
uses: actions/download-artifact@v6
with:
name: bitkit-e2e-ios_${{ github.run_number }}
path: bitkit-e2e-tests/aut
- name: Download migration env
uses: actions/download-artifact@v6
with:
name: migration-env_${{ matrix.rn_version }}_${{ matrix.scenario.name }}
path: bitkit-e2e-tests/artifacts
- name: Export migration env
working-directory: bitkit-e2e-tests
run: |
set -euo pipefail
env_file="artifacts/migration_setup_${{ matrix.scenario.setup_type }}.env"
echo "=== Env file contents ==="
cat "$env_file"
echo "========================="
cat "$env_file" >> "$GITHUB_ENV"
- name: Download RN app for migration
run: |
mkdir -p bitkit-e2e-tests/aut
curl -L -o bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.zip \
https://github.com/synonymdev/bitkit-e2e-tests/releases/download/migration-rn-regtest/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.zip
unzip -o bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.zip -d bitkit-e2e-tests/aut
# Rename the versioned RN app to the expected default name
# (Bitkit.app / bitkit.app is the native app - don't touch it)
if [ -d "bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.app" ]; then
mv "bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.app" \
"bitkit-e2e-tests/aut/bitkit_rn_regtest_ios.app"
echo "Renamed bitkit_rn_regtest_ios_${{ matrix.rn_version }}.app to bitkit_rn_regtest_ios.app"
fi
- name: List app directory contents
run: ls -la bitkit-e2e-tests/aut
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 22
- name: Cache npm cache
uses: actions/cache@v5
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
working-directory: bitkit-e2e-tests
run: npm ci
- name: Install ffmpeg
run: |
echo "Installing ffmpeg..."
brew install ffmpeg || brew upgrade ffmpeg || true
echo "ffmpeg version: $(ffmpeg -version | head -1)"
- name: Boot Simulator
run: |
echo "Erasing simulator..."
xcrun simctl erase "${{ env.SIMULATOR_NAME }}" || true
echo "Booting simulator..."
xcrun simctl boot "${{ env.SIMULATOR_NAME }}" || true
echo "Waiting for boot status..."
xcrun simctl bootstatus "${{ env.SIMULATOR_NAME }}" -b
echo "Opening Simulator app to ensure UI is ready..."
open -a Simulator
echo "Waiting for simulator to fully initialize..."
sleep 30
echo "Verifying simulator state..."
xcrun simctl list devices booted
- name: Start Appium Server
working-directory: bitkit-e2e-tests
run: |
echo "Starting Appium server..."
npx appium --log-timestamp --log-no-colors > appium.log 2>&1 &
APPIUM_PID=$!
echo "APPIUM_PID=$APPIUM_PID" >> $GITHUB_ENV
echo "Waiting for Appium server to be ready..."
for i in {1..30}; do
if curl -s http://127.0.0.1:4723/status > /dev/null 2>&1; then
echo "Appium server is ready!"
break
fi
echo "Waiting for Appium... ($i/30)"
sleep 2
done
curl -s http://127.0.0.1:4723/status || echo "Warning: Appium status check failed"
- name: Run E2E Tests 1 (${{ matrix.scenario.name }})
continue-on-error: true
id: test1
working-directory: bitkit-e2e-tests
run: ./ci_run_ios.sh --mochaOpts.grep '${{ matrix.scenario.grep }}'
env:
SIMULATOR_NAME: ${{ env.SIMULATOR_NAME }}
SIMULATOR_OS_VERSION: ${{ env.IOS_VERSION }}
RECORD_VIDEO: true
ATTEMPT: 1
- name: Run E2E Tests 2 (${{ matrix.scenario.name }})
continue-on-error: true
if: steps.test1.outcome != 'success'
id: test2
working-directory: bitkit-e2e-tests
run: ./ci_run_ios.sh --mochaOpts.grep "${{ matrix.scenario.grep }}"
env:
SIMULATOR_NAME: ${{ env.SIMULATOR_NAME }}
SIMULATOR_OS_VERSION: ${{ env.IOS_VERSION }}
RECORD_VIDEO: true
ATTEMPT: 2
- name: Run E2E Tests 3 (${{ matrix.scenario.name }})
if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success'
id: test3
working-directory: bitkit-e2e-tests
run: ./ci_run_ios.sh --mochaOpts.grep "${{ matrix.scenario.grep }}"
env:
SIMULATOR_NAME: ${{ env.SIMULATOR_NAME }}
SIMULATOR_OS_VERSION: ${{ env.IOS_VERSION }}
RECORD_VIDEO: true
ATTEMPT: 3
- name: Copy Appium logs to artifacts
if: always()
working-directory: bitkit-e2e-tests
run: |
mkdir -p artifacts
cp appium.log artifacts/ || true
- name: Upload E2E Artifacts (${{ matrix.scenario.name }})
if: failure()
uses: actions/upload-artifact@v6
with:
name: e2e-artifacts_${{ matrix.scenario.name }}_${{ matrix.rn_version }}_${{ github.run_number }}
path: bitkit-e2e-tests/artifacts/