diff --git a/.github/actions/boot-simulator/action.yml b/.github/actions/boot-simulator/action.yml new file mode 100644 index 000000000..2c217e7d2 --- /dev/null +++ b/.github/actions/boot-simulator/action.yml @@ -0,0 +1,51 @@ +name: 'Boot iOS Simulator' +description: 'Boots an iOS simulator with retry logic and timeout handling' +author: 'Bitwarden' + +inputs: + simulator-name: + description: 'Name of the simulator device (e.g., iPhone 17 Pro)' + required: true + simulator-version: + description: 'iOS version for the simulator (e.g., 26.0)' + required: true + +runs: + using: 'composite' + steps: + - name: Boot Simulator + shell: bash + env: + _SIMULATOR_NAME: ${{ inputs.simulator-name }} + _SIMULATOR_VERSION: ${{ inputs.simulator-version }} + run: | + echo "Listing simulator devices:" + SIMULATORS=$(xcrun simctl list devices "iOS $_SIMULATOR_VERSION" available) + echo "$SIMULATORS" + DEVICE_ID=$(echo "$SIMULATORS" | grep "$_SIMULATOR_NAME" | head -1 | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/') + echo "--------------------------------" + echo "👀 Updating dyld_shared_cache:" + xcrun simctl runtime dyld_shared_cache update --all + echo "--------------------------------" + echo "👀 Booting simulator: $_SIMULATOR_NAME ($_SIMULATOR_VERSION) with ID: $DEVICE_ID" + + i=1 + max=5 + while [ $i -le $max ]; do + echo "👀 Launching Simulator (Attempt $i/$max)" + # Brewfile installs coreutils which includes gtimeout + if gtimeout -s SIGKILL 2m xcrun simctl bootstatus "$DEVICE_ID" -b; then + echo "✅ Simulator booted successfully" + exit 0 + else + echo "❌ Simulator boot timed out. Shutting down..." + xcrun simctl shutdown "$DEVICE_ID" || true # prevents "Unable to shutdown device in current state: Shutdown" error + + echo "🔁 Retrying in 5s..." + i=$((i + 1)) + sleep 5 + fi + done + + echo "::error::Failed to boot simulator after $max attempts." + exit 1 diff --git a/.github/workflows/test-bwa.yml b/.github/workflows/test-bwa.yml index 011f531c5..6e70269a3 100644 --- a/.github/workflows/test-bwa.yml +++ b/.github/workflows/test-bwa.yml @@ -128,17 +128,10 @@ jobs: ./Scripts/bootstrap.sh - name: Boot Simulator - run: | - echo "Listing simulator devices:" - SIMULATORS=$(xcrun simctl list devices "iOS $_SIMULATOR_VERSION" available) - echo "$SIMULATORS" - DEVICE_ID=$(echo "$SIMULATORS" | grep "$_SIMULATOR_NAME" | head -1 | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/') - echo "--------------------------------" - echo "👀 Updating dyld_shared_cache:" - xcrun simctl runtime dyld_shared_cache update --all - echo "--------------------------------" - echo "👀 Booting simulator: $_SIMULATOR_NAME ($_SIMULATOR_VERSION) with ID: $DEVICE_ID" - xcrun simctl bootstatus "$DEVICE_ID" -b + uses: ./.github/actions/boot-simulator + with: + simulator-name: ${{ env._SIMULATOR_NAME }} + simulator-version: ${{ env._SIMULATOR_VERSION }} - name: Build run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bcef0286e..887a0b514 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -123,17 +123,10 @@ jobs: ./Scripts/bootstrap.sh - name: Boot Simulator - run: | - echo "Listing simulator devices:" - SIMULATORS=$(xcrun simctl list devices "iOS $_SIMULATOR_VERSION" available) - echo "$SIMULATORS" - DEVICE_ID=$(echo "$SIMULATORS" | grep "$_SIMULATOR_NAME" | head -1 | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/') - echo "--------------------------------" - echo "👀 Updating dyld_shared_cache:" - xcrun simctl runtime dyld_shared_cache update --all - echo "--------------------------------" - echo "👀 Booting simulator: $_SIMULATOR_NAME ($_SIMULATOR_VERSION) with ID: $DEVICE_ID" - xcrun simctl bootstatus "$DEVICE_ID" -b + uses: ./.github/actions/boot-simulator + with: + simulator-name: ${{ env._SIMULATOR_NAME }} + simulator-version: ${{ env._SIMULATOR_VERSION }} - name: Build run: | diff --git a/Brewfile b/Brewfile index 91c1984d8..cd7145663 100644 --- a/Brewfile +++ b/Brewfile @@ -5,4 +5,5 @@ brew "swift-protobuf" # used by Bitwarden Authenticator if ENV["CI"] brew "yq" brew "xcresultparser" + brew "coreutils" # using gtimeout in test workflows to stop hanging simulators end