From 0bfebe187189d35f8bf54e69fbf0dac173d2046b Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Thu, 3 Sep 2026 10:08:48 +0200 Subject: [PATCH 01/10] Run the iOS Maestro E2E on Linux against remote simulators via sim-remote Move the E2E test jobs from macOS runners to ubuntu-latest, driving a fleet simulator through sim-remote's Maestro shims, and put the template-app build job on macos-26: larger GitHub-hosted runners are not enabled for this org, so macos-26-large queues forever. The maestro-ios action installs libplist-utils for the plutil shim, downloads sim-remote with a preflight for install-shims, logs in and retries acquire (the router clamps one wait to 300s), and logs out when done. The runner script skips foregrounding the simulator (no local GUI) and opens a reverse tunnel so the app can reach the runner-local Metro in Debug. --- .github/actions/maestro-ios/action.yml | 60 +++++++++++++++++++++-- .github/workflow-scripts/maestro-ios.js | 20 ++++++++ .github/workflows/e2e-ios-rntester.yml | 6 ++- .github/workflows/e2e-ios-templateapp.yml | 10 +++- 4 files changed, 90 insertions(+), 6 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index b5e4036d6280..f20d79114549 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -1,5 +1,5 @@ name: Maestro E2E iOS -description: Runs E2E Tests on iOS using Maestro +description: Runs E2E Tests on iOS using Maestro against a remote simulator via sim-remote inputs: app-path: required: true @@ -35,9 +35,55 @@ runs: run: export MAESTRO_VERSION=2.6.1; curl -Ls "https://get.maestro.mobile.dev" | bash - name: Installing Maestro dependencies shell: bash + # libplist-utils provides plistutil, which backs the sim-remote plutil + # shim (Maestro pipes `simctl listapps` output through `plutil`). run: | - brew tap facebook/fb - brew install facebook/fb/idb-companion + sudo apt-get update + sudo apt-get install -y libplist-utils + - name: Install sim-remote + shell: bash + run: | + case "$(uname -m)" in + x86_64) TARGET="x86_64-unknown-linux-gnu" ;; + aarch64 | arm64) TARGET="aarch64-unknown-linux-gnu" ;; + *) echo "Unsupported architecture: $(uname -m)"; exit 1 ;; + esac + mkdir -p "$HOME/.local/bin" + curl -fL --retry 3 -o "$HOME/.local/bin/sim-remote" \ + "https://github.com/software-mansion/sim-remote-releases/releases/download/softu/sim-remote-${TARGET}" + chmod +x "$HOME/.local/bin/sim-remote" + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + + # `softu` is a rolling tag and has been rebuilt without the shims before. + if ! "$HOME/.local/bin/sim-remote" install-shims --help >/dev/null 2>&1; then + echo "The sim-remote build at the 'softu' tag has no 'install-shims' command," >&2 + echo "so Maestro cannot drive a remote simulator. Rebuild the tag from a tree" >&2 + echo "that includes the Maestro shims (software-mansion/radon-cloud#143)." >&2 + exit 1 + fi + - name: Acquire remote simulator + shell: bash + # Credentials come from the calling job's env: + # SIM_ROUTER_URL, SIM_ROUTER_USERNAME, SIM_ROUTER_API_KEY. + run: | + # An unset SIM_ROUTER_URL secret arrives as an empty env var, which + # would override the router URL baked into the binary — drop it. + [ -n "${SIM_ROUTER_URL:-}" ] || unset SIM_ROUTER_URL + + sim-remote login --no-acquire + + # The router clamps a single acquire wait to 300s, so retry rather than + # asking for a longer timeout that is silently truncated. + for attempt in $(seq 1 8); do + if sim-remote acquire --timeout 300; then + exit 0 + fi + echo "Attempt $attempt: no fleet machine available yet, retrying..." + sleep 30 + done + + echo "Could not acquire a fleet machine" >&2 + exit 1 - name: Set up JDK 17 uses: actions/setup-java@v5 with: @@ -61,6 +107,10 @@ runs: id: run-tests shell: bash run: | + # Put the Maestro shims (xcrun, xcodebuild, plutil, ...) on PATH so + # stock Maestro drives the remote simulator through sim-remote. + eval "$(sim-remote install-shims)" + # Avoid exit from the job if one of the command returns an error. # Maestro can fail in case of flakyness, we have some retry logic. set +e @@ -74,6 +124,10 @@ runs: "${{ inputs.working-directory }}" \ "${{ inputs.device-model }}" \ "${{ inputs.device-os }}" + - name: Release remote simulator + if: ${{ always() }} + shell: bash + run: sim-remote logout || true - name: Store video record if: always() uses: ./.github/actions/upload-artifact diff --git a/.github/workflow-scripts/maestro-ios.js b/.github/workflow-scripts/maestro-ios.js index a9782ec6506f..2249081d3912 100644 --- a/.github/workflow-scripts/maestro-ios.js +++ b/.github/workflow-scripts/maestro-ios.js @@ -81,7 +81,24 @@ function installAppOnSimulator(appPath, udid) { childProcess.execSync(`xcrun simctl install "${udid}" "${appPath}"`); } +// A remote simulator's localhost is the remote host, so Metro needs a tunnel. +function exposeMetroToSimulator(udid) { + const simRemote = process.env.SIM_REMOTE_BIN; + if (!simRemote) { + return; + } + + console.log('Exposing local Metro port 8081 to the remote simulator'); + childProcess.execSync(`"${simRemote}" reverse start "${udid}" 8081`, { + stdio: 'inherit', + }); +} + function bringSimulatorInForeground() { + // Nothing to foreground on a remote simulator. + if (process.env.SIM_REMOTE_BIN) { + return; + } console.log('Bringing simulator in foreground'); childProcess.execSync('open -a simulator'); } @@ -266,6 +283,9 @@ async function main(args = process.argv.slice(2)) { launchSimulator(simulator); installAppOnSimulator(appPath, simulator.udid); bringSimulatorInForeground(); + if (isDebug) { + exposeMetroToSimulator(simulator.udid); + } await launchAppOnSimulator(appId, simulator.udid, isDebug); await executeFlows(appId, simulator.udid, maestroFlow, jsengine); console.log('Test finished'); diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index e0f69be743ae..730c8ff992e0 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -16,7 +16,11 @@ on: jobs: test: - runs-on: macos-26-large + runs-on: ubuntu-latest + env: + SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} + SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} + SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: status: ${{ steps.report-status.outputs.status }} strategy: diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index dbaaaa2b5666..9238552d1af1 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -15,8 +15,10 @@ on: value: ${{ jobs.report.outputs.status }} jobs: + # Building the app needs Xcode, so it stays on a macOS runner. The E2E run + # itself drives a remote simulator via sim-remote, so it runs on Linux. build: - runs-on: macos-26-large + runs-on: macos-26 strategy: fail-fast: false matrix: @@ -99,7 +101,11 @@ jobs: test: needs: build - runs-on: macos-26-large + runs-on: ubuntu-latest + env: + SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} + SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} + SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: status: ${{ steps.report-status.outputs.status }} strategy: From 76c4022556482272fe28f930f63797010468bb75 Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Thu, 3 Sep 2026 15:22:00 +0200 Subject: [PATCH 02/10] Compose the E2E action from argent-cloud-actions Replace the hand-rolled sim-remote download, login and retried acquire, install-shims preflight, plistutil install and logout with the install, acquire and maestro-shims actions from software-mansion-labs/argent-cloud-actions, which implement the same logic. The machine is now released by acquire's post step, so it is also freed when the job is cancelled. --- .github/actions/maestro-ios/action.yml | 71 +++++--------------------- 1 file changed, 14 insertions(+), 57 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index f20d79114549..470bb4e35ebd 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -33,57 +33,18 @@ runs: - name: Installing Maestro shell: bash run: export MAESTRO_VERSION=2.6.1; curl -Ls "https://get.maestro.mobile.dev" | bash - - name: Installing Maestro dependencies - shell: bash - # libplist-utils provides plistutil, which backs the sim-remote plutil - # shim (Maestro pipes `simctl listapps` output through `plutil`). - run: | - sudo apt-get update - sudo apt-get install -y libplist-utils - name: Install sim-remote - shell: bash - run: | - case "$(uname -m)" in - x86_64) TARGET="x86_64-unknown-linux-gnu" ;; - aarch64 | arm64) TARGET="aarch64-unknown-linux-gnu" ;; - *) echo "Unsupported architecture: $(uname -m)"; exit 1 ;; - esac - mkdir -p "$HOME/.local/bin" - curl -fL --retry 3 -o "$HOME/.local/bin/sim-remote" \ - "https://github.com/software-mansion/sim-remote-releases/releases/download/softu/sim-remote-${TARGET}" - chmod +x "$HOME/.local/bin/sim-remote" - echo "$HOME/.local/bin" >> "$GITHUB_PATH" - - # `softu` is a rolling tag and has been rebuilt without the shims before. - if ! "$HOME/.local/bin/sim-remote" install-shims --help >/dev/null 2>&1; then - echo "The sim-remote build at the 'softu' tag has no 'install-shims' command," >&2 - echo "so Maestro cannot drive a remote simulator. Rebuild the tag from a tree" >&2 - echo "that includes the Maestro shims (software-mansion/radon-cloud#143)." >&2 - exit 1 - fi + uses: software-mansion-labs/argent-cloud-actions/install@v1 + with: + version: softu - name: Acquire remote simulator - shell: bash - # Credentials come from the calling job's env: - # SIM_ROUTER_URL, SIM_ROUTER_USERNAME, SIM_ROUTER_API_KEY. - run: | - # An unset SIM_ROUTER_URL secret arrives as an empty env var, which - # would override the router URL baked into the binary — drop it. - [ -n "${SIM_ROUTER_URL:-}" ] || unset SIM_ROUTER_URL - - sim-remote login --no-acquire - - # The router clamps a single acquire wait to 300s, so retry rather than - # asking for a longer timeout that is silently truncated. - for attempt in $(seq 1 8); do - if sim-remote acquire --timeout 300; then - exit 0 - fi - echo "Attempt $attempt: no fleet machine available yet, retrying..." - sleep 30 - done - - echo "Could not acquire a fleet machine" >&2 - exit 1 + # Credentials come from the calling job's env. The machine is released + # by the action's post step, even if the job fails or is cancelled. + uses: software-mansion-labs/argent-cloud-actions/acquire@v1 + with: + username: ${{ env.SIM_ROUTER_USERNAME }} + api-key: ${{ env.SIM_ROUTER_API_KEY }} + router-url: ${{ env.SIM_ROUTER_URL }} - name: Set up JDK 17 uses: actions/setup-java@v5 with: @@ -103,14 +64,14 @@ runs: cd ${{ inputs.working-directory }} yarn start & sleep 5 # to give metro time to load + - name: Install Maestro shims + # Puts xcrun, xcodebuild, plutil, ... stand-ins on PATH so stock Maestro + # drives the remote simulator, and exports SIM_REMOTE_BIN for the script. + uses: software-mansion-labs/argent-cloud-actions/maestro-shims@v1 - name: Run tests id: run-tests shell: bash run: | - # Put the Maestro shims (xcrun, xcodebuild, plutil, ...) on PATH so - # stock Maestro drives the remote simulator through sim-remote. - eval "$(sim-remote install-shims)" - # Avoid exit from the job if one of the command returns an error. # Maestro can fail in case of flakyness, we have some retry logic. set +e @@ -124,10 +85,6 @@ runs: "${{ inputs.working-directory }}" \ "${{ inputs.device-model }}" \ "${{ inputs.device-os }}" - - name: Release remote simulator - if: ${{ always() }} - shell: bash - run: sim-remote logout || true - name: Store video record if: always() uses: ./.github/actions/upload-artifact From 6748957c98ed42b253ab44a29e51c82a175dff57 Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Thu, 3 Sep 2026 17:18:29 +0200 Subject: [PATCH 03/10] Do not declare an empty SIM_ROUTER_URL at job level Neither reusable E2E workflow has a router-url secret configured, so SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} evaluated to an empty *string*, not an unset variable. The acquire action's process.env merge does not clear an already-empty inherited env var even when its own router-url input is left empty, so sim-remote's HTTP client builder failed trying to parse "" as a URL ('error: builder error') instead of falling back to the router baked into the binary. Drop the job-level env entirely, and the now-pointless router-url passthrough in the acquire step. --- .github/actions/maestro-ios/action.yml | 1 - .github/workflows/e2e-ios-rntester.yml | 6 +++++- .github/workflows/e2e-ios-templateapp.yml | 6 +++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index 470bb4e35ebd..30590cab81e6 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -44,7 +44,6 @@ runs: with: username: ${{ env.SIM_ROUTER_USERNAME }} api-key: ${{ env.SIM_ROUTER_API_KEY }} - router-url: ${{ env.SIM_ROUTER_URL }} - name: Set up JDK 17 uses: actions/setup-java@v5 with: diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index 730c8ff992e0..00df20f8ecc7 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -18,7 +18,11 @@ jobs: test: runs-on: ubuntu-latest env: - SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} + # SIM_ROUTER_URL is deliberately absent: an unset secret arrives as an + # empty *string*, and the acquire action's process.env merge does not + # clear an already-empty inherited var, which makes sim-remote's HTTP + # client builder fail on "" rather than falling back to its baked-in + # default. Only set this if the router URL secret is actually populated. SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index 9238552d1af1..7a128d829c7e 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -103,7 +103,11 @@ jobs: needs: build runs-on: ubuntu-latest env: - SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} + # SIM_ROUTER_URL is deliberately absent: an unset secret arrives as an + # empty *string*, and the acquire action's process.env merge does not + # clear an already-empty inherited var, which makes sim-remote's HTTP + # client builder fail on "" rather than falling back to its baked-in + # default. Only set this if the router URL secret is actually populated. SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: From 21bab5ae16f5022e8f82df1e2a801580f4a8ef0d Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Thu, 3 Sep 2026 18:47:47 +0200 Subject: [PATCH 04/10] Pin argent-cloud-actions to a commit SHA instead of @v1 The v1 tag was retagged upstream to fix an empty-SIM_ROUTER_URL bug (d2e23bc, 'Treat an empty SIM_ROUTER_URL as unset'), but GitHub kept resolving react-native's uses: references to a cached pre-fix copy of that tag for over an hour after the move, failing to parse a 'secrets.SIM_ROUTER_URL' expression that no longer exists in the live content. A commit SHA is an immutable ref this repo has never resolved before, so there is nothing stale to serve. --- .github/actions/maestro-ios/action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index 30590cab81e6..97a690ec667b 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -34,13 +34,13 @@ runs: shell: bash run: export MAESTRO_VERSION=2.6.1; curl -Ls "https://get.maestro.mobile.dev" | bash - name: Install sim-remote - uses: software-mansion-labs/argent-cloud-actions/install@v1 + uses: software-mansion-labs/argent-cloud-actions/install@d2e23bc7607bb328a6df2dec916585fccca5d55f with: version: softu - name: Acquire remote simulator # Credentials come from the calling job's env. The machine is released # by the action's post step, even if the job fails or is cancelled. - uses: software-mansion-labs/argent-cloud-actions/acquire@v1 + uses: software-mansion-labs/argent-cloud-actions/acquire@d2e23bc7607bb328a6df2dec916585fccca5d55f with: username: ${{ env.SIM_ROUTER_USERNAME }} api-key: ${{ env.SIM_ROUTER_API_KEY }} @@ -66,7 +66,7 @@ runs: - name: Install Maestro shims # Puts xcrun, xcodebuild, plutil, ... stand-ins on PATH so stock Maestro # drives the remote simulator, and exports SIM_REMOTE_BIN for the script. - uses: software-mansion-labs/argent-cloud-actions/maestro-shims@v1 + uses: software-mansion-labs/argent-cloud-actions/maestro-shims@d2e23bc7607bb328a6df2dec916585fccca5d55f - name: Run tests id: run-tests shell: bash From 01bb053abb45f33dc6c8cf57eea775df5b62dc82 Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Fri, 4 Sep 2026 12:37:51 +0200 Subject: [PATCH 05/10] Revert the SIM_ROUTER_URL and SHA-pin workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both landed on argent-cloud-actions' side: childEnv() now deletes an inherited empty SIM_ROUTER_URL rather than merely not overriding it (fixing the acquire client's builder error), and the v1 tag's manifest loads again (the fix's own description text no longer embeds a live ${{ }} expression, which the previous version did and which the runner evaluates even inside description fields). Restore the router-url passthrough, the job-level SIM_ROUTER_URL env, and the @v1 tag reference — the documented, idiomatic way to consume these actions, with nothing routed around. --- .github/actions/maestro-ios/action.yml | 7 ++++--- .github/workflows/e2e-ios-rntester.yml | 6 +----- .github/workflows/e2e-ios-templateapp.yml | 6 +----- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index 97a690ec667b..470bb4e35ebd 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -34,16 +34,17 @@ runs: shell: bash run: export MAESTRO_VERSION=2.6.1; curl -Ls "https://get.maestro.mobile.dev" | bash - name: Install sim-remote - uses: software-mansion-labs/argent-cloud-actions/install@d2e23bc7607bb328a6df2dec916585fccca5d55f + uses: software-mansion-labs/argent-cloud-actions/install@v1 with: version: softu - name: Acquire remote simulator # Credentials come from the calling job's env. The machine is released # by the action's post step, even if the job fails or is cancelled. - uses: software-mansion-labs/argent-cloud-actions/acquire@d2e23bc7607bb328a6df2dec916585fccca5d55f + uses: software-mansion-labs/argent-cloud-actions/acquire@v1 with: username: ${{ env.SIM_ROUTER_USERNAME }} api-key: ${{ env.SIM_ROUTER_API_KEY }} + router-url: ${{ env.SIM_ROUTER_URL }} - name: Set up JDK 17 uses: actions/setup-java@v5 with: @@ -66,7 +67,7 @@ runs: - name: Install Maestro shims # Puts xcrun, xcodebuild, plutil, ... stand-ins on PATH so stock Maestro # drives the remote simulator, and exports SIM_REMOTE_BIN for the script. - uses: software-mansion-labs/argent-cloud-actions/maestro-shims@d2e23bc7607bb328a6df2dec916585fccca5d55f + uses: software-mansion-labs/argent-cloud-actions/maestro-shims@v1 - name: Run tests id: run-tests shell: bash diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index 00df20f8ecc7..730c8ff992e0 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -18,11 +18,7 @@ jobs: test: runs-on: ubuntu-latest env: - # SIM_ROUTER_URL is deliberately absent: an unset secret arrives as an - # empty *string*, and the acquire action's process.env merge does not - # clear an already-empty inherited var, which makes sim-remote's HTTP - # client builder fail on "" rather than falling back to its baked-in - # default. Only set this if the router URL secret is actually populated. + SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index 7a128d829c7e..9238552d1af1 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -103,11 +103,7 @@ jobs: needs: build runs-on: ubuntu-latest env: - # SIM_ROUTER_URL is deliberately absent: an unset secret arrives as an - # empty *string*, and the acquire action's process.env merge does not - # clear an already-empty inherited var, which makes sim-remote's HTTP - # client builder fail on "" rather than falling back to its baked-in - # default. Only set this if the router URL secret is actually populated. + SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: From 234b9b470b55fd2a1f2dd27dd8061b389a44a654 Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Fri, 11 Sep 2026 11:36:01 +0200 Subject: [PATCH 06/10] Adapt to argent-cloud-actions without a username or release pin argent-cloud-actions@v1 (2159fde) dropped acquire's username input, which sim-remote login no longer takes, and install's version input: it now always installs the latest published sim-remote release. Stop passing both, and stop exporting SIM_ROUTER_USERNAME to the test jobs. --- .github/actions/maestro-ios/action.yml | 3 --- .github/workflows/e2e-ios-rntester.yml | 1 - .github/workflows/e2e-ios-templateapp.yml | 1 - 3 files changed, 5 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index 470bb4e35ebd..2f15769fa034 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -35,14 +35,11 @@ runs: run: export MAESTRO_VERSION=2.6.1; curl -Ls "https://get.maestro.mobile.dev" | bash - name: Install sim-remote uses: software-mansion-labs/argent-cloud-actions/install@v1 - with: - version: softu - name: Acquire remote simulator # Credentials come from the calling job's env. The machine is released # by the action's post step, even if the job fails or is cancelled. uses: software-mansion-labs/argent-cloud-actions/acquire@v1 with: - username: ${{ env.SIM_ROUTER_USERNAME }} api-key: ${{ env.SIM_ROUTER_API_KEY }} router-url: ${{ env.SIM_ROUTER_URL }} - name: Set up JDK 17 diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index 730c8ff992e0..c850df43c111 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -19,7 +19,6 @@ jobs: runs-on: ubuntu-latest env: SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} - SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: status: ${{ steps.report-status.outputs.status }} diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index 9238552d1af1..0f4d43e843d8 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -104,7 +104,6 @@ jobs: runs-on: ubuntu-latest env: SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} - SIM_ROUTER_USERNAME: ${{ vars.SIM_ROUTER_USERNAME }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: status: ${{ steps.report-status.outputs.status }} From 0cef2650799cf41738e9449a8442e878952ef33b Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Fri, 11 Sep 2026 14:05:47 +0200 Subject: [PATCH 07/10] Allow more time for ScrollView navigation on remote simulators --- .../rn-tester/.maestro/scrollview-minindex-maintainvisible.yml | 1 + .../rn-tester/.maestro/scrollview-threshold-maintainvisible.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/rn-tester/.maestro/scrollview-minindex-maintainvisible.yml b/packages/rn-tester/.maestro/scrollview-minindex-maintainvisible.yml index 0925eda988fe..23a5b3b5fef1 100644 --- a/packages/rn-tester/.maestro/scrollview-minindex-maintainvisible.yml +++ b/packages/rn-tester/.maestro/scrollview-minindex-maintainvisible.yml @@ -14,6 +14,7 @@ appId: ${APP_ID} id: 'ScrollViewMaintainVisibleContentPositionExample' direction: DOWN speed: 80 + timeout: 90000 - tapOn: id: 'ScrollViewMaintainVisibleContentPositionExample' - waitForAnimationToEnd: diff --git a/packages/rn-tester/.maestro/scrollview-threshold-maintainvisible.yml b/packages/rn-tester/.maestro/scrollview-threshold-maintainvisible.yml index c865c3cb26e9..972a14d388d4 100644 --- a/packages/rn-tester/.maestro/scrollview-threshold-maintainvisible.yml +++ b/packages/rn-tester/.maestro/scrollview-threshold-maintainvisible.yml @@ -14,6 +14,7 @@ appId: ${APP_ID} id: 'ScrollViewMaintainVisibleContentPositionExample' direction: DOWN speed: 80 + timeout: 90000 - tapOn: id: 'ScrollViewMaintainVisibleContentPositionExample' - waitForAnimationToEnd: From 7783483701f7468105ee428099bd97f4f44a6422 Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Fri, 11 Sep 2026 14:15:09 +0200 Subject: [PATCH 08/10] Keep the upstream macOS runner for template app builds --- .github/workflows/e2e-ios-templateapp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index 0f4d43e843d8..679ad18d1caf 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -18,7 +18,7 @@ jobs: # Building the app needs Xcode, so it stays on a macOS runner. The E2E run # itself drives a remote simulator via sim-remote, so it runs on Linux. build: - runs-on: macos-26 + runs-on: macos-26-large strategy: fail-fast: false matrix: From bfc4291bbccd1c279c92a1fc8e44c60e63089b71 Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Fri, 11 Sep 2026 14:21:11 +0200 Subject: [PATCH 09/10] Stop passing SIM_ROUTER_URL to argent-cloud-actions argent-cloud-actions@v1 (fa197d0) dropped acquire's router-url input: the router is the one built into sim-remote. Remove the passthrough and the job-level SIM_ROUTER_URL env that fed it. --- .github/actions/maestro-ios/action.yml | 1 - .github/workflows/e2e-ios-rntester.yml | 1 - .github/workflows/e2e-ios-templateapp.yml | 1 - 3 files changed, 3 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index 2f15769fa034..299443efbdfb 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -41,7 +41,6 @@ runs: uses: software-mansion-labs/argent-cloud-actions/acquire@v1 with: api-key: ${{ env.SIM_ROUTER_API_KEY }} - router-url: ${{ env.SIM_ROUTER_URL }} - name: Set up JDK 17 uses: actions/setup-java@v5 with: diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index c850df43c111..2936c97c4820 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -18,7 +18,6 @@ jobs: test: runs-on: ubuntu-latest env: - SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: status: ${{ steps.report-status.outputs.status }} diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index 679ad18d1caf..10a13395e3e0 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -103,7 +103,6 @@ jobs: needs: build runs-on: ubuntu-latest env: - SIM_ROUTER_URL: ${{ secrets.SIM_ROUTER_URL }} SIM_ROUTER_API_KEY: ${{ secrets.SIM_ROUTER_API_KEY }} outputs: status: ${{ steps.report-status.outputs.status }} From 0201c40b2549b094c6e1e24f07746a809c3ba9c8 Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt Date: Fri, 11 Sep 2026 14:30:58 +0200 Subject: [PATCH 10/10] Pin the RNTester E2E simulator to iOS 26.5 The fleet's iPhone 17 Pro simulators run iOS 26.5; upstream's iOS-26-2 pin, meant for local macOS runners, would find no matching simulator and fail before any flow runs. --- .github/workflows/e2e-ios-rntester.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index 2936c97c4820..8c7165cb2350 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -47,7 +47,7 @@ jobs: maestro-flow: ./packages/rn-tester/.maestro/ flavor: ${{ matrix.flavor }} device-model: iPhone-17-Pro - device-os: iOS-26-2 + device-os: iOS-26-5 - name: Report status id: report-status if: ${{ always() && steps.run-tests.outcome == 'failure' }}