chore: Add try? linter for tests and fix current cases
#18989
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - v8.x | |
| - release/** | |
| pull_request: | |
| types: [opened, synchronize, reopened, labeled] | |
| # Concurrency configuration: | |
| # - We use workflow-specific concurrency groups to allow independent test runs across different workflows | |
| # while preventing multiple runs of the same test suite on the same branch/commit. | |
| # - For pull requests, we cancel in-progress runs when new commits are pushed to save CI resources | |
| # and provide faster feedback on the latest changes. | |
| # - For main branch pushes and scheduled runs, we never cancel in-progress runs to ensure the complete | |
| # test suite always finishes, maintaining the integrity of our main branch quality gates. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| ready-to-merge-gate: | |
| name: Ready-to-merge gate | |
| uses: ./.github/workflows/ready-to-merge-workflow.yml | |
| # This job detects if the PR contains changes that require running unit tests. | |
| # If yes, the job will output a flag that will be used by the next job to run the unit tests. | |
| # If no, the job will output a flag that will be used by the next job to skip running the unit tests. | |
| # At the end of this workflow, we run a check that validates that either all unit tests passed or were | |
| # called unit-tests-required-check. | |
| files-changed: | |
| name: Detect File Changes | |
| runs-on: ubuntu-latest | |
| needs: ready-to-merge-gate | |
| # Map a step output to a job output | |
| outputs: | |
| run_unit_tests_for_prs: ${{ steps.changes.outputs.run_unit_tests_for_prs }} | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Get changed files | |
| id: changes | |
| uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 | |
| with: | |
| token: ${{ github.token }} | |
| filters: .github/file-filters.yml | |
| build-test-server: | |
| name: Build test server | |
| if: github.event_name != 'pull_request' || needs.files-changed.outputs.run_unit_tests_for_prs == 'true' | |
| needs: files-changed | |
| runs-on: macos-15 | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Cache for Test Server | |
| id: cache_test_server | |
| uses: actions/cache@v5 | |
| with: | |
| path: ./test-server/.build | |
| key: test-server-${{ hashFiles('./test-server') }}-universal | |
| restore-keys: | | |
| test-server-${{ hashFiles('./test-server') }}-universal | |
| test-server- | |
| - name: Build Test Server for Intel CPU | |
| if: steps.cache_test_server.outputs.cache-hit != 'true' | |
| working-directory: test-server | |
| run: >- | |
| swift build -c release --triple x86_64-apple-macosx 2>&1 | tee test-server-build-intel.log | |
| - name: Build Test Server for M1 CPU | |
| if: steps.cache_test_server.outputs.cache-hit != 'true' | |
| working-directory: test-server | |
| run: >- | |
| swift build -c release --arch arm64 2>&1 | tee test-server-build-arm64.log | |
| - name: Combine Test Server | |
| working-directory: test-server | |
| run: >- | |
| lipo -create -output test-server-exec $(swift build --show-bin-path -c release --triple arm64-apple-macosx)/Run $(swift build --show-bin-path -c release --triple x86_64-apple-macosx)/Run | |
| - name: Archiving DerivedData | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: test-server | |
| path: | | |
| ./test-server/test-server-exec | |
| - name: Archiving Raw Test Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: test-server-build-log | |
| path: | | |
| test-server-build-intel.log | |
| test-server-build-arm64.log | |
| - name: Run CI Diagnostics | |
| if: failure() | |
| run: ./scripts/ci-diagnostics.sh | |
| distribution-tests: | |
| name: Distribution Tests | |
| runs-on: macos-15 | |
| # Don't run this on release branches, cause the SPM Package.swift points to the unreleased versions. | |
| # Also, skip when PR changes don't require running tests to save CI time. | |
| if: startsWith(github.ref, 'refs/heads/release/') == false && (github.event_name != 'pull_request' || needs.files-changed.outputs.run_unit_tests_for_prs == 'true') | |
| needs: files-changed | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - name: Prepare Package.swift | |
| shell: bash | |
| run: | | |
| ./scripts/prepare-package.sh \ | |
| --package-file Package.swift \ | |
| --is-pr "${{ github.event_name == 'pull_request' }}" \ | |
| --remove-duplicate true \ | |
| --change-path false \ | |
| --remove-binary-targets true | |
| - name: Ensure required runtime is loaded | |
| # Ideally we will not need this, but CI sometimes is failing to load some runtimes, this will ensure they are loaded | |
| timeout-minutes: 5 # 5 minutes timeout | |
| env: | |
| OS_VERSION: "18.5" | |
| PLATFORM: "iOS" | |
| run: ./scripts/ci-ensure-runtime-loaded.sh --os-version "$OS_VERSION" --platform "$PLATFORM" | |
| - run: rm -r Sentry.xcodeproj && rm -r Sentry.xcworkspace | |
| - run: set -o pipefail && NSUnbufferedIO=YES SKIP_BINARIES=1 xcodebuild test -scheme Sentry-Package -sdk iphonesimulator -destination 'platform=iOS Simulator,OS=18.5,name=iPhone 16 Pro' | tee raw-test-output-distribution.log | xcbeautify --preserve-unbeautified | |
| shell: sh | |
| - name: Upload Distribution Test Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: raw-test-output-distribution | |
| path: | | |
| raw-test-output-distribution.log | |
| # This matrix runs only the unit tests requiring the test server. | |
| # We do this to speed up the other unit test jobs and to avoid running the | |
| # test server with potential side effects in GH actions for all unit tests. | |
| # We don't run this matrix for all different OS versions, because the chances | |
| # of a bug solely on a specific OS version is minimal. | |
| unit-tests-with-test-server: | |
| name: Unit with Test Server ${{matrix.name}} | |
| runs-on: ${{matrix.runs-on}} | |
| timeout-minutes: 20 | |
| needs: build-test-server | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Running the tests with simulators is incredibly flaky. Our assumption is that simulators might have difficulties | |
| # with communicating with the test server in CI. | |
| # We are going to add these back in https://github.com/getsentry/sentry-cocoa/issues/6361 | |
| - name: macOS 15 | |
| runs-on: | |
| ["ghcr.io/cirruslabs/macos-runner:sequoia", "runner_group_id:10"] | |
| platform: "macOS" | |
| xcode: "16.4" | |
| test-destination-os: "15.0" | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| - uses: actions/download-artifact@v7 | |
| with: | |
| name: test-server | |
| - name: Start Test Server | |
| run: ./scripts/start-test-server.sh | |
| - run: ./scripts/ci-select-xcode.sh ${{matrix.xcode}} | |
| # Note: We don't install Slather or gather code coverage for this job because it only runs | |
| # the SentryTestServerTests target, which contains minimal tests that don't significantly | |
| # contribute to overall code coverage metrics. The main unit-tests job handles comprehensive | |
| # code coverage reporting. | |
| # We split building and running tests in two steps so we know how long running the tests takes. | |
| - name: Build tests | |
| id: build_tests | |
| run: | | |
| ./scripts/sentry-xcodebuild.sh \ | |
| --platform ${{matrix.platform}} \ | |
| --os ${{matrix.test-destination-os}} \ | |
| --ref ${{ github.ref_name }} \ | |
| --command build-for-testing \ | |
| --configuration TestCI \ | |
| --scheme Sentry \ | |
| --test-plan Sentry_TestServer | |
| - name: Run tests | |
| run: | | |
| ./scripts/sentry-xcodebuild.sh \ | |
| --platform ${{matrix.platform}} \ | |
| --os ${{matrix.test-destination-os}} \ | |
| --ref ${{ github.ref_name }} \ | |
| --command test-without-building \ | |
| --configuration TestCI \ | |
| --scheme Sentry \ | |
| --test-plan Sentry_TestServer | |
| - name: Archiving DerivedData Logs | |
| uses: actions/upload-artifact@v6 | |
| if: steps.build_tests.outcome == 'failure' | |
| with: | |
| name: derived-data-test-server-${{matrix.platform}}-xcode-${{matrix.xcode}} | |
| path: | | |
| /Users/runner/Library/Developer/Xcode/DerivedData/**/Logs/** | |
| - name: Archiving Raw Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: raw-output-test-server-${{matrix.platform}}-xcode-${{matrix.xcode}} | |
| path: | | |
| raw-build-output.log | |
| raw-build-for-testing-output.log | |
| raw-test-output.log | |
| - name: Archiving Crash Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: crash-logs-test-server-${{matrix.platform}}-xcode-${{matrix.xcode}} | |
| path: | | |
| ~/Library/Logs/DiagnosticReports/** | |
| - name: Run CI Diagnostics | |
| if: ${{ failure() || cancelled() }} | |
| run: ./scripts/ci-diagnostics.sh | |
| - name: Store screenshot | |
| uses: ./.github/actions/capture-screenshot | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| suffix: ${{ matrix.platform }}-xcode-${{ matrix.xcode }} | |
| unit-tests: | |
| name: Unit ${{matrix.name}} | |
| needs: files-changed | |
| uses: ./.github/workflows/unit-test-common.yml | |
| secrets: inherit | |
| with: | |
| name: ${{matrix.name}} | |
| runs-on: ${{ matrix.runs-on }} | |
| should_skip: ${{github.event_name == 'pull_request' && needs.files-changed.outputs.run_unit_tests_for_prs != 'true'}} | |
| xcode: ${{matrix.xcode}} | |
| platform: ${{matrix.platform}} | |
| test-destination-os: ${{matrix.test-destination-os || 'latest'}} | |
| timeout: ${{matrix.timeout || 20}} | |
| device: ${{matrix.device || ''}} | |
| scheme: ${{matrix.scheme || 'Sentry'}} | |
| run_on_cirrus_labs: true # We always run tests on Cirrus Labs | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Can't run tests on watchOS because XCTest is not available | |
| include: | |
| # We are running tests on iOS 17 and later, as there were OS-internal changes introduced in succeeding versions. | |
| # iOS 17 | |
| - name: iOS 17 Sentry | |
| runs-on: sequoia | |
| xcode: "16.4" | |
| test-destination-os: "17.5" | |
| platform: "iOS" | |
| device: "iPhone 15 Pro" | |
| scheme: "Sentry" | |
| # iOS 18 | |
| - name: iOS 18 Sentry | |
| runs-on: sequoia | |
| xcode: "16.4" | |
| test-destination-os: "18.5" | |
| platform: "iOS" | |
| device: "iPhone 16 Pro" | |
| scheme: "Sentry" | |
| # iOS 26 | |
| - name: iOS 26 Sentry | |
| runs-on: tahoe | |
| xcode: "26.1.1" | |
| test-destination-os: "26.1" | |
| platform: "iOS" | |
| device: "iPhone 17 Pro" | |
| scheme: "Sentry" | |
| # We don't run the unit tests on macOS 13 cause we run them on all on GH actions available iOS versions. | |
| # The chance of missing a bug solely on tvOS 16 that doesn't occur on iOS, macOS 12 or macOS 14 is minimal. | |
| # We are running tests on macOS 14 and later, as there were OS-internal changes introduced in succeeding versions. | |
| # macOS 14 | |
| - name: macOS 14 Sentry | |
| runs-on: sonoma | |
| xcode: "16.1" | |
| test-destination-os: "latest" | |
| platform: "macOS" | |
| scheme: "Sentry" | |
| # macOS 15 | |
| - name: macOS 15 Sentry | |
| runs-on: sequoia | |
| xcode: "16.4" | |
| test-destination-os: "latest" | |
| platform: "macOS" | |
| scheme: "Sentry" | |
| # macOS 26 | |
| - name: macOS 26 Sentry | |
| runs-on: tahoe | |
| xcode: "26.1.1" | |
| test-destination-os: "26.1" | |
| platform: "macOS" | |
| scheme: "Sentry" | |
| # Catalyst. We test the latest version, as the risk something breaking on Catalyst and not | |
| # on an older iOS or macOS version is low. | |
| # In addition we are running tests on macOS 14, as there were OS-internal changes introduced in succeeding versions. | |
| - name: Catalyst 14 Sentry | |
| runs-on: sonoma | |
| xcode: "16.1" | |
| test-destination-os: "latest" | |
| platform: "Catalyst" | |
| scheme: "Sentry" | |
| - name: Catalyst 15 Sentry | |
| runs-on: sequoia | |
| xcode: "16.4" | |
| test-destination-os: "latest" | |
| platform: "Catalyst" | |
| scheme: "Sentry" | |
| ## We don't run unit tests on macCatalyst 26 yet because of https://github.com/getsentry/sentry-cocoa/issues/6165. | |
| # We don't run the unit tests on tvOS 16 cause we run them on all on GH actions available iOS versions. | |
| # The chance of missing a bug solely on tvOS 16 that doesn't occur on iOS, tvOS 15 or tvOS 16 is minimal. | |
| # We are running tests on tvOS 17 and latest, as there were OS-internal changes introduced in succeeding versions. | |
| # tvOS 17 | |
| - name: tvOS 17 Sentry | |
| runs-on: sequoia | |
| xcode: "16.4" | |
| test-destination-os: "17.5" | |
| platform: "tvOS" | |
| scheme: "Sentry" | |
| # iOS 17 - SwiftUI | |
| - name: iOS 17 SentrySwiftUI | |
| runs-on: sequoia | |
| xcode: "16.4" | |
| test-destination-os: "17.5" | |
| platform: "iOS" | |
| device: "iPhone 15 Pro" | |
| scheme: "SentrySwiftUI" | |
| # tvOS 18 | |
| - name: tvOS 18 Sentry | |
| runs-on: sequoia | |
| xcode: "16.4" | |
| test-destination-os: "18.5" | |
| platform: "tvOS" | |
| scheme: "Sentry" | |
| # tvOS 26 | |
| - name: tvOS 26 Sentry | |
| runs-on: tahoe | |
| xcode: "26.1.1" | |
| test-destination-os: "26.1" | |
| platform: "tvOS" | |
| device: "Apple TV" | |
| scheme: "Sentry" | |
| # visionOS 26 | |
| - name: visionOS 26 Sentry | |
| runs-on: tahoe | |
| xcode: "26.1.1" | |
| test-destination-os: "26.1" | |
| platform: "visionOS" | |
| scheme: "Sentry" | |
| device: "Apple Vision Pro" | |
| timeout: 30 | |
| # This will be replaced once #6945 is merged. | |
| swiftlog-integration-unit-tests: | |
| name: SentrySwiftLog Unit Tests | |
| if: startsWith(github.ref, 'refs/heads/release/') == false && (github.event_name != 'pull_request' || needs.files-changed.outputs.run_unit_tests_for_prs == 'true') | |
| needs: files-changed | |
| runs-on: ["ghcr.io/cirruslabs/macos-runner:sequoia", "runner_group_id:10"] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Select Xcode | |
| run: ./scripts/ci-select-xcode.sh 16.4 | |
| - name: Setup local sentry-cocoa dependency | |
| working-directory: 3rd-party-integrations/SentrySwiftLog | |
| run: swift package edit sentry-cocoa --path ../.. | |
| - name: Run SwiftLog tests | |
| working-directory: 3rd-party-integrations/SentrySwiftLog | |
| run: swift test | |
| - name: Archiving Raw Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: raw-output-swiftlog-integration | |
| path: | | |
| 3rd-party-integrations/SentrySwiftLog/.build/**/*.log | |
| - name: Run CI Diagnostics | |
| if: failure() | |
| run: ./scripts/ci-diagnostics.sh | |
| # This will be replaced once #6945 is merged. | |
| swiftybeaver-integration-unit-tests: | |
| name: SentrySwiftyBeaver Unit Tests | |
| if: startsWith(github.ref, 'refs/heads/release/') == false && (github.event_name != 'pull_request' || needs.files-changed.outputs.run_unit_tests_for_prs == 'true') | |
| needs: files-changed | |
| runs-on: ["ghcr.io/cirruslabs/macos-runner:sequoia", "runner_group_id:10"] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Select Xcode | |
| run: ./scripts/ci-select-xcode.sh 16.4 | |
| - name: Setup local sentry-cocoa dependency | |
| working-directory: 3rd-party-integrations/SentrySwiftyBeaver | |
| run: swift package edit sentry-cocoa --path ../.. | |
| - name: Run SwiftyBeaver tests | |
| working-directory: 3rd-party-integrations/SentrySwiftyBeaver | |
| run: swift test | |
| - name: Archiving Raw Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: raw-output-swiftybeaver-integration | |
| path: | | |
| 3rd-party-integrations/SentrySwiftyBeaver/.build/**/*.log | |
| - name: Run CI Diagnostics | |
| if: failure() | |
| run: ./scripts/ci-diagnostics.sh | |
| # This will be replaced once #6945 is merged. | |
| cocoalumberjack-integration-unit-tests: | |
| name: SentryCocoaLumberjack Unit Tests | |
| if: startsWith(github.ref, 'refs/heads/release/') == false && (github.event_name != 'pull_request' || needs.files-changed.outputs.run_unit_tests_for_prs == 'true') | |
| needs: files-changed | |
| runs-on: ["ghcr.io/cirruslabs/macos-runner:sequoia", "runner_group_id:10"] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Select Xcode | |
| run: ./scripts/ci-select-xcode.sh 16.4 | |
| - name: Setup local sentry-cocoa dependency | |
| working-directory: 3rd-party-integrations/SentryCocoaLumberjack | |
| run: swift package edit sentry-cocoa --path ../.. | |
| - name: Run CocoaLumberjack tests | |
| working-directory: 3rd-party-integrations/SentryCocoaLumberjack | |
| run: swift test | |
| - name: Archiving Raw Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: raw-output-cocoalumberjack-integration | |
| path: | | |
| 3rd-party-integrations/SentryCocoaLumberjack/.build/**/*.log | |
| - name: Run CI Diagnostics | |
| if: failure() | |
| run: ./scripts/ci-diagnostics.sh | |
| # This will be replaced once #6945 is merged. | |
| pulse-integration-unit-tests: | |
| name: SentryPulse Unit Tests | |
| if: startsWith(github.ref, 'refs/heads/release/') == false && (github.event_name != 'pull_request' || needs.files-changed.outputs.run_unit_tests_for_prs == 'true') | |
| needs: files-changed | |
| runs-on: ["ghcr.io/cirruslabs/macos-runner:sequoia", "runner_group_id:10"] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Select Xcode | |
| run: ./scripts/ci-select-xcode.sh 16.4 | |
| - name: Setup local sentry-cocoa dependency | |
| working-directory: 3rd-party-integrations/SentryPulse | |
| run: swift package edit sentry-cocoa --path ../.. | |
| - name: Run Pulse tests | |
| working-directory: 3rd-party-integrations/SentryPulse | |
| run: swift test | |
| - name: Archiving Raw Logs | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ failure() || cancelled() }} | |
| with: | |
| name: raw-output-pulse-integration | |
| path: | | |
| 3rd-party-integrations/SentryPulse/.build/**/*.log | |
| - name: Run CI Diagnostics | |
| if: failure() | |
| run: ./scripts/ci-diagnostics.sh | |
| # This check validates that either all unit tests passed or were skipped, which allows us | |
| # to make unit tests a required check with only running the unit tests when required. | |
| # So, we don't have to run unit tests, for example, for Changelog or ReadMe changes. | |
| unit-tests-required-check: | |
| needs: | |
| [ | |
| files-changed, | |
| build-test-server, | |
| distribution-tests, | |
| unit-tests, | |
| swiftlog-integration-unit-tests, | |
| swiftybeaver-integration-unit-tests, | |
| cocoalumberjack-integration-unit-tests, | |
| pulse-integration-unit-tests, | |
| ready-to-merge-gate, | |
| unit-tests-with-test-server, | |
| ] | |
| name: Unit Tests | |
| # This is necessary since a failed/skipped dependent job would cause this job to be skipped | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| # If any jobs we depend on fails gets cancelled or times out, this job will fail. | |
| # Skipped jobs are not considered failures. | |
| - name: Check for failures | |
| if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') | |
| run: | | |
| echo "One of the unit test jobs has failed." && exit 1 |