From cf3329d356eea4bfb3629be559d1aa9c56da576e Mon Sep 17 00:00:00 2001 From: Ricardo Colombo Oliveira Date: Sun, 25 Oct 2026 16:07:04 +0100 Subject: [PATCH 1/2] ci: run the iOS integration tests in their own job The iOS job ran the device tests and then the integration tests on one Mac, about 42 minutes in all. The two build and run different apps and share only the simulator, so the integration tests now run in a second job at the same time. ios.Tests.ps1 skips every case unless a simulator is already booted, and xharness only boots one in the ios-tests job, so the new job boots its own, with a 10-minute timeout. The boot takes about 2 minutes. The job uploads no results, because ios.Tests.ps1 writes nothing to the integration-test/mobile-app/test_output folder the old job uploaded. On its first run, the iOS workflow took 18 minutes, against 38.7 for the single job the same night, and all 8 integration cases passed. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/device-tests-ios.yml | 62 ++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/.github/workflows/device-tests-ios.yml b/.github/workflows/device-tests-ios.yml index f1ac40fa39..00c8820065 100644 --- a/.github/workflows/device-tests-ios.yml +++ b/.github/workflows/device-tests-ios.yml @@ -75,7 +75,7 @@ jobs: - name: Setup Environment uses: ./.github/actions/environment with: - projects: test/Sentry.Maui.Device.TestApp/Sentry.Maui.Device.TestApp.csproj integration-test/net9-maui/Sentry.Maui.Device.IntegrationTestApp.csproj + projects: test/Sentry.Maui.Device.TestApp/Sentry.Maui.Device.TestApp.csproj # See build.yml - name: Get Cocoa SDK cache key @@ -110,6 +110,54 @@ jobs: timeout-minutes: 40 run: pwsh scripts/device-test.ps1 ios -Run -Verbose + - name: Upload results + if: success() || failure() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: device-test-ios-results + path: test_output + + # The integration tests build and run their own app, so they run next to the device tests instead of after them + ios-integration-tests: + runs-on: xcode-27 + env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_NOLOGO: 1 + NO_ANDROID: true + NO_MACCATALYST: true + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + submodules: recursive + + - name: Setup Environment + uses: ./.github/actions/environment + with: + projects: integration-test/net9-maui/Sentry.Maui.Device.IntegrationTestApp.csproj + + - name: Get Cocoa SDK cache key + id: cocoa-key + uses: ./.github/actions/cocoa-cache-key + + - name: Restore Cocoa SDK + id: cache-cocoa + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: modules/sentry-cocoa/Carthage + key: ${{ steps.cocoa-key.outputs.key }} + + # ios.Tests.ps1 skips every case unless a simulator is already booted. In the ios-tests job, xharness boots it. + - name: Boot the iOS Simulator + timeout-minutes: 10 + shell: pwsh + run: | + . ./scripts/device-test-utils.ps1 + $udid = Get-IosSimulatorUdid -Verbose + if (-not $udid) { throw 'No iOS simulator found' } + xcrun simctl bootstatus $udid -b + if ($LASTEXITCODE -ne 0) { throw "Couldn't boot simulator $udid" } + - name: Run Integration Tests id: first-integration-test-run continue-on-error: true @@ -125,11 +173,9 @@ jobs: with: path: integration-test/ios.Tests.ps1 - - name: Upload results - if: success() || failure() - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + - name: Save Cocoa SDK + if: ${{ !cancelled() && steps.cache-cocoa.outputs.cache-hit != 'true' && hashFiles('modules/sentry-cocoa/Carthage/.built-from-sha') != '' }} + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: - name: device-test-ios-results - path: | - test_output - integration-test/mobile-app/test_output + path: modules/sentry-cocoa/Carthage + key: ${{ steps.cache-cocoa.outputs.cache-primary-key }} From 050b2568b43cafaf37b685cbca40f0791831f2af Mon Sep 17 00:00:00 2001 From: Ricardo Colombo Oliveira Date: Sun, 25 Oct 2026 16:07:32 +0100 Subject: [PATCH 2/2] ci: run the Android integration tests in their own job Each Android emulator job ran the device tests, then Setup Environment, then the integration tests, about 22 minutes after waiting 7.5 for the device test app builds. The integration tests build their own app from source and share only the emulator, so they now run in a second job that starts with the workflow, on the same runners. The new job drops "Select Java 21". #4559 added it as "Select Java 17", when Setup Environment ended on Java 11, and since #5060 Setup Environment installs only Java 21. The new job uploads integration-test/mobile-app/test_output, where android.Tests.ps1 points xharness, without a warning when it's empty. It was empty on every run so far. On its first run, the Android workflow took 19.8 minutes instead of 30.1. The device test jobs took 3.6 to 3.8 minutes and the integration jobs 12.0 to 19.7. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/device-tests-android.yml | 46 ++++++++++++++++------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/.github/workflows/device-tests-android.yml b/.github/workflows/device-tests-android.yml index 3303724bea..e657a88ead 100644 --- a/.github/workflows/device-tests-android.yml +++ b/.github/workflows/device-tests-android.yml @@ -101,14 +101,14 @@ jobs: # Requires a "larger runner", for nested virtualization support runs-on: ubuntu-latest-4-cores - strategy: + strategy: &android-emulator-matrix fail-fast: false matrix: tfm: [net9.0, net10.0] # Must be 34+ for new apps and app updates as of August 31, 2024. # See https://apilevels.com/ api-level: [34, 36] - env: + env: &android-emulator-env DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_NOLOGO: 1 # We don't need the Google APIs, but the default images are not available for 32+ @@ -165,17 +165,40 @@ jobs: uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2.38.0 with: *android-emulator-test + - name: Upload results + if: success() || failure() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: device-test-android-${{ matrix.api-level }}-${{ matrix.tfm }}-results + path: test_output + + # The integration tests build and run their own app, so they run next to the device tests instead of after them + android-integration-tests: + name: Run Android API-${{ matrix.api-level }} Integration Test (${{ matrix.tfm }}) + + # Requires a "larger runner", for nested virtualization support + runs-on: ubuntu-latest-4-cores + + strategy: *android-emulator-matrix + env: *android-emulator-env + steps: + # See https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/ + - name: Enable KVM group perms + 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: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + submodules: recursive + - name: Setup Environment uses: ./.github/actions/environment with: projects: integration-test/net9-maui/Sentry.Maui.Device.IntegrationTestApp.csproj - - name: Select Java 21 - uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0 - with: - distribution: temurin - java-version: '21' - - name: Checkout github-workflows uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -209,7 +232,6 @@ jobs: if: success() || failure() uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: - name: device-test-android-${{ matrix.api-level }}-${{ matrix.tfm }}-results - path: | - test_output - integration-test/mobile-app/test_output + name: device-test-android-integration-${{ matrix.api-level }}-${{ matrix.tfm }}-results + path: integration-test/mobile-app/test_output + if-no-files-found: ignore