From b4e3555cf533549d6f1e36d1dd75ef9a2f20e352 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:08:41 -0300 Subject: [PATCH 1/9] Fix build with 15.4 issue --- .../build-xcframework-variant-slices.yml | 8 ++------ .../Performance/IO/Data+SentryTracing.swift | 4 ++-- sdk_api.json | 15 ++++----------- sdk_api_V9.json | 15 ++++----------- 4 files changed, 12 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build-xcframework-variant-slices.yml b/.github/workflows/build-xcframework-variant-slices.yml index 5f7fc21c2ee..9125804c35b 100644 --- a/.github/workflows/build-xcframework-variant-slices.yml +++ b/.github/workflows/build-xcframework-variant-slices.yml @@ -67,12 +67,8 @@ jobs: steps: - uses: actions/checkout@v4 - # We have to compile on Xcode 15.2 because compiling on Xcode 15.4 fails with - # Data+SentryTracing.swift:21:62: error: 'ReadingOptions' aliases 'Foundation.ReadingOptions' - # and cannot be used here because C++ types from imported module 'Foundation' do not support - # library evolution; this is an error in the Swift 6 language mode - # We also can't use Xcode 16.x because validating the XCFramework then fails with Xcode 15.x. - - run: ./scripts/ci-select-xcode.sh 15.2 + # We can't use Xcode 16.x because validating the XCFramework then fails with Xcode 15.x. + - run: ./scripts/ci-select-xcode.sh 15.4 shell: bash - name: Get version diff --git a/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift b/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift index c72a764bdf8..ded0e7d17a5 100644 --- a/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift +++ b/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift @@ -18,9 +18,9 @@ public extension Data { /// - url: The location on disk of the data to read. /// - options: The mask specifying the options to use when reading the data. For more information, see ``NSData.ReadingOptions``. /// - Note: See ``Data.init(contentsOf:options:)`` for more information. - init(contentsOfWithSentryTracing url: URL, options: Data.ReadingOptions = []) throws { + init(contentsOfWithSentryTracing url: URL, options: NSData.ReadingOptions = []) throws { // Gets a tracker instance if the SDK is enabled, otherwise uses the original method. - let method = { (url: URL, options: Data.ReadingOptions) throws -> Data in + let method = { (url: URL, options: NSData.ReadingOptions) throws -> Data in try Data(contentsOf: url, options: options) } guard let tracker = SentryFileIOTracker.sharedInstance() else { diff --git a/sdk_api.json b/sdk_api.json index 47bac207404..a9cb9a6e7ee 100644 --- a/sdk_api.json +++ b/sdk_api.json @@ -56887,18 +56887,11 @@ "usr": "s:10Foundation3URLV" }, { - "kind": "TypeNameAlias", + "kind": "TypeNominal", "name": "ReadingOptions", - "printedName": "Foundation.Data.ReadingOptions", - "children": [ - { - "kind": "TypeNominal", - "name": "ReadingOptions", - "printedName": "Foundation.NSData.ReadingOptions", - "usr": "c:@E@NSDataReadingOptions" - } - ], - "hasDefaultArg": true + "printedName": "Foundation.NSData.ReadingOptions", + "hasDefaultArg": true, + "usr": "c:@E@NSDataReadingOptions" } ], "declKind": "Constructor", diff --git a/sdk_api_V9.json b/sdk_api_V9.json index e8a530c1824..595e5dd672d 100644 --- a/sdk_api_V9.json +++ b/sdk_api_V9.json @@ -53936,18 +53936,11 @@ "usr": "s:10Foundation3URLV" }, { - "kind": "TypeNameAlias", + "kind": "TypeNominal", "name": "ReadingOptions", - "printedName": "Foundation.Data.ReadingOptions", - "children": [ - { - "kind": "TypeNominal", - "name": "ReadingOptions", - "printedName": "Foundation.NSData.ReadingOptions", - "usr": "c:@E@NSDataReadingOptions" - } - ], - "hasDefaultArg": true + "printedName": "Foundation.NSData.ReadingOptions", + "hasDefaultArg": true, + "usr": "c:@E@NSDataReadingOptions" } ], "declKind": "Constructor", From f3ffe64914cd6791768854c573db0171e69d3566 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:09:56 -0300 Subject: [PATCH 2/9] Disable all other tests --- .github/workflows/api-stability.yml | 55 ---- .../assemble-xcframework-variant.yml | 137 --------- .github/workflows/auto-update-tools.yml | 91 ------ .github/workflows/benchmarking.yml | 173 ----------- .../build-xcframework-variant-slices.yml | 142 --------- .github/workflows/build.yml | 228 -------------- .../workflows/changes-in-high-risk-code.yml | 75 ----- .github/workflows/codeql-analysis.yml | 47 --- .github/workflows/danger.yml | 9 - .github/workflows/integration-test.yml | 46 --- .github/workflows/lint-clang-formatting.yml | 50 ---- .github/workflows/lint-dprint.yml | 29 -- .github/workflows/lint-shellcheck.yml | 25 -- .github/workflows/lint-swift-formatting.yml | 39 --- .github/workflows/lint.yml | 76 ----- .../workflows/objc-conversion-analysis.yml | 58 ---- .github/workflows/release-comment-issues.yml | 33 -- .../workflows/release-upload-xcframework.yml | 47 --- .github/workflows/test-cross-platform.yml | 68 ----- .github/workflows/test.yml | 281 ------------------ .github/workflows/testflight.yml | 66 ---- .github/workflows/ui-tests-common.yml | 150 ---------- .github/workflows/ui-tests-critical.yml | 78 ----- .github/workflows/ui-tests.yml | 99 ------ .github/workflows/version-bump-util.yml | 81 ----- 25 files changed, 2183 deletions(-) delete mode 100644 .github/workflows/api-stability.yml delete mode 100644 .github/workflows/assemble-xcframework-variant.yml delete mode 100644 .github/workflows/auto-update-tools.yml delete mode 100644 .github/workflows/benchmarking.yml delete mode 100644 .github/workflows/build-xcframework-variant-slices.yml delete mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/changes-in-high-risk-code.yml delete mode 100644 .github/workflows/codeql-analysis.yml delete mode 100644 .github/workflows/danger.yml delete mode 100644 .github/workflows/integration-test.yml delete mode 100644 .github/workflows/lint-clang-formatting.yml delete mode 100644 .github/workflows/lint-dprint.yml delete mode 100644 .github/workflows/lint-shellcheck.yml delete mode 100644 .github/workflows/lint-swift-formatting.yml delete mode 100644 .github/workflows/lint.yml delete mode 100644 .github/workflows/objc-conversion-analysis.yml delete mode 100644 .github/workflows/release-comment-issues.yml delete mode 100644 .github/workflows/release-upload-xcframework.yml delete mode 100644 .github/workflows/test-cross-platform.yml delete mode 100644 .github/workflows/test.yml delete mode 100644 .github/workflows/testflight.yml delete mode 100644 .github/workflows/ui-tests-common.yml delete mode 100644 .github/workflows/ui-tests-critical.yml delete mode 100644 .github/workflows/ui-tests.yml delete mode 100644 .github/workflows/version-bump-util.yml diff --git a/.github/workflows/api-stability.yml b/.github/workflows/api-stability.yml deleted file mode 100644 index 45cb74c6e26..00000000000 --- a/.github/workflows/api-stability.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: API Stability Check - -on: - pull_request: - paths: - - "Sources/**" - - "test-server/**" - - ".github/workflows/api-stability.yml" - - Sentry.xcworkspace/** - - Sentry.xcodeproj/** - - "Package.swift" - - "scripts/build-xcframework-local.sh" - - "scripts/update-api.sh" - -jobs: - api-stability: - runs-on: macos-15 - strategy: - matrix: - version: [default, v9] - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - run: ./scripts/ci-select-xcode.sh 16.4 - - - name: Generate HEAD SDK - run: | - if [ "${{ matrix.version }}" = "v9" ]; then - mv sdk_api_v9.json sdk_api_base.json - make generate-public-api CONFIG=V9 - mv sdk_api_v9.json sdk_api.json - else - mv sdk_api.json sdk_api_base.json - make generate-public-api - fi - - - name: Diagnose breaking changes - run: | - if diff -q "sdk_api_base.json" "sdk_api.json" > /dev/null; then - echo "No API changes detected for ${{ matrix.version }} version." - else - echo "❌ Public API changes are detected for ${{ matrix.version }} version. If they're intended run "make generate-public-api" and commit the changes." - diff "sdk_api_base.json" "sdk_api.json" || true - xcrun --sdk iphoneos swift-api-digester \ - -diagnose-sdk \ - -o result.json \ - -input-paths sdk_api_base.json \ - -input-paths sdk_api.json \ - -json \ - -v - cat result.json - exit 1 - fi diff --git a/.github/workflows/assemble-xcframework-variant.yml b/.github/workflows/assemble-xcframework-variant.yml deleted file mode 100644 index 8336b99df85..00000000000 --- a/.github/workflows/assemble-xcframework-variant.yml +++ /dev/null @@ -1,137 +0,0 @@ -name: "Assemble Sentry Cocoa XCFramework variant" - -on: - workflow_call: - inputs: - name: - description: |- - The Sentry project target to build an XCFramework slice for. - Possible values: Sentry, SentrySwiftUI. - required: true - type: string - - suffix: - description: |- - The suffix to add to the build product name. - E.g. "-Dynamic" or "-WithoutUIKitOrAppKit". - required: false - type: string - - configuration-suffix: - description: |- - The suffix to add to the build product name to build an alternate configuration of the target. - E.g. "WithoutUIKit". - required: false - type: string - - variant-id: - description: |- - The ID of the variant to build an XCFramework slice for. Used to collect appropriate slices for final deliverable assembly. - E.g. "sentry-static", "sentry-dynamic" or "sentry-withoutuikit-dynamic" - required: true - type: string - - signed: - description: |- - Whether or not the assembled XCFramework should be signed. - required: false - type: boolean - default: false - - sdks: - description: |- - The SDK slices to assemble into an XCFramework. - required: false - type: string - default: "iphoneos,iphonesimulator,macosx,maccatalyst,appletvos,appletvsimulator,watchos,watchsimulator,xros,xrsimulator" - - release-version: - description: |- - For release workflows, the version to inject into the SDK. - required: false - type: string - -jobs: - assemble-xcframework-variant: - name: Assemble ${{inputs.name}}${{inputs.suffix}} XCFramework Variant - - runs-on: macos-14 - steps: - - uses: actions/checkout@v4 - - - uses: ruby/setup-ruby@v1 - if: ${{ inputs.signed }} - with: - bundler-cache: true - - - name: "Download Fastlane Certificate" - if: ${{ inputs.signed }} - run: bundle exec fastlane prepare_xcframework_signing - env: - APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} - APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} - APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} - FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} - MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} - - - name: Get version - id: get-version - run: | - if [ -n "${{ inputs.release-version }}" ]; then - echo "VERSION=${{ inputs.release-version }}" >> $GITHUB_ENV - else - echo "VERSION=$(grep MARKETING_VERSION Sources/Configuration/Versioning.xcconfig | cut -d ' ' -f 3)+${{ github.sha }}" >> $GITHUB_ENV - fi - shell: sh - - - name: Compute cache key - run: | - sdks_string=${{inputs.sdks}} - sdks_string_slugified=${sdks_string//,/_} - echo "SENTRY_XCFRAMEWORK_CACHE_KEY=${{runner.os}}-xcframework-${{inputs.variant-id}}-$sdks_string_slugified-${{inputs.signed}}-${{env.VERSION}}-${{hashFiles('Sources/**')}}-${{hashFiles('Sentry.xcodeproj/**')}}" >> $GITHUB_ENV - - - name: Restore XCFramework cache - id: cache-xcframework - uses: actions/cache@v4 - with: - key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} - path: ${{inputs.name}}${{inputs.suffix}}.xcframework.zip - - - name: Download ${{inputs.variant-id}} Slices - if: steps.cache-xcframework.outputs.cache-hit != 'true' - uses: actions/download-artifact@v4 - with: - pattern: xcframework-${{inputs.variant-id}}-slice-* - path: xcframework-slices - - - name: Unzip slice artifact ZIP archives - if: steps.cache-xcframework.outputs.cache-hit != 'true' - run: | - find xcframework-slices -type f -print0 | xargs -t0I @ unzip @ -d xcframework-slices - shell: bash - - - name: Assemble XCFramework - if: steps.cache-xcframework.outputs.cache-hit != 'true' - run: ./scripts/assemble-xcframework.sh "${{inputs.name}}" "${{inputs.suffix}}" "${{inputs.configuration-suffix}}" "${{inputs.sdks}}" "/Users/runner/work/sentry-cocoa/sentry-cocoa/xcframework-slices/SDK_NAME.xcarchive" - shell: bash - - - name: Zip XCFramework - if: steps.cache-xcframework.outputs.cache-hit != 'true' - run: ./scripts/compress-xcframework.sh ${{inputs.signed && '--sign' || '--not-signed'}} ${{inputs.name}}${{inputs.suffix}} - shell: bash - - - name: Cache XCFramework - uses: actions/cache@v4 - with: - key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} - path: ${{inputs.name}}${{inputs.suffix}}.xcframework.zip - - - name: Upload XCFramework - uses: actions/upload-artifact@v4 - with: - overwrite: true - name: xcframework-${{github.sha}}-${{inputs.variant-id}} - if-no-files-found: error - path: ${{inputs.name}}${{inputs.suffix}}.xcframework.zip diff --git a/.github/workflows/auto-update-tools.yml b/.github/workflows/auto-update-tools.yml deleted file mode 100644 index 141d4ad99ba..00000000000 --- a/.github/workflows/auto-update-tools.yml +++ /dev/null @@ -1,91 +0,0 @@ -# This workflow is used to update the custom tooling versions for the project. -# -# We prefer to use Dependabot to update external dependencies, but at this time it does not include Homebrew as a supported package manager (https://docs.github.com/en/code-security/dependabot/ecosystems-supported-by-dependabot/supported-ecosystems-and-repositories). -# Furthermore, neither `swiftlint` nor `clang-format` are listed as dependencies in our repository, therefore also not picked up by Dependabot. -# -# Therefore we are using a custom workflow to update relevant files and open a pull request with the changes. - -name: "Automation: Update tooling versions" - -on: - schedule: - - cron: "0 0 * * *" - workflow_dispatch: - pull_request: - paths: - - ".github/workflows/auto-update-tools.yml" - - "Brewfile*" - - "Makefile" - - "scripts/.clang-format-version" - - "scripts/.swiftlint-version" - - ".pre-commit-config.yaml" - -# Permissions configuration: -# - 'contents: write' is required to allow the workflow to commit changes to the repository -# when updating the tooling version files and creating branches for pull requests. -# - 'pull-requests: write' is required to allow the workflow to create pull requests -# using the peter-evans/create-pull-request action when tooling version updates are available. -permissions: - contents: write - pull-requests: write - -# Concurrency configuration: -# - We use a named concurrency group to prevent multiple instances of this workflow from running -# simultaneously, which could lead to race conditions when creating branches and pull requests. -# Since this workflow modifies version files and creates PRs, concurrent runs could interfere -# with each other, resulting in conflicting branches or duplicate PRs. -# - We enable cancellation of in-progress runs because only the most recent run matters for -# version updates. There's no value in completing outdated runs, especially for scheduled -# workflows that might queue up overnight. This approach conserves GitHub Actions minutes -# and ensures we're always working with the latest repository state. -concurrency: - group: "auto-update-tools" - cancel-in-progress: true - -jobs: - auto-update-tools: - runs-on: macos-15 - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Update Homebrew - run: brew update - - - name: Install Tools - run: make init - - - name: Update tooling versions - run: make update-versions - - - name: Check tooling versions - run: make check-versions - - - name: Print git status and changes - run: | - git status - git diff HEAD - - - name: Create pull request for clang-format version - uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e #v7.0.8 - if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} - with: - add-paths: scripts/.clang-format-version - branch: github-actions/auto-update-tools-clang-format - commit-message: "chore(deps): Update clang-format version" - delete-branch: true - title: "chore(deps): Update clang-format version" - sign-commits: true - base: main - - - name: Create pull request for swiftlint version - uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e #v7.0.8 - if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} - with: - add-paths: scripts/.swiftlint-version - branch: github-actions/auto-update-tools-swiftlint - commit-message: "chore(deps): Update swiftlint version" - delete-branch: true - title: "chore(deps): Update swiftlint version" - sign-commits: true - base: main diff --git a/.github/workflows/benchmarking.yml b/.github/workflows/benchmarking.yml deleted file mode 100644 index f90b9676b3d..00000000000 --- a/.github/workflows/benchmarking.yml +++ /dev/null @@ -1,173 +0,0 @@ -name: Benchmarking -on: - push: - branches: - - main - - pull_request: - paths: - # test changes to Sentry SDK sources - - "Sources/**" - - # test changes to benchmarking implementation - - "Samples/iOS-Swift/**" - - ".github/workflows/benchmarking.yml" - - ".sauce/benchmarking-config.yml" - - "fastlane/**" - - "scripts/ci-select-xcode.sh" - - "Samples/iOS-Swift/iOS-Swift.yml" - - "Samples/iOS-Swift/iOS-Swift.xcconfig" - - "Samples/iOS-Swift/iOS-SwiftClilp.xcconfig" - - "Samples/iOS-Swift/iOS-Benchmarking.xcconfig" - - "scripts/build-xcframework-slice.sh" - - "scripts/assemble-xcframework.sh" - - ".github/workflows/build-xcframework-variant-slices.yml" - - ".github/workflows/assemble-xcframework-variant.yml" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-benchmark-test-target: - name: Build app and test runner - runs-on: macos-13 - steps: - - uses: actions/checkout@v4 - - run: ./scripts/ci-select-xcode.sh 15.2 - - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true - - run: make init-ci-build - - run: make xcode-ci - - name: Install SentryCli - run: brew install getsentry/tools/sentry-cli - - name: Cache iOS-Swift App and dSYM build products - id: ios-swift-cache - uses: actions/cache@v4 - with: - path: | - DerivedData/Build/Products/Debug-iphoneos/iOS-Swift.app.dSYM - DerivedData/Build/Products/Debug-iphoneos/iOS-Swift.app - key: ios-swift-for-ui-testing-cache-key-${{ hashFiles('Samples/iOS-Swift/**') }}-${{ hashFiles('Sources/Sentry/**') }} - - name: Cache iOS-Swift UI Test Runner App build product - id: ios-swift-benchmark-runner-cache - uses: actions/cache@v4 - with: - path: | - DerivedData/Build/Products/Debug-iphoneos/iOS-Benchmarking-Runner.app - key: ios-swift-for-ui-testing-cache-key-${{ hashFiles('Samples/iOS-Benchmarking/**') }} - - run: bundle exec fastlane build_ios_swift_for_tests - env: - APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} - APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} - APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} - FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} - MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} - - run: bundle exec fastlane build_ios_benchmark_test - env: - APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} - APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} - APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} - FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} - MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} - - name: Upload dSYMs - run: | - sentry-cli --auth-token ${{ secrets.SENTRY_AUTH_TOKEN }} upload-dif --org sentry-sdks --project sentry-cocoa DerivedData/Build/Products/Debug-iphoneos/iOS-Swift.app.dSYM - - name: Archiving DerivedData - uses: actions/upload-artifact@v4 - with: - name: DerivedData-Xcode - path: | - **/Debug-iphoneos/iOS-Swift.app - **/Debug-iphoneos/iOS-Benchmarking-Runner.app - - run-ui-tests-with-sauce: - name: Run benchmarks on Sauce Labs - runs-on: ubuntu-latest - needs: build-benchmark-test-target - strategy: - fail-fast: false - matrix: - suite: ["High-end device", "Mid-range device", "Low-end device"] - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: DerivedData-Xcode - - run: npm install -g saucectl@0.186.0 - - name: Run Benchmarks in SauceLab - id: run-benchmarks-in-sauce-lab - env: - SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} - SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} - # Note: We are not setting continue-on-error here, because we want the step to be marked as failed. - run: | - set -o pipefail && saucectl run \ - --select-suite "${{matrix.suite}}" \ - --config .sauce/benchmarking-config.yml \ - --tags benchmark \ - --verbose \ - 2>&1 | tee output.log - - - name: Recovery - Extract Test ID from output - id: should-retry-test - # Note: We need to use always() here, because the previous run step might be marked as failed. - if: ${{ always() && steps.run-benchmarks-in-sauce-lab.outcome == 'failure' }} - uses: actions/github-script@v7 - env: - SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} - SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} - with: - script: | - const fs = require('fs'); - const { execSync } = require('child_process'); - - console.log("Extracting test ID from output log"); - const outputLog = fs.readFileSync('output.log', 'utf8'); - - // Lookup for the test ID in the output log - // Note: The CLI output might change over time, so this might need to be updated. - const match = outputLog.match(/https:\/\/app\.saucelabs\.com\/tests\/([^\s]+)/); - const testId = match?.[1] ?? ''; - - if (!testId) { - core.warning("No SauceLabs test ID found in CLI output, it might have changed, retrying..."); - core.setOutput('RETRY_TEST', 'true'); - - return; - } - - try { - console.log(`Checking if the test exists in SauceLabs: ${testId}`); - execSync(`saucectl jobs get ${testId}`, { - env: process.env, - stdio: 'inherit' - }); - - console.log("Test exists but failed, not retrying."); - core.setFailed('Test exists but failed'); - } catch (error) { - console.log("Failed to get job, retrying..."); - core.setOutput('RETRY_TEST', 'true'); - } - - - name: Run Benchmarks in SauceLab - Retry 1 - id: run-benchmarks-in-sauce-lab-retry-1 - # Note: We need to use always() here, because the previous run step might be marked as failed. - if: ${{ always() && steps.should-retry-test.outputs.RETRY_TEST == 'true' }} - env: - SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} - SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} - run: | - echo "::warning SauceLabs benchmark tests need to be retried" - saucectl run \ - --select-suite "${{matrix.suite}}" \ - --config .sauce/benchmarking-config.yml \ - --tags benchmark \ - --verbose diff --git a/.github/workflows/build-xcframework-variant-slices.yml b/.github/workflows/build-xcframework-variant-slices.yml deleted file mode 100644 index 9125804c35b..00000000000 --- a/.github/workflows/build-xcframework-variant-slices.yml +++ /dev/null @@ -1,142 +0,0 @@ -name: "Build Sentry Cocoa XCFramework variant slices" - -on: - workflow_call: - inputs: - sdk-list: - description: |- - The list of Apple platform SDKs for which to build slices and assemble into an XCFramework. This must be a JSON array of strings, itself in a string since GitHub Actions doesn't support arrays as inputs. - Possible values: iphoneos, iphonesimulator, macosx, appletvos, appletvsimulator, watchos, watchsimulator, xros, xrsimulator. - required: false - default: '["iphoneos", "iphonesimulator", "macosx", "maccatalyst", "appletvos", "appletvsimulator", "watchos", "watchsimulator", "xros", "xrsimulator"]' - type: string - - name: - description: |- - The Sentry project target to build an XCFramework slice for. - Possible values: Sentry, SentrySwiftUI. - required: true - type: string - - suffix: - description: |- - The suffix to add to the build product name. - E.g. "-Dynamic" or "-WithoutUIKitOrAppKit". - required: false - type: string - - macho-type: - description: |- - The Mach-O type of the build product. - Possible values: mh_dylib, staticlib. - required: false - type: string - default: "mh_dylib" - - configuration-suffix: - description: |- - The suffix to add to the build product name to build an alternate configuration of the target. - E.g. "WithoutUIKit". - required: false - type: string - - variant-id: - description: |- - The ID of the variant to build an XCFramework slice for. Used to collect appropriate slices for final deliverable assembly. - required: true - type: string - - release-version: - description: |- - For release workflows, the version to inject into the SDK. - required: false - type: string - -jobs: - build-xcframework-variant-slices: - name: ${{matrix.sdk}} - - # We must compile this on an arm64 runner, cause it's required for visionOS. macos-14 uses arm64. - # To see the available runners see https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories. - runs-on: macos-14 - - strategy: - matrix: - sdk: ${{ fromJson(inputs.sdk-list) }} - - steps: - - uses: actions/checkout@v4 - - # We can't use Xcode 16.x because validating the XCFramework then fails with Xcode 15.x. - - run: ./scripts/ci-select-xcode.sh 15.4 - shell: bash - - - name: Get version - id: get-version - run: | - if [ -n "${{ inputs.release-version }}" ]; then - echo "VERSION=${{ inputs.release-version }}" >> $GITHUB_ENV - else - echo "VERSION=$(grep MARKETING_VERSION Sources/Configuration/Versioning.xcconfig | cut -d ' ' -f 3)+${{ github.sha }}" >> $GITHUB_ENV - fi - shell: sh - - - name: Compute cache key - run: | - echo "SENTRY_XCFRAMEWORK_CACHE_KEY=${{ runner.os }}-xcframework-${{inputs.variant-id}}-slice-${{matrix.sdk}}-${{ env.VERSION }}-${{hashFiles('Sources/**')}}-${{hashFiles('Sentry.xcodeproj/**')}}" >> $GITHUB_ENV - - - name: Restore xcarchive cache - id: cache-xcarchive - uses: actions/cache@v4 - with: - key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} - path: ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip - - - name: Bump version - if: steps.cache-xcarchive.outputs.cache-hit != 'true' - run: | - ./scripts/ci-select-xcode.sh 15.2 - make bump-version TO=${{ env.VERSION }} - - - name: Build ${{inputs.name}}${{inputs.suffix}} XCFramework slice for ${{matrix.sdk}} - if: steps.cache-xcarchive.outputs.cache-hit != 'true' - run: ./scripts/build-xcframework-slice.sh ${{matrix.sdk}} ${{inputs.name}} "${{inputs.suffix}}" "${{inputs.macho-type}}" "${{inputs.configuration-suffix}}" - shell: bash - - # The SentrySwiftUI archive build also builds Sentry.framework as a byproduct of the dependency. We need to remove that to avoid downstream assembly tasks from tripping on these extra files. In the future we could investigate using this byproduct instead of running a separate task for Sentry.framework, or use the one already built by that other task instead of rebuilding it here. - - name: Remove Sentry.framework from SentrySwiftUI build - if: steps.cache-xcarchive.outputs.cache-hit != 'true' && inputs.name == 'SentrySwiftUI' - run: | - find "${{github.workspace}}/Carthage/archive" -name "Sentry.framework" -print0 | xargs -t0 rm -rf - find "${{github.workspace}}/Carthage/archive" -name "Sentry.framework.dSYM" -print0 | xargs -t0 rm -rf - shell: bash - - # the upload action broke symlinks in the mac sdk slice's xcarchive - - name: Zip xcarchive - if: steps.cache-xcarchive.outputs.cache-hit != 'true' - run: | - ditto -c -k -X --rsrc --keepParent ${{github.workspace}}/Carthage/archive/${{inputs.name}}${{inputs.suffix}}/${{matrix.sdk}}.xcarchive ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip - shell: bash - - - name: Cache xcarchive - if: steps.cache-xcarchive.outputs.cache-hit != 'true' - uses: actions/cache@v4 - with: - key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} - path: ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip - - - name: Upload xcarchive - uses: actions/upload-artifact@v4 - with: - name: xcframework-${{inputs.variant-id}}-slice-${{matrix.sdk}} - if-no-files-found: error - path: | - ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip - - - name: Upload build log if failed - uses: actions/upload-artifact@v4 - if: ${{ failure() || cancelled() }} - with: - name: raw-build-output-build-xcframework-${{inputs.variant-id}}-${{matrix.sdk}} - path: | - *.log diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index ee4967a4ed6..00000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,228 +0,0 @@ -name: Build -on: - push: - branches: - - main - - release/** - - pull_request: - paths: - - "Sources/**" - - "test-server/**" - - "Samples/**" - - ".github/workflows/build.yml" - - "fastlane/**" - - "scripts/ci-select-xcode.sh" - - Sentry.xcworkspace/** - - Sentry.xcodeproj/** - - Gemfile.lock - - "Package.swift" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - # We had issues that the release build was broken on main. - # With this we catch potential issues already in the PR. - ios-swift-release: - name: Release Build of iOS Swift - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - run: ./scripts/ci-select-xcode.sh 16.4 - - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true - - run: make init-ci-build - - run: make xcode-ci - - name: Run Fastlane - env: - APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} - APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} - APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} - FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} - MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} - run: bundle exec fastlane build_ios_swift - - build-sample: - name: Sample ${{ matrix.scheme }} ${{ matrix.config }} - runs-on: macos-15 - strategy: - fail-fast: false - matrix: - # other sample projects are built in ui-tests - include: - - scheme: macOS-Swift - config: Debug - - scheme: iOS13-Swift - config: Debug - - scheme: watchOS-Swift WatchKit App - config: Debug - - scheme: macOS-SwiftUI - config: Debug - - scheme: SessionReplay-CameraTest - config: Debug - - scheme: visionOS-Swift - config: Debug - - scheme: iOS-Swift - config: DebugV9 - - scheme: macOS-Swift - config: DebugV9 - - scheme: tvOS-Swift - config: DebugV9 - - scheme: visionOS-Swift - config: DebugV9 - - scheme: iOS-SwiftUI - config: DebugV9 - - scheme: iOS-ObjectiveC - config: DebugV9 - - steps: - - uses: actions/checkout@v4 - - run: ./scripts/ci-select-xcode.sh 16.4 - - run: make init-ci-build - - run: make xcode-ci - - # Note: Due to complexity in implementing the CODE_SIGNING_ALLOWED flag in the sentry-xcodebuild.sh script, - # we did not yet migrate this step to use the script yet. - - run: >- - env NSUnbufferedIO=YES - xcodebuild - -workspace Sentry.xcworkspace - -scheme '${{matrix.scheme}}' - -configuration ${{matrix.config}} - CODE_SIGNING_ALLOWED="NO" - build - - - name: Archiving Raw Build Logs - uses: actions/upload-artifact@v4 - if: ${{ failure() || cancelled() }} - with: - name: raw-build-output-scheme-${{matrix.scheme}} - path: | - raw-build-output.log - build-spm: - name: Build with SPM - runs-on: macos-15 - # Don't run this on release branches, cause the SPM Package.swift points to the unreleased versions. - if: startsWith(github.ref, 'refs/heads/release/') == false - steps: - - uses: actions/checkout@v4 - - run: rm -r Sentry.xcodeproj && rm -r Sentry.xcworkspace && EXPERIMENTAL_SPM_BUILDS=1 xcodebuild build -scheme SentrySPM -sdk watchos -destination 'generic/platform=watchOS' - shell: sh - - run: EXPERIMENTAL_SPM_BUILDS=1 xcodebuild build -scheme SentrySPM -sdk iphoneos -destination 'generic/platform=iphoneos' - shell: sh - - build-v9: - name: Build SDK v9 - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - run: ./scripts/sentry-xcodebuild.sh --platform iOS --os latest --device "iPhone 16" --command build --configuration DebugV9 - - check-debug-without-UIKit: - name: Check no UIKit linkage (DebugWithoutUIKit) - runs-on: macos-13 - steps: - - uses: actions/checkout@v4 - - name: Build for Debug - run: | - ./scripts/sentry-xcodebuild.sh \ - --platform iOS \ - --os latest \ - --ref ${{ github.ref }} \ - --command build \ - --device "iPhone 14" \ - --configuration DebugWithoutUIKit \ - --derived-data uikit-check-build - - name: Ensure UIKit is not linked - run: ./scripts/check-uikit-linkage.sh DebugWithoutUIKit uikit-check-build unlinked SentryWithoutUIKit - - check-release-without-UIKit: - name: Check no UIKit linkage (ReleaseWithoutUIKit) - runs-on: macos-13 - steps: - - uses: actions/checkout@v4 - - name: Build for Release - run: | - ./scripts/sentry-xcodebuild.sh \ - --platform iOS \ - --os latest \ - --ref ${{ github.ref }} \ - --command build \ - --device "iPhone 14" \ - --configuration ReleaseWithoutUIKit \ - --derived-data uikit-check-build - - name: Ensure UIKit is not linked - run: ./scripts/check-uikit-linkage.sh ReleaseWithoutUIKit uikit-check-build unlinked SentryWithoutUIKit - - check-debug-with-UIKit: - name: Check UIKit linkage (Debug) - runs-on: macos-13 - steps: - - uses: actions/checkout@v4 - - name: Build for Debug - run: | - ./scripts/sentry-xcodebuild.sh \ - --platform iOS \ - --os latest \ - --ref ${{ github.ref }} \ - --command build \ - --device "iPhone 14" \ - --configuration Debug \ - --derived-data uikit-check-build - - name: Ensure UIKit is linked - run: ./scripts/check-uikit-linkage.sh Debug uikit-check-build linked Sentry - - check-release-with-UIKit: - name: Check UIKit linkage (Release) - runs-on: macos-13 - steps: - - uses: actions/checkout@v4 - - name: Build for Release - run: | - ./scripts/sentry-xcodebuild.sh \ - --platform iOS \ - --os latest \ - --ref ${{ github.ref }} \ - --command build \ - --device "iPhone 14" \ - --configuration Release \ - --derived-data uikit-check-build - - name: Ensure UIKit is linked - run: ./scripts/check-uikit-linkage.sh Release uikit-check-build linked Sentry - - # The compiler only evaluates SentryAsyncSafeLogs that get printed based on the SENTRY_ASYNC_SAFE_LOG_LEVEL. - # So if the level is set to error, which is the default, and a SENTRY_ASYNC_SAFE_LOG_DEBUG has a compiler error, - # you only get the compiler error when setting the SENTRY_ASYNC_SAFE_LOG_LEVEL to SENTRY_ASYNC_SAFE_LOG_LEVEL_DEBUG or lower. - - check-compiling-async-safe-logs: - name: Check compiling Async Safe Logs - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - # If the SentryAsyncSafeLog doesn't contain the SENTRY_ASYNC_SAFE_LOG_LEVEL_ERROR this fails. - - name: Async Safe Log Level is Error - run: grep -c "SENTRY_ASYNC_SAFE_LOG_LEVEL SENTRY_ASYNC_SAFE_LOG_LEVEL_ERROR" Sources/Sentry/SentryAsyncSafeLog.h - - - name: Set Async Safe Log Level to Debug - run: | - sed -i '' 's/#define SENTRY_ASYNC_SAFE_LOG_LEVEL SENTRY_ASYNC_SAFE_LOG_LEVEL_ERROR/#define SENTRY_ASYNC_SAFE_LOG_LEVEL SENTRY_ASYNC_SAFE_LOG_LEVEL_TRACE/' Sources/Sentry/SentryAsyncSafeLog.h - shell: bash - - - run: ./scripts/ci-select-xcode.sh 16.4 - - - name: Build for Debug - run: | - ./scripts/sentry-xcodebuild.sh \ - --platform iOS \ - --os latest \ - --ref ${{ github.ref }} \ - --command build \ - --device "iPhone 16" \ - --configuration Debug diff --git a/.github/workflows/changes-in-high-risk-code.yml b/.github/workflows/changes-in-high-risk-code.yml deleted file mode 100644 index 4f8e16d95d9..00000000000 --- a/.github/workflows/changes-in-high-risk-code.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Changes In High Risk Code -on: - pull_request: - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - files-changed: - name: Detect changed files - runs-on: ubuntu-latest - # Map a step output to a job output - outputs: - high_risk_code: ${{ steps.changes.outputs.high_risk_code }} - high_risk_code_files: ${{ steps.changes.outputs.high_risk_code_files }} - steps: - - uses: actions/checkout@v4 - - name: Get changed files - id: changes - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 - with: - token: ${{ github.token }} - filters: .github/file-filters.yml - - # Enable listing of files matching each filter. - # Paths to files will be available in `${FILTER_NAME}_files` output variable. - list-files: csv - - validate-high-risk-code: - if: needs.files-changed.outputs.high_risk_code == 'true' - needs: files-changed - runs-on: ubuntu-latest - steps: - - name: Remove previous comments - uses: actions/github-script@v7 - with: - script: | - core.debug('Listing comments') - const response = await github.rest.issues.listComments({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo - }) - if (!response.data) { - core.info('No comments found') - return - } - core.debug(`Found ${response.data.length} comments`) - for (const comment of response.data) { - if (comment.user.login === 'github-actions[bot]' && comment.body.includes('### 🚨 Detected changes in high risk code 🚨')) { - core.info(`Deleting comment ${comment.id}`) - await github.rest.issues.deleteComment({ - comment_id: comment.id, - owner: context.repo.owner, - repo: context.repo.repo, - }) - } - } - - name: Comment on PR to notify of changes in high risk files - uses: actions/github-script@v7 - env: - high_risk_code: ${{ needs.files-changed.outputs.high_risk_code_files }} - with: - script: | - const highRiskFiles = process.env.high_risk_code; - const fileList = highRiskFiles.split(',').map(file => `- [ ] ${file}`).join('\n'); - - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: `### 🚨 Detected changes in high risk code 🚨 \n High-risk code can easily blow up and is hard to test. We had severe bugs in the past. Be extra careful when changing these files, and have an extra careful look at these:\n ${fileList}` - }) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index e22f4b94738..00000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [main] - pull_request: - branches: - - main - schedule: - - cron: "40 4 * * 6" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - analyze: - name: Analyze - runs-on: macos-13 - - strategy: - fail-fast: false - matrix: - language: ["cpp"] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - - - run: | - set -o pipefail && NSUnbufferedIO=YES xcodebuild \ - -workspace Sentry.xcworkspace \ - -scheme Sentry \ - -configuration Release \ - -destination platform="iOS Simulator,OS=latest,name=iPhone 14 Pro" \ - build 2>&1 | - tee raw-analyze-output.log | - xcbeautify - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml deleted file mode 100644 index 000b75ff3ee..00000000000 --- a/.github/workflows/danger.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Danger - -on: - pull_request: - types: [opened, synchronize, reopened, edited, ready_for_review] - -jobs: - danger: - uses: getsentry/github-workflows/.github/workflows/danger.yml@v2 diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml deleted file mode 100644 index 79ab0045907..00000000000 --- a/.github/workflows/integration-test.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: CocoaPods Integration Tests -on: - push: - branches: - - main - - pull_request: - paths: - - ".github/workflows/integration-test.yml" - - "*.xcodeproj" - - "*.xcworkspace" - - "Samples/iOS-Cocoapods-*/**" - - "scripts/ci-select-xcode.sh" - - "Sources/**" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - cocoapods: - name: Integration Test - runs-on: macos-15 - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Select Xcode - run: ./scripts/ci-select-xcode.sh 16.4 - - - name: Setup Ruby - uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0 - with: - bundler-cache: true - - - name: Run Integration Test - run: bundle exec fastlane cocoapods_integration_test - working-directory: Samples/iOS-Cocoapods-Swift6 - - - name: Upload Result Bundle - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: integration-test-iOS-Cocoapods-Swift6.xcresult - path: Samples/iOS-Cocoapods-Swift6/fastlane/test_results/results.xcresult diff --git a/.github/workflows/lint-clang-formatting.yml b/.github/workflows/lint-clang-formatting.yml deleted file mode 100644 index e9315874bac..00000000000 --- a/.github/workflows/lint-clang-formatting.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Check Code Formatting -on: - push: - branches: - - main - paths: - - "**/*.h" - - "**/*.hpp" - - "**/*.c" - - "**/*.cpp" - - "**/*.m" - - "**/*.mm" - - ".github/workflows/lint-clang-formatting.yml" - - ".clang-format" - - pull_request: - paths: - - "**/*.h" - - "**/*.hpp" - - "**/*.c" - - "**/*.cpp" - - "**/*.m" - - "**/*.mm" - - ".github/workflows/lint-clang-formatting.yml" - - ".clang-format" - -jobs: - format-code: - # While ubuntu runners have clang-format preinstalled, they use an older version. We want to use the most recent one, - # that we can easily install locally via brew. - name: Check Formatting of Clang Format - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - name: Install tooling - run: make init-ci-format - - - name: Format with Clang - run: make format-clang - - - name: Check for Formatting Changes - run: | - if [[ -n "$(git status --porcelain)" ]]; then - echo "❌ Some code formatted with clang-format is not formatted correctly. Please run 'make format' and commit the changes." - git status - git diff - exit 1 - else - echo "✅ All code is formatted correctly." - fi diff --git a/.github/workflows/lint-dprint.yml b/.github/workflows/lint-dprint.yml deleted file mode 100644 index 56d56e0247d..00000000000 --- a/.github/workflows/lint-dprint.yml +++ /dev/null @@ -1,29 +0,0 @@ -# We want to run dprint for only the files it checks without running the other linters, which are -# expensive. For example, dprint should run for markdown changes, but pod lib lint doesn't need to -# run for markdown changes. Therefore, we run it in an extra workflow. - -name: lint-dprint -on: - push: - branches: - - main - paths: - - "**/*.yml" - - "**/*.yaml" - - "**/*.json" - - "**/*.md" - - pull_request: - paths: - - "**/*.yml" - - "**/*.yaml" - - "**/*.json" - - "**/*.md" - -jobs: - lint-dprint: - name: Run dprint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dprint/check@v2.3 diff --git a/.github/workflows/lint-shellcheck.yml b/.github/workflows/lint-shellcheck.yml deleted file mode 100644 index d18d53abc6a..00000000000 --- a/.github/workflows/lint-shellcheck.yml +++ /dev/null @@ -1,25 +0,0 @@ -# We want only to run the shellcheck when sh files change without running the other linters, which are -# expensive. For example, pod lib lint doesn't need to run for sh changes. Therefore, we run it in an -# extra workflow. - -name: lint-shellcheck -on: - push: - branches: - - main - paths: - - ".github/workflows/lint-shellcheck.yml" - - "**/*.sh" - - pull_request: - paths: - - ".github/workflows/lint-shellcheck.yml" - - "**/*.sh" - -jobs: - shellcheck: - name: Run Shellcheck - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: shellcheck **/*.sh diff --git a/.github/workflows/lint-swift-formatting.yml b/.github/workflows/lint-swift-formatting.yml deleted file mode 100644 index 4e6ac0efd80..00000000000 --- a/.github/workflows/lint-swift-formatting.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Check Code Formatting -on: - push: - branches: - - main - paths: - - "**/*.swift" - - ".github/workflows/lint-swift-formatting.yml" - - ".swiftlint.yml" - - pull_request: - paths: - - "**/*.swift" - - ".github/workflows/lint-swift-formatting.yml" - - ".swiftlint.yml" - -jobs: - format-code: - name: Check Formatting of Swiftlint Code - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - - name: Install tooling - run: make init-ci-format - - - name: Run SwiftLint - run: make format-swift-all - - - name: Check for Formatting Changes - run: | - if [[ -n "$(git status --porcelain)" ]]; then - echo "❌ Some Swift code is not formatted correctly. Please run 'make format' and commit the changes." - git status - git diff - exit 1 - else - echo "✅ All code is formatted correctly." - fi diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 9e06c438eef..00000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: lint -on: - push: - branches: - - main - paths: - - "Sources/**" - - "Tests/**" - - "test-server/**" - - "Samples/**" - - ".github/workflows/lint.yml" - - "scripts/ci-select-xcode.sh" - - pull_request: - paths: - - "Sources/**" - - "Tests/**" - - "test-server/**" - - "Samples/**" - - ".github/workflows/lint.yml" - - "scripts/ci-select-xcode.sh" - - "Sentry.xcodeproj/**" - - "*.podspec" - - "Gemfile.lock" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - swift-lint: - name: Swift Lint - runs-on: macos-13 - steps: - - uses: actions/checkout@v4 - - run: swiftlint --version - - name: Run SwiftLint - run: swiftlint --strict - - xcode-analyze: - name: Xcode Analyze - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - run: ./scripts/ci-select-xcode.sh 16.4 - - run: make analyze - - lint-podspec: - name: pod lint ${{ matrix.podspec}} ${{ matrix.library_type }} ${{ matrix.platform}} - runs-on: macos-14 - strategy: - fail-fast: false - matrix: - podspec: ["Sentry", "SentrySwiftUI"] - platform: ["ios", "macos", "tvos", "watchos"] - library_type: ["dynamic", "static"] - - steps: - - uses: actions/checkout@v4 - - run: ./scripts/ci-select-xcode.sh 15.4 - # We need to update the spec-repo, because it can happen that it is not up to date and then the lint fails. - - run: pod repo update - - name: Validate Podspec - run: ./scripts/pod-lib-lint.sh ${{ matrix.platform }} ${{ matrix.podspec}} ${{ matrix.library_type}} - - lint-hybrid-sdk-podspec: - name: pod lint Sentry/HybridSDK - runs-on: macos-14 - - steps: - - uses: actions/checkout@v4 - - run: ./scripts/ci-select-xcode.sh 15.4 - - run: pod repo update - - name: Validate HybridPod Podspec - run: pod lib lint ./Tests/HybridSDKTest/HybridPod.podspec --allow-warnings --verbose --platforms=ios "--include-podspecs={Sentry.podspec}" diff --git a/.github/workflows/objc-conversion-analysis.yml b/.github/workflows/objc-conversion-analysis.yml deleted file mode 100644 index 6c0af7b65a5..00000000000 --- a/.github/workflows/objc-conversion-analysis.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Objective-C Conversion Analysis - -on: - push: - branches: - - main - pull_request: - paths: - - ".github/workflows/objc-conversion-analysis.yml" - - "SwiftConversion/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - analyze-objc-conversion: - name: Analyze Objective-C to Swift Conversion - runs-on: macos-15 - timeout-minutes: 10 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Ruby - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # pin@v5.4.3 - with: - ruby-version: "3.2" - bundler-cache: true - - - name: Install Graphviz - run: brew install graphviz - - - name: Run Objective-C conversion analyzer - working-directory: SwiftConversion - run: | - ruby objc_conversion_analyzer.rb - - - name: Generate Graphviz DOT file - working-directory: SwiftConversion - run: | - ruby generate_graphviz.rb - - - name: Convert DOT to SVG - working-directory: SwiftConversion - run: | - dot -Tsvg objc_dependencies_topo.dot -o objc_dependencies_topo.svg - - - name: Upload analysis artifacts - uses: actions/upload-artifact@v4 - with: - name: objc-conversion-analysis - path: | - SwiftConversion/objc_conversion_analysis.json - SwiftConversion/objc_dependencies_topo.dot - SwiftConversion/objc_dependencies_topo.svg - retention-days: 30 diff --git a/.github/workflows/release-comment-issues.yml b/.github/workflows/release-comment-issues.yml deleted file mode 100644 index ecf61b50824..00000000000 --- a/.github/workflows/release-comment-issues.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: "Automation: Notify issues for release" -on: - release: - types: - - published - workflow_dispatch: - inputs: - version: - description: Which version to notify issues for - required: false - -# This workflow is triggered when a release is published -jobs: - release-comment-issues: - runs-on: ubuntu-24.04 - name: Notify issues - steps: - - name: Get version - id: get_version - run: echo "version=${VERSION}" >> $GITHUB_OUTPUT - env: - VERSION: ${{ github.event.inputs.version || github.event.release.tag_name }} - - - name: Comment on linked issues that are mentioned in release - if: | - steps.get_version.outputs.version != '' - && !contains(steps.get_version.outputs.version, 'a') - && !contains(steps.get_version.outputs.version, 'b') - && !contains(steps.get_version.outputs.version, 'rc') - uses: getsentry/release-comment-issues-gh-action@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - version: ${{ steps.get_version.outputs.version }} diff --git a/.github/workflows/release-upload-xcframework.yml b/.github/workflows/release-upload-xcframework.yml deleted file mode 100644 index f72e906b45a..00000000000 --- a/.github/workflows/release-upload-xcframework.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Upload XCFrameworks -on: - push: - branches: - - release/** - -jobs: - # Craft uses the Git commit hash to query GitHub Actions for artifacts - # uploaded in a workflow run associated with that commit. - # - # To support this, we download the XCFramework already built and uploaded - # in release.yml (triggered via workflow_dispatch), and reupload it here. - # This associates it with the new commit in the release branch, which is - # created by getsentry/action-prepare-release in release.yml. - # - # This is necessary because Swift Package Manager requires a checksum for - # XCFrameworks, creating a chicken-and-egg problem: we need the XCFramework - # to generate the checksum, but we also need the checksum to update Package.swift. - # - # The sequence is: - # 1. Build the XCFrameworks in release.yml. - # 2. getsentry/action-prepare-release updates Package.swift with the checksum. - # 3. Upload the XCFrameworks again here so Craft can find it by commit. - upload-xcframeworks: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Get Release workflow run ID - run: echo "FRAMEWORK_RUN_ID=$(./scripts/xcframework-generated-run.sh)" >> $GITHUB_ENV - - - uses: actions/download-artifact@v4 - with: - name: xcframeworks.zip - path: Carthage/ - github-token: ${{ secrets.GITHUB_TOKEN }} - run-id: ${{ env.FRAMEWORK_RUN_ID }} - - - name: Archive XCFrameworks for Craft - uses: actions/upload-artifact@v4 - with: - # Craft uses the git commit hash of the release branch to download the release artifacts. - name: ${{ github.sha }} - if-no-files-found: error - overwrite: true - path: | - ${{github.workspace}}/Carthage/*.zip diff --git a/.github/workflows/test-cross-platform.yml b/.github/workflows/test-cross-platform.yml deleted file mode 100644 index 61637eca5b7..00000000000 --- a/.github/workflows/test-cross-platform.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Test Cross-Platform Sentry SDK Installation - -on: - push: - branches: - - main - pull_request: - paths: - - ".github/workflows/test-cross-platform.yml" - - "Sources/**" - - "Sentry.podspec" - -jobs: - test-react-native: - name: React Native - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - with: - repository: getsentry/sentry-cocoa - path: sentry-cocoa - - - name: Initialize tools - run: make init-ci-build - working-directory: sentry-cocoa - - - name: Clone Sentry React Native Repository - uses: actions/checkout@v4 - with: - repository: getsentry/sentry-react-native - path: sentry-react-native - - - name: Enable Corepack - working-directory: sentry-react-native - run: npm i -g corepack - - - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: "yarn" - cache-dependency-path: sentry-react-native/yarn.lock - - - name: Install SDK JS Dependencies - working-directory: sentry-react-native - run: yarn install - - - name: Remove Sentry/HybridSDK Dependency from RNSentry.podspec - run: sed -i '' "s/s.dependency 'Sentry\/HybridSDK', '[0-9]*\.[0-9]*\.[0-9]*'/s.dependency 'Sentry\/HybridSDK'/" sentry-react-native/packages/core/RNSentry.podspec - - - name: Add Sentry/HybridSDK Dependency to RNSentryCocoaTester/Podfile - run: sed -i '' -e "s/RNSentry.podspec'/RNSentry.podspec'\\n pod 'Sentry\/HybridSDK', :path => '..\/..\/..\/..\/sentry-cocoa'/" sentry-react-native/packages/core/RNSentryCocoaTester/Podfile - - - name: Install App Pods - working-directory: sentry-react-native/packages/core/RNSentryCocoaTester - run: pod install - - - name: Run iOS Tests - working-directory: sentry-react-native/packages/core/RNSentryCocoaTester - env: - SCHEME: RNSentryCocoaTester - CONFIGURATION: Release - DESTINATION: "platform=iOS Simulator,OS=latest,name=iPhone 16" - run: | - env NSUnbufferedIO=YES \ - xcodebuild -workspace *.xcworkspace \ - -scheme $SCHEME -configuration $CONFIGURATION \ - -destination "$DESTINATION" \ - test | xcbeautify diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index c81489a703a..00000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,281 +0,0 @@ -name: Test -on: - push: - branches: - - main - - release/** - - pull_request: - paths: - - "Sources/**" - - "Tests/**" - - "SentryTestUtils/**" - - "test-server/**" - - ".github/workflows/test.yml" - - "fastlane/**" - - "scripts/tests-with-thread-sanitizer.sh" - - "scripts/ci-select-xcode.sh" - - "scripts/sentry-xcodebuild.sh" - - ".codecov.yml" - - "Sentry.xcodeproj" - - "**/*.xctestplan" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-test-server: - name: Build test server - runs-on: macos-13 - steps: - - uses: actions/checkout@v4 - - name: Cache for Test Server - id: cache_test_server - uses: actions/cache@v4 - with: - path: ./test-server/.build - key: test-server-${{ hashFiles('./test-server') }} - restore-keys: | - test-server-${{ hashFiles('./test-server') }} - test-server- - - - name: Build Test Server - if: steps.cache_test_server.outputs.cache-hit != 'true' - working-directory: test-server - run: >- - swift build -c release 2>&1 | tee test-server-build.log - - - name: Copy exec - working-directory: test-server - run: cp $(swift build --show-bin-path -c release)/Run test-server-exec - - - name: Archiving DerivedData - uses: actions/upload-artifact@v4 - with: - name: test-server - path: | - ./test-server/test-server-exec - - - name: Archiving Raw Test Logs - uses: actions/upload-artifact@v4 - if: ${{ failure() || cancelled() }} - with: - name: test-server-build-log-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} - path: | - raw-test-output.log - - unit-tests: - name: Unit ${{matrix.platform}} - Xcode ${{matrix.xcode}} - OS ${{matrix.test-destination-os}} ${{matrix.scheme}} - runs-on: ${{matrix.runs-on}} - timeout-minutes: 20 - needs: build-test-server - - 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 16 - - runs-on: macos-13 - platform: "iOS" - xcode: "14.3.1" - test-destination-os: "16.4" - device: "iPhone 14" - scheme: "Sentry" - - # iOS 17 - - runs-on: macos-14 - platform: "iOS" - xcode: "15.4" - test-destination-os: "17.2" - device: "iPhone 15" - scheme: "Sentry" - - # iOS 18 - - runs-on: macos-15 - platform: "iOS" - xcode: "16.4" - test-destination-os: "18.2" - device: "iPhone 16" - 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 - - runs-on: macos-14 - platform: "macOS" - xcode: "15.4" - test-destination-os: "latest" - scheme: "Sentry" - - # macOS 15 - - runs-on: macos-15 - platform: "macOS" - xcode: "16.4" - test-destination-os: "latest" - 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. - - runs-on: macos-14 - platform: "Catalyst" - xcode: "15.4" - test-destination-os: "latest" - scheme: "Sentry" - - - runs-on: macos-15 - platform: "Catalyst" - xcode: "16.4" - test-destination-os: "latest" - scheme: "Sentry" - - # 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 - - runs-on: macos-14 - platform: "tvOS" - xcode: "15.4" - test-destination-os: "17.5" - scheme: "Sentry" - - # iOS 17 - - runs-on: macos-14 - platform: "iOS" - xcode: "15.4" - test-destination-os: "17.2" - device: "iPhone 15" - scheme: "SentrySwiftUI" - - # tvOS 18 - - runs-on: macos-15 - platform: "tvOS" - xcode: "16.4" - test-destination-os: "18.1" - scheme: "Sentry" - - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: test-server - - - name: Print hardware info - run: system_profiler SPHardwareDataType - - - name: Start Test Server - run: ./scripts/start-test-server.sh - - - run: ./scripts/ci-select-xcode.sh ${{matrix.xcode}} - - - name: Install Slather - run: gem install slather - - # 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 \ - --device "${{matrix.device}}" \ - --configuration TestCI \ - --scheme ${{matrix.scheme}} - - - name: Run tests - # We call a script with the platform so the destination - # passed to xcodebuild doesn't end up in the job name, - # because GitHub Actions don't provide an easy way of - # manipulating string in expressions. - run: | - ./scripts/sentry-xcodebuild.sh \ - --platform ${{matrix.platform}} \ - --os ${{matrix.test-destination-os}} \ - --ref ${{ github.ref_name }} \ - --command test-without-building \ - --device "${{matrix.device}}" \ - --configuration TestCI \ - --scheme ${{matrix.scheme}} - - - name: Publish Test Report - uses: mikepenz/action-junit-report@3585e9575db828022551b4231f165eb59a0e74e3 # v5.6.2 - if: always() - with: - report_paths: "build/reports/junit.xml" - fail_on_failure: true - fail_on_parse_error: true - detailed_summary: true - - - name: Slowest Tests - if: ${{ always() }} - run: ./scripts/xcode-slowest-tests.sh - - - name: Archiving DerivedData Logs - uses: actions/upload-artifact@v4 - if: steps.build_tests.outcome == 'failure' - with: - name: derived-data-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} - path: | - /Users/runner/Library/Developer/Xcode/DerivedData/**/Logs/** - - - name: Archiving Raw Logs - uses: actions/upload-artifact@v4 - if: ${{ failure() || cancelled() }} - with: - name: raw-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} - path: | - raw-build-output.log - raw-build-for-testing-output.log - raw-test-output.log - - - name: Archiving Crash Logs - uses: actions/upload-artifact@v4 - if: ${{ failure() || cancelled() }} - with: - name: crash-logs-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} - path: | - ~/Library/Logs/DiagnosticReports/** - - # We can upload all coverage reports, because codecov merges them. - # See https://docs.codecov.io/docs/merging-reports - # Checkout .codecov.yml to see the config of Codecov - # We don't upload codecov for release branches, as we don't want a failing coverage check to block a release. - # We don't upload codecov for scheduled runs as CodeCov only accepts a limited amount of uploads per commit. - - name: Push code coverage to codecov - id: codecov_1 - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # pin@v5.4.3 - if: ${{ contains(matrix.platform, 'iOS') && !contains(github.ref, 'release') && github.event.schedule == '' }} - with: - # Although public repos should not have to specify a token there seems to be a bug with the Codecov GH action, which can - # be solved by specifying the token, see https://github.com/codecov/codecov-action/issues/557#issuecomment-1224970469 - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false - verbose: true - - # Sometimes codecov uploads etc can fail. Retry one time to rule out e.g. intermittent network failures. - - name: Push code coverage to codecov - id: codecov_2 - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # pin@v5.4.3 - if: ${{ steps.codecov_1.outcome == 'failure' && contains(matrix.platform, 'iOS') && !contains(github.ref, 'release') && github.event.schedule == '' }} - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true - verbose: true - - - name: Codecov test analytics - if: ${{ !cancelled() && !contains(github.ref, 'release') && github.event.schedule == '' }} - uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # pin@v1.1.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - name: sentry-cocoa-unit-tests diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml deleted file mode 100644 index 32513b2f64c..00000000000 --- a/.github/workflows/testflight.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Upload to Testflight -on: - push: - branches: - - main - - release/** - - paths: - - "Sources/**" - - "Samples/iOS-Swift/**" - - ".github/workflows/testflight.yml" - - "fastlane/**" - - "scripts/ci-select-xcode.sh" - - pull_request: - paths: - - ".github/workflows/testflight.yml" - workflow_dispatch: - -jobs: - upload_to_testflight: - name: Build and Upload iOS-Swift to Testflight - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - run: ./scripts/ci-select-xcode.sh 16.4 - - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true - - - run: make init-ci-build - - run: make xcode-ci - - # We upload a new version to TestFlight on every commit on main - # So we need to bump the build number each time - - name: Bump Build Version - env: - FASTLANE_BUILD_NUMBER: ${{ github.run_number }} - run: bundle exec fastlane bump_build_number - - - name: Remove preview version suffixes - run: bundle exec fastlane remove_preview_version_suffixes - - - name: Run Fastlane - env: - APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} - APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} - APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} - FASTLANE_BUNDLE_VERSION: ${{ github.run_number }} - FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} - MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - run: | - bundle exec fastlane build_ios_swift - bundle exec fastlane ios_swift_to_testflight - - - name: Archiving - uses: actions/upload-artifact@v4 - with: - name: dSYMs - path: | - ${{ github.workspace }}/iOS-Swift.* - ${{ github.workspace }}/*.dSYM.zip - ${{ github.workspace }}/dSYMs/ diff --git a/.github/workflows/ui-tests-common.yml b/.github/workflows/ui-tests-common.yml deleted file mode 100644 index 736fe4e9faa..00000000000 --- a/.github/workflows/ui-tests-common.yml +++ /dev/null @@ -1,150 +0,0 @@ -name: UI Tests Common - -on: - workflow_call: - inputs: - fastlane_command: - description: "The fastlane command to run" - required: true - type: string - fastlane_command_extra_arguments: - description: "Extra arguments for the fastlane command" - required: false - default: "" - type: string - files_suffix: - description: "Suffix for the files to upload" - required: false - default: "" - type: string - xcode_version: - description: "Xcode version" - required: true - type: string - build_with_make: - description: "Build with make" - required: false - default: false - type: boolean - macos_version: - description: "macOS version" - required: true - type: string - needs_xcframework: - description: "Whether the workflow needs to download the XCFramework." - required: false - default: false - type: boolean - codecov_test_analytics: - description: "Whether or not to push results to Codecov for analytics." - required: false - default: false - type: boolean - secrets: - CODECOV_TOKEN: - required: true - -jobs: - common-ui-tests: - name: UI Tests Common - runs-on: ${{ inputs.macos_version }} - steps: - - uses: actions/checkout@v4 - - - name: Print hardware info - shell: bash - run: system_profiler SPHardwareDataType - - - name: Print available disk space - shell: bash - run: df -h - - - name: Setup Ruby - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0 - with: - bundler-cache: true - - - name: Select Xcode version - run: ./scripts/ci-select-xcode.sh "$XCODE_VERSION" - env: - XCODE_VERSION: ${{ inputs.xcode_version }} - - - run: make init-ci-build - if: ${{ inputs.build_with_make }} - - - run: make xcode-ci - if: ${{ inputs.build_with_make }} - - - name: Add Microphone permissions - uses: ./.github/actions/add-microphone-permissions - - - name: Download XCFramework - if: ${{ inputs.needs_xcframework }} - uses: actions/download-artifact@v4 - with: - name: xcframework-${{github.sha}}-sentry-static - path: Carthage/ - - - name: Unzip XCFramework - if: ${{ inputs.needs_xcframework }} - run: | - unzip -o Carthage/Sentry.xcframework.zip -d Carthage/ - - - name: Run Fastlane - env: - FASTLANE_COMMAND: ${{ inputs.fastlane_command }} - FASTLANE_EXTRA_ARGS: ${{ inputs.fastlane_command_extra_arguments }} - run: | - if [ -n "$FASTLANE_EXTRA_ARGS" ]; then - bundle exec fastlane "$FASTLANE_COMMAND" "$FASTLANE_EXTRA_ARGS" - else - bundle exec fastlane "$FASTLANE_COMMAND" - fi - - - name: Publish Test Report - uses: mikepenz/action-junit-report@3585e9575db828022551b4231f165eb59a0e74e3 # v5.6.2 - if: always() - with: - report_paths: build/reports/*junit.xml - fail_on_failure: true - fail_on_parse_error: true - detailed_summary: true - - - name: Codecov test analytics - if: ${{ !cancelled() && inputs.codecov_test_analytics }} - uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # pin@v1.1.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - name: sentry-cocoa-unit-tests - - - name: Upload Result Bundle - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }} - path: | - fastlane/test_results/**/*.xcresult - - - name: Upload iOS Simulator Crash Logs - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }}_crash_logs - path: | - ~/Library/Logs/DiagnosticReports/** - - - name: Archiving Raw Test Logs - uses: actions/upload-artifact@v4 - if: ${{ failure() || cancelled() }} - with: - name: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }}_raw_output - path: | - ~/Library/Logs/scan/*.log - ./fastlane/test_output/** - - - name: Store screenshot - uses: ./.github/actions/capture-screenshot - if: failure() - with: - suffix: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }} diff --git a/.github/workflows/ui-tests-critical.yml b/.github/workflows/ui-tests-critical.yml deleted file mode 100644 index d0dd557db02..00000000000 --- a/.github/workflows/ui-tests-critical.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: UI Tests Critical -on: - push: - branches: - - main - - pull_request: - paths: - - "Sources/**" - - ".github/workflows/ui-tests-critical.yml" - - ".github/workflows/ui-tests-common.yml" - - "fastlane/**" - - "TestSamples/**" - - "**/*.xctestplan" - # Explicitly list used scripts to avoid unnecessary runs - - "scripts/ci-boot-simulator.sh" - - "scripts/ci-select-xcode.sh" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - run-tests: - name: Test iOS on Xcode ${{matrix.platform.xcode}} - ${{ matrix.command.fastlane_command }} - V4 # Up the version with every change to keep track of flaky tests - uses: ./.github/workflows/ui-tests-common.yml - with: - fastlane_command: ${{ matrix.command.fastlane_command }} - build_with_make: true - xcode_version: ${{matrix.platform.xcode}} - macos_version: ${{matrix.platform.runs-on}} - files_suffix: _${{matrix.platform.xcode}} - strategy: - fail-fast: false - matrix: - platform: - # As of 25th March 2025, the preinstalled iOS simulator version is 16.4 for macOS 13 and Xcode 14.3.1; see - # https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md#installed-sdks - - runs-on: macos-13 - xcode: "14.3.1" - - # macos-14 iOS 17 not included due to the XCUIServerNotFound errors causing flaky tests - - # As of 25th March 2025, the preinstalled iOS simulator version is 18.2 for macOS 15 and Xcode 16.2; see - # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md#installed-sdks - - runs-on: macos-15 - xcode: "16.2" - command: - - fastlane_command: ui_critical_tests_ios_swiftui_envelope - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - run-swiftui-crash-test: - name: Run SwiftUI Crash Test - runs-on: macos-15 - timeout-minutes: 15 - steps: - - uses: actions/checkout@v4 - - - run: ./scripts/ci-select-xcode.sh 16.4 - - - run: make init-ci-build - - run: make xcode-ci - - - name: Boot simulator - run: ./scripts/ci-boot-simulator.sh - - - name: Run SwiftUI Crash Test - run: | - ./TestSamples/SwiftUICrashTest/test-crash-and-relaunch.sh --screenshots-dir "swiftui-crash-test-screenshots" - - - name: Upload SwiftUI Crash Test Screenshots - uses: actions/upload-artifact@v4 - if: always() - with: - name: swiftui-crash-test-screenshots - path: swiftui-crash-test-screenshots diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml deleted file mode 100644 index 8e88d37a7af..00000000000 --- a/.github/workflows/ui-tests.yml +++ /dev/null @@ -1,99 +0,0 @@ -name: UI Tests -on: - push: - branches: - - main - - pull_request: - paths: - - "Sources/**" - - "Tests/**" - - ".github/workflows/ui-tests.yml" - - ".github/workflows/ui-tests-common.yml" - - "fastlane/**" - - ".sauce/config.yml" - - "scripts/ci-select-xcode.sh" - - "**/*.xctestplan" - - "Samples/iOS-SwiftUI/**" - - "Samples/iOS-Swift/**" - - "Samples/iOS-Swift6/**" - - "Samples/SentrySampleShared/**" - - "Samples/Shared/**" - - "scripts/build-xcframework-slice.sh" - - "scripts/assemble-xcframework.sh" - - ".github/workflows/build-xcframework-variant-slices.yml" - - ".github/workflows/assemble-xcframework-variant.yml" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - ui-tests: - name: UI Tests for ${{matrix.target}} - V3 # Up the version with every change to keep track of flaky tests - uses: ./.github/workflows/ui-tests-common.yml - strategy: - matrix: - target: ["ios_objc", "tvos_swift"] - with: - fastlane_command: ui_tests_${{matrix.target}} - xcode_version: 16.2 - build_with_make: true - macos_version: macos-14 - codecov_test_analytics: true - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - # SwiftUI only supports iOS 14+ so we run it in a separate matrix here - ui-tests-swift-ui: - name: UI Tests for SwiftUI - V4 # Up the version with every change to keep track of flaky tests - uses: ./.github/workflows/ui-tests-common.yml - with: - fastlane_command: ui_tests_ios_swiftui - xcode_version: 16.4 - build_with_make: true - macos_version: macos-15 - fastlane_command_extra_arguments: device:iPhone 16 (18.5) - codecov_test_analytics: true - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - ui-tests-swift: - name: UI Tests for iOS-Swift Xcode ${{matrix.xcode}} - V5 # Up the version with every change to keep track of flaky tests - uses: ./.github/workflows/ui-tests-common.yml - strategy: - fail-fast: false - matrix: - include: - - runs-on: macos-13 - xcode: "14.3.1" - device: iPhone 14 (16.4) - - runs-on: macos-14 - xcode: "15.4" - device: iPhone 15 (17.5) - - runs-on: macos-15 - xcode: "16.4" - device: iPhone 16 (18.5) - with: - fastlane_command: ui_tests_ios_swift - fastlane_command_extra_arguments: device:${{matrix.device}} - files_suffix: _xcode_${{matrix.xcode}}-${{matrix.device}} - xcode_version: ${{matrix.xcode}} - build_with_make: true - macos_version: ${{matrix.runs-on}} - codecov_test_analytics: true - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - ui-tests-swift6: - name: UI Tests for iOS-Swift6 - V3 # Up the version with every change to keep track of flaky tests - uses: ./.github/workflows/ui-tests-common.yml - with: - fastlane_command: ui_tests_ios_swift6 - xcode_version: 16.2 - build_with_make: true - macos_version: macos-15 - codecov_test_analytics: true - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/version-bump-util.yml b/.github/workflows/version-bump-util.yml deleted file mode 100644 index 71c94ae5353..00000000000 --- a/.github/workflows/version-bump-util.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Test Version Bump Util - -on: - push: - branches: - - main - - pull_request: - paths: - - "Utils/VersionBump/**" - - ".github/workflows/version-bump-util.yml" - - "./Sentry.podspec" - - "./Package.swift" - - "./SentryPrivate.podspec" - - "./SentrySwiftUI.podspec" - - "./Sources/Sentry/SentryMeta.m" - - "./Tests/HybridSDKTest/HybridPod.podspec" - - "./Sources/Configuration/SDK.xcconfig" - - "./Sources/Configuration/Versioning.xcconfig" - - "./Sources/Configuration/SentrySwiftUI.xcconfig" - - "./Samples/Shared/Config/Versioning.xcconfig" - - "./scripts/bump.sh" - -jobs: - run-version-bump: - # The release workflow uses the Makefile to bump the version so it needs to be tested. - name: Run Version Bump (Makefile) - # We intentionally run this on ubuntu because the release workflow also runs on ubuntu, which uses the version bump util. - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Generate Version Number - id: generate-version-number - run: | - TIMESTAMP=$(date +%Y%m%d%H%M%S) - echo "VERSION=100.0.$TIMESTAMP" >> $GITHUB_OUTPUT - # We don't care which version we bump to, as long as it's a valid semver - - run: make bump-version TO=${{ steps.generate-version-number.outputs.VERSION }} - - run: make verify-version TO=${{ steps.generate-version-number.outputs.VERSION }} - - run-version-bump-script: - # Craft uses the shell script to bump the version so it needs to be tested. - name: Run Version Bump (Shell Script) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Generate Version Number - id: generate-version-number - run: | - OLD_VERSION=$(cat ./Sources/Configuration/Versioning.xcconfig | grep MARKETING_VERSION | cut -d '=' -f 2 | tr -d ' ') - echo "Read old version: ${OLD_VERSION}" - echo "OLD_VERSION=${OLD_VERSION}" >> $GITHUB_OUTPUT - - NEW_VERSION="100.0.$(date +%Y%m%d%H%M%S)" - echo "Generated new version: ${NEW_VERSION}" - echo "NEW_VERSION=${NEW_VERSION}" >> $GITHUB_OUTPUT - - - name: Verify OLD_VERSION is defined - if: ${{ steps.generate-version-number.outputs.OLD_VERSION == '' }} - run: | - echo "OLD_VERSION is not defined. Make sure this script is reading the version from the correct file." - exit 1 - - - name: Create fake xcframework for update-package-sha.sh - run: | - mkdir -p Carthage - echo "" > Carthage/Sentry.xcframework.zip - echo "" > Carthage/Sentry-Dynamic.xcframework.zip - - - name: Bump version - run: ./scripts/bump.sh ${{ steps.generate-version-number.outputs.OLD_VERSION }} ${{ steps.generate-version-number.outputs.NEW_VERSION }} - - - name: Verify outputs of bump.sh - run: make verify-version TO=${{ steps.generate-version-number.outputs.NEW_VERSION }} - - - name: Verify outputs of update-package-sha.sh - run: | - ./scripts/verify-package-sha.sh \ - --static-checksum "7062a80f8a80f8b6d812698af87384751567a6aaa0df6f03b0596d728b22dcfd" \ - --dynamic-checksum "f6325cd8f05523d60222451fa61b3cd3d58148e5a21236f82abfd3f92750c87c" \ - --last-release-runid "${{ github.run_id }}" From 238b705f8a707f85b5c6200363821e8f443033b8 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:12:07 -0300 Subject: [PATCH 3/9] Restore file --- .github/workflows/ui-tests-common.yml | 150 ++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 .github/workflows/ui-tests-common.yml diff --git a/.github/workflows/ui-tests-common.yml b/.github/workflows/ui-tests-common.yml new file mode 100644 index 00000000000..736fe4e9faa --- /dev/null +++ b/.github/workflows/ui-tests-common.yml @@ -0,0 +1,150 @@ +name: UI Tests Common + +on: + workflow_call: + inputs: + fastlane_command: + description: "The fastlane command to run" + required: true + type: string + fastlane_command_extra_arguments: + description: "Extra arguments for the fastlane command" + required: false + default: "" + type: string + files_suffix: + description: "Suffix for the files to upload" + required: false + default: "" + type: string + xcode_version: + description: "Xcode version" + required: true + type: string + build_with_make: + description: "Build with make" + required: false + default: false + type: boolean + macos_version: + description: "macOS version" + required: true + type: string + needs_xcframework: + description: "Whether the workflow needs to download the XCFramework." + required: false + default: false + type: boolean + codecov_test_analytics: + description: "Whether or not to push results to Codecov for analytics." + required: false + default: false + type: boolean + secrets: + CODECOV_TOKEN: + required: true + +jobs: + common-ui-tests: + name: UI Tests Common + runs-on: ${{ inputs.macos_version }} + steps: + - uses: actions/checkout@v4 + + - name: Print hardware info + shell: bash + run: system_profiler SPHardwareDataType + + - name: Print available disk space + shell: bash + run: df -h + + - name: Setup Ruby + uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0 + with: + bundler-cache: true + + - name: Select Xcode version + run: ./scripts/ci-select-xcode.sh "$XCODE_VERSION" + env: + XCODE_VERSION: ${{ inputs.xcode_version }} + + - run: make init-ci-build + if: ${{ inputs.build_with_make }} + + - run: make xcode-ci + if: ${{ inputs.build_with_make }} + + - name: Add Microphone permissions + uses: ./.github/actions/add-microphone-permissions + + - name: Download XCFramework + if: ${{ inputs.needs_xcframework }} + uses: actions/download-artifact@v4 + with: + name: xcframework-${{github.sha}}-sentry-static + path: Carthage/ + + - name: Unzip XCFramework + if: ${{ inputs.needs_xcframework }} + run: | + unzip -o Carthage/Sentry.xcframework.zip -d Carthage/ + + - name: Run Fastlane + env: + FASTLANE_COMMAND: ${{ inputs.fastlane_command }} + FASTLANE_EXTRA_ARGS: ${{ inputs.fastlane_command_extra_arguments }} + run: | + if [ -n "$FASTLANE_EXTRA_ARGS" ]; then + bundle exec fastlane "$FASTLANE_COMMAND" "$FASTLANE_EXTRA_ARGS" + else + bundle exec fastlane "$FASTLANE_COMMAND" + fi + + - name: Publish Test Report + uses: mikepenz/action-junit-report@3585e9575db828022551b4231f165eb59a0e74e3 # v5.6.2 + if: always() + with: + report_paths: build/reports/*junit.xml + fail_on_failure: true + fail_on_parse_error: true + detailed_summary: true + + - name: Codecov test analytics + if: ${{ !cancelled() && inputs.codecov_test_analytics }} + uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # pin@v1.1.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + name: sentry-cocoa-unit-tests + + - name: Upload Result Bundle + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }} + path: | + fastlane/test_results/**/*.xcresult + + - name: Upload iOS Simulator Crash Logs + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }}_crash_logs + path: | + ~/Library/Logs/DiagnosticReports/** + + - name: Archiving Raw Test Logs + uses: actions/upload-artifact@v4 + if: ${{ failure() || cancelled() }} + with: + name: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }}_raw_output + path: | + ~/Library/Logs/scan/*.log + ./fastlane/test_output/** + + - name: Store screenshot + uses: ./.github/actions/capture-screenshot + if: failure() + with: + suffix: ${{ inputs.fastlane_command }}${{ inputs.files_suffix }} From e4accffde411c0f71ad2705ee264d6e58c2f44a1 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:12:42 -0300 Subject: [PATCH 4/9] Restore file --- .../build-xcframework-variant-slices.yml | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 .github/workflows/build-xcframework-variant-slices.yml diff --git a/.github/workflows/build-xcframework-variant-slices.yml b/.github/workflows/build-xcframework-variant-slices.yml new file mode 100644 index 00000000000..5f7fc21c2ee --- /dev/null +++ b/.github/workflows/build-xcframework-variant-slices.yml @@ -0,0 +1,146 @@ +name: "Build Sentry Cocoa XCFramework variant slices" + +on: + workflow_call: + inputs: + sdk-list: + description: |- + The list of Apple platform SDKs for which to build slices and assemble into an XCFramework. This must be a JSON array of strings, itself in a string since GitHub Actions doesn't support arrays as inputs. + Possible values: iphoneos, iphonesimulator, macosx, appletvos, appletvsimulator, watchos, watchsimulator, xros, xrsimulator. + required: false + default: '["iphoneos", "iphonesimulator", "macosx", "maccatalyst", "appletvos", "appletvsimulator", "watchos", "watchsimulator", "xros", "xrsimulator"]' + type: string + + name: + description: |- + The Sentry project target to build an XCFramework slice for. + Possible values: Sentry, SentrySwiftUI. + required: true + type: string + + suffix: + description: |- + The suffix to add to the build product name. + E.g. "-Dynamic" or "-WithoutUIKitOrAppKit". + required: false + type: string + + macho-type: + description: |- + The Mach-O type of the build product. + Possible values: mh_dylib, staticlib. + required: false + type: string + default: "mh_dylib" + + configuration-suffix: + description: |- + The suffix to add to the build product name to build an alternate configuration of the target. + E.g. "WithoutUIKit". + required: false + type: string + + variant-id: + description: |- + The ID of the variant to build an XCFramework slice for. Used to collect appropriate slices for final deliverable assembly. + required: true + type: string + + release-version: + description: |- + For release workflows, the version to inject into the SDK. + required: false + type: string + +jobs: + build-xcframework-variant-slices: + name: ${{matrix.sdk}} + + # We must compile this on an arm64 runner, cause it's required for visionOS. macos-14 uses arm64. + # To see the available runners see https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories. + runs-on: macos-14 + + strategy: + matrix: + sdk: ${{ fromJson(inputs.sdk-list) }} + + steps: + - uses: actions/checkout@v4 + + # We have to compile on Xcode 15.2 because compiling on Xcode 15.4 fails with + # Data+SentryTracing.swift:21:62: error: 'ReadingOptions' aliases 'Foundation.ReadingOptions' + # and cannot be used here because C++ types from imported module 'Foundation' do not support + # library evolution; this is an error in the Swift 6 language mode + # We also can't use Xcode 16.x because validating the XCFramework then fails with Xcode 15.x. + - run: ./scripts/ci-select-xcode.sh 15.2 + shell: bash + + - name: Get version + id: get-version + run: | + if [ -n "${{ inputs.release-version }}" ]; then + echo "VERSION=${{ inputs.release-version }}" >> $GITHUB_ENV + else + echo "VERSION=$(grep MARKETING_VERSION Sources/Configuration/Versioning.xcconfig | cut -d ' ' -f 3)+${{ github.sha }}" >> $GITHUB_ENV + fi + shell: sh + + - name: Compute cache key + run: | + echo "SENTRY_XCFRAMEWORK_CACHE_KEY=${{ runner.os }}-xcframework-${{inputs.variant-id}}-slice-${{matrix.sdk}}-${{ env.VERSION }}-${{hashFiles('Sources/**')}}-${{hashFiles('Sentry.xcodeproj/**')}}" >> $GITHUB_ENV + + - name: Restore xcarchive cache + id: cache-xcarchive + uses: actions/cache@v4 + with: + key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} + path: ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip + + - name: Bump version + if: steps.cache-xcarchive.outputs.cache-hit != 'true' + run: | + ./scripts/ci-select-xcode.sh 15.2 + make bump-version TO=${{ env.VERSION }} + + - name: Build ${{inputs.name}}${{inputs.suffix}} XCFramework slice for ${{matrix.sdk}} + if: steps.cache-xcarchive.outputs.cache-hit != 'true' + run: ./scripts/build-xcframework-slice.sh ${{matrix.sdk}} ${{inputs.name}} "${{inputs.suffix}}" "${{inputs.macho-type}}" "${{inputs.configuration-suffix}}" + shell: bash + + # The SentrySwiftUI archive build also builds Sentry.framework as a byproduct of the dependency. We need to remove that to avoid downstream assembly tasks from tripping on these extra files. In the future we could investigate using this byproduct instead of running a separate task for Sentry.framework, or use the one already built by that other task instead of rebuilding it here. + - name: Remove Sentry.framework from SentrySwiftUI build + if: steps.cache-xcarchive.outputs.cache-hit != 'true' && inputs.name == 'SentrySwiftUI' + run: | + find "${{github.workspace}}/Carthage/archive" -name "Sentry.framework" -print0 | xargs -t0 rm -rf + find "${{github.workspace}}/Carthage/archive" -name "Sentry.framework.dSYM" -print0 | xargs -t0 rm -rf + shell: bash + + # the upload action broke symlinks in the mac sdk slice's xcarchive + - name: Zip xcarchive + if: steps.cache-xcarchive.outputs.cache-hit != 'true' + run: | + ditto -c -k -X --rsrc --keepParent ${{github.workspace}}/Carthage/archive/${{inputs.name}}${{inputs.suffix}}/${{matrix.sdk}}.xcarchive ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip + shell: bash + + - name: Cache xcarchive + if: steps.cache-xcarchive.outputs.cache-hit != 'true' + uses: actions/cache@v4 + with: + key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} + path: ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip + + - name: Upload xcarchive + uses: actions/upload-artifact@v4 + with: + name: xcframework-${{inputs.variant-id}}-slice-${{matrix.sdk}} + if-no-files-found: error + path: | + ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip + + - name: Upload build log if failed + uses: actions/upload-artifact@v4 + if: ${{ failure() || cancelled() }} + with: + name: raw-build-output-build-xcframework-${{inputs.variant-id}}-${{matrix.sdk}} + path: | + *.log From 38d304a101d2ed3cf310e67bf56dc82dfae68eaa Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:13:10 -0300 Subject: [PATCH 5/9] Restore file --- .../assemble-xcframework-variant.yml | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 .github/workflows/assemble-xcframework-variant.yml diff --git a/.github/workflows/assemble-xcframework-variant.yml b/.github/workflows/assemble-xcframework-variant.yml new file mode 100644 index 00000000000..8336b99df85 --- /dev/null +++ b/.github/workflows/assemble-xcframework-variant.yml @@ -0,0 +1,137 @@ +name: "Assemble Sentry Cocoa XCFramework variant" + +on: + workflow_call: + inputs: + name: + description: |- + The Sentry project target to build an XCFramework slice for. + Possible values: Sentry, SentrySwiftUI. + required: true + type: string + + suffix: + description: |- + The suffix to add to the build product name. + E.g. "-Dynamic" or "-WithoutUIKitOrAppKit". + required: false + type: string + + configuration-suffix: + description: |- + The suffix to add to the build product name to build an alternate configuration of the target. + E.g. "WithoutUIKit". + required: false + type: string + + variant-id: + description: |- + The ID of the variant to build an XCFramework slice for. Used to collect appropriate slices for final deliverable assembly. + E.g. "sentry-static", "sentry-dynamic" or "sentry-withoutuikit-dynamic" + required: true + type: string + + signed: + description: |- + Whether or not the assembled XCFramework should be signed. + required: false + type: boolean + default: false + + sdks: + description: |- + The SDK slices to assemble into an XCFramework. + required: false + type: string + default: "iphoneos,iphonesimulator,macosx,maccatalyst,appletvos,appletvsimulator,watchos,watchsimulator,xros,xrsimulator" + + release-version: + description: |- + For release workflows, the version to inject into the SDK. + required: false + type: string + +jobs: + assemble-xcframework-variant: + name: Assemble ${{inputs.name}}${{inputs.suffix}} XCFramework Variant + + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + + - uses: ruby/setup-ruby@v1 + if: ${{ inputs.signed }} + with: + bundler-cache: true + + - name: "Download Fastlane Certificate" + if: ${{ inputs.signed }} + run: bundle exec fastlane prepare_xcframework_signing + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} + FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} + MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} + + - name: Get version + id: get-version + run: | + if [ -n "${{ inputs.release-version }}" ]; then + echo "VERSION=${{ inputs.release-version }}" >> $GITHUB_ENV + else + echo "VERSION=$(grep MARKETING_VERSION Sources/Configuration/Versioning.xcconfig | cut -d ' ' -f 3)+${{ github.sha }}" >> $GITHUB_ENV + fi + shell: sh + + - name: Compute cache key + run: | + sdks_string=${{inputs.sdks}} + sdks_string_slugified=${sdks_string//,/_} + echo "SENTRY_XCFRAMEWORK_CACHE_KEY=${{runner.os}}-xcframework-${{inputs.variant-id}}-$sdks_string_slugified-${{inputs.signed}}-${{env.VERSION}}-${{hashFiles('Sources/**')}}-${{hashFiles('Sentry.xcodeproj/**')}}" >> $GITHUB_ENV + + - name: Restore XCFramework cache + id: cache-xcframework + uses: actions/cache@v4 + with: + key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} + path: ${{inputs.name}}${{inputs.suffix}}.xcframework.zip + + - name: Download ${{inputs.variant-id}} Slices + if: steps.cache-xcframework.outputs.cache-hit != 'true' + uses: actions/download-artifact@v4 + with: + pattern: xcframework-${{inputs.variant-id}}-slice-* + path: xcframework-slices + + - name: Unzip slice artifact ZIP archives + if: steps.cache-xcframework.outputs.cache-hit != 'true' + run: | + find xcframework-slices -type f -print0 | xargs -t0I @ unzip @ -d xcframework-slices + shell: bash + + - name: Assemble XCFramework + if: steps.cache-xcframework.outputs.cache-hit != 'true' + run: ./scripts/assemble-xcframework.sh "${{inputs.name}}" "${{inputs.suffix}}" "${{inputs.configuration-suffix}}" "${{inputs.sdks}}" "/Users/runner/work/sentry-cocoa/sentry-cocoa/xcframework-slices/SDK_NAME.xcarchive" + shell: bash + + - name: Zip XCFramework + if: steps.cache-xcframework.outputs.cache-hit != 'true' + run: ./scripts/compress-xcframework.sh ${{inputs.signed && '--sign' || '--not-signed'}} ${{inputs.name}}${{inputs.suffix}} + shell: bash + + - name: Cache XCFramework + uses: actions/cache@v4 + with: + key: ${{env.SENTRY_XCFRAMEWORK_CACHE_KEY}} + path: ${{inputs.name}}${{inputs.suffix}}.xcframework.zip + + - name: Upload XCFramework + uses: actions/upload-artifact@v4 + with: + overwrite: true + name: xcframework-${{github.sha}}-${{inputs.variant-id}} + if-no-files-found: error + path: ${{inputs.name}}${{inputs.suffix}}.xcframework.zip From a33b86b01c06bcc4da37208d2a2967ebe1e700b7 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:27:34 -0300 Subject: [PATCH 6/9] Use Xcode 15.4 --- .github/workflows/build-xcframework-variant-slices.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-xcframework-variant-slices.yml b/.github/workflows/build-xcframework-variant-slices.yml index 5f7fc21c2ee..9125804c35b 100644 --- a/.github/workflows/build-xcframework-variant-slices.yml +++ b/.github/workflows/build-xcframework-variant-slices.yml @@ -67,12 +67,8 @@ jobs: steps: - uses: actions/checkout@v4 - # We have to compile on Xcode 15.2 because compiling on Xcode 15.4 fails with - # Data+SentryTracing.swift:21:62: error: 'ReadingOptions' aliases 'Foundation.ReadingOptions' - # and cannot be used here because C++ types from imported module 'Foundation' do not support - # library evolution; this is an error in the Swift 6 language mode - # We also can't use Xcode 16.x because validating the XCFramework then fails with Xcode 15.x. - - run: ./scripts/ci-select-xcode.sh 15.2 + # We can't use Xcode 16.x because validating the XCFramework then fails with Xcode 15.x. + - run: ./scripts/ci-select-xcode.sh 15.4 shell: bash - name: Get version From 4e5ee7891a0639036a9e27947a8d91c6f282800c Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:40:02 -0300 Subject: [PATCH 7/9] Restore pending tests --- .github/workflows/api-stability.yml | 55 ++++ .github/workflows/auto-update-tools.yml | 91 ++++++ .github/workflows/benchmarking.yml | 173 +++++++++++ .github/workflows/build.yml | 228 ++++++++++++++ .../workflows/changes-in-high-risk-code.yml | 75 +++++ .github/workflows/codeql-analysis.yml | 47 +++ .github/workflows/danger.yml | 9 + .github/workflows/integration-test.yml | 46 +++ .github/workflows/lint-clang-formatting.yml | 50 ++++ .github/workflows/lint-dprint.yml | 29 ++ .github/workflows/lint-shellcheck.yml | 25 ++ .github/workflows/lint-swift-formatting.yml | 39 +++ .github/workflows/lint.yml | 76 +++++ .../workflows/objc-conversion-analysis.yml | 58 ++++ .github/workflows/release-comment-issues.yml | 33 ++ .../workflows/release-upload-xcframework.yml | 47 +++ .github/workflows/test-cross-platform.yml | 68 +++++ .github/workflows/test.yml | 281 ++++++++++++++++++ .github/workflows/testflight.yml | 66 ++++ .github/workflows/ui-tests-critical.yml | 78 +++++ .github/workflows/ui-tests.yml | 99 ++++++ .github/workflows/version-bump-util.yml | 81 +++++ 22 files changed, 1754 insertions(+) create mode 100644 .github/workflows/api-stability.yml create mode 100644 .github/workflows/auto-update-tools.yml create mode 100644 .github/workflows/benchmarking.yml create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/changes-in-high-risk-code.yml create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/danger.yml create mode 100644 .github/workflows/integration-test.yml create mode 100644 .github/workflows/lint-clang-formatting.yml create mode 100644 .github/workflows/lint-dprint.yml create mode 100644 .github/workflows/lint-shellcheck.yml create mode 100644 .github/workflows/lint-swift-formatting.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/objc-conversion-analysis.yml create mode 100644 .github/workflows/release-comment-issues.yml create mode 100644 .github/workflows/release-upload-xcframework.yml create mode 100644 .github/workflows/test-cross-platform.yml create mode 100644 .github/workflows/test.yml create mode 100644 .github/workflows/testflight.yml create mode 100644 .github/workflows/ui-tests-critical.yml create mode 100644 .github/workflows/ui-tests.yml create mode 100644 .github/workflows/version-bump-util.yml diff --git a/.github/workflows/api-stability.yml b/.github/workflows/api-stability.yml new file mode 100644 index 00000000000..45cb74c6e26 --- /dev/null +++ b/.github/workflows/api-stability.yml @@ -0,0 +1,55 @@ +name: API Stability Check + +on: + pull_request: + paths: + - "Sources/**" + - "test-server/**" + - ".github/workflows/api-stability.yml" + - Sentry.xcworkspace/** + - Sentry.xcodeproj/** + - "Package.swift" + - "scripts/build-xcframework-local.sh" + - "scripts/update-api.sh" + +jobs: + api-stability: + runs-on: macos-15 + strategy: + matrix: + version: [default, v9] + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - run: ./scripts/ci-select-xcode.sh 16.4 + + - name: Generate HEAD SDK + run: | + if [ "${{ matrix.version }}" = "v9" ]; then + mv sdk_api_v9.json sdk_api_base.json + make generate-public-api CONFIG=V9 + mv sdk_api_v9.json sdk_api.json + else + mv sdk_api.json sdk_api_base.json + make generate-public-api + fi + + - name: Diagnose breaking changes + run: | + if diff -q "sdk_api_base.json" "sdk_api.json" > /dev/null; then + echo "No API changes detected for ${{ matrix.version }} version." + else + echo "❌ Public API changes are detected for ${{ matrix.version }} version. If they're intended run "make generate-public-api" and commit the changes." + diff "sdk_api_base.json" "sdk_api.json" || true + xcrun --sdk iphoneos swift-api-digester \ + -diagnose-sdk \ + -o result.json \ + -input-paths sdk_api_base.json \ + -input-paths sdk_api.json \ + -json \ + -v + cat result.json + exit 1 + fi diff --git a/.github/workflows/auto-update-tools.yml b/.github/workflows/auto-update-tools.yml new file mode 100644 index 00000000000..141d4ad99ba --- /dev/null +++ b/.github/workflows/auto-update-tools.yml @@ -0,0 +1,91 @@ +# This workflow is used to update the custom tooling versions for the project. +# +# We prefer to use Dependabot to update external dependencies, but at this time it does not include Homebrew as a supported package manager (https://docs.github.com/en/code-security/dependabot/ecosystems-supported-by-dependabot/supported-ecosystems-and-repositories). +# Furthermore, neither `swiftlint` nor `clang-format` are listed as dependencies in our repository, therefore also not picked up by Dependabot. +# +# Therefore we are using a custom workflow to update relevant files and open a pull request with the changes. + +name: "Automation: Update tooling versions" + +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + pull_request: + paths: + - ".github/workflows/auto-update-tools.yml" + - "Brewfile*" + - "Makefile" + - "scripts/.clang-format-version" + - "scripts/.swiftlint-version" + - ".pre-commit-config.yaml" + +# Permissions configuration: +# - 'contents: write' is required to allow the workflow to commit changes to the repository +# when updating the tooling version files and creating branches for pull requests. +# - 'pull-requests: write' is required to allow the workflow to create pull requests +# using the peter-evans/create-pull-request action when tooling version updates are available. +permissions: + contents: write + pull-requests: write + +# Concurrency configuration: +# - We use a named concurrency group to prevent multiple instances of this workflow from running +# simultaneously, which could lead to race conditions when creating branches and pull requests. +# Since this workflow modifies version files and creates PRs, concurrent runs could interfere +# with each other, resulting in conflicting branches or duplicate PRs. +# - We enable cancellation of in-progress runs because only the most recent run matters for +# version updates. There's no value in completing outdated runs, especially for scheduled +# workflows that might queue up overnight. This approach conserves GitHub Actions minutes +# and ensures we're always working with the latest repository state. +concurrency: + group: "auto-update-tools" + cancel-in-progress: true + +jobs: + auto-update-tools: + runs-on: macos-15 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Update Homebrew + run: brew update + + - name: Install Tools + run: make init + + - name: Update tooling versions + run: make update-versions + + - name: Check tooling versions + run: make check-versions + + - name: Print git status and changes + run: | + git status + git diff HEAD + + - name: Create pull request for clang-format version + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e #v7.0.8 + if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} + with: + add-paths: scripts/.clang-format-version + branch: github-actions/auto-update-tools-clang-format + commit-message: "chore(deps): Update clang-format version" + delete-branch: true + title: "chore(deps): Update clang-format version" + sign-commits: true + base: main + + - name: Create pull request for swiftlint version + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e #v7.0.8 + if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} + with: + add-paths: scripts/.swiftlint-version + branch: github-actions/auto-update-tools-swiftlint + commit-message: "chore(deps): Update swiftlint version" + delete-branch: true + title: "chore(deps): Update swiftlint version" + sign-commits: true + base: main diff --git a/.github/workflows/benchmarking.yml b/.github/workflows/benchmarking.yml new file mode 100644 index 00000000000..f90b9676b3d --- /dev/null +++ b/.github/workflows/benchmarking.yml @@ -0,0 +1,173 @@ +name: Benchmarking +on: + push: + branches: + - main + + pull_request: + paths: + # test changes to Sentry SDK sources + - "Sources/**" + + # test changes to benchmarking implementation + - "Samples/iOS-Swift/**" + - ".github/workflows/benchmarking.yml" + - ".sauce/benchmarking-config.yml" + - "fastlane/**" + - "scripts/ci-select-xcode.sh" + - "Samples/iOS-Swift/iOS-Swift.yml" + - "Samples/iOS-Swift/iOS-Swift.xcconfig" + - "Samples/iOS-Swift/iOS-SwiftClilp.xcconfig" + - "Samples/iOS-Swift/iOS-Benchmarking.xcconfig" + - "scripts/build-xcframework-slice.sh" + - "scripts/assemble-xcframework.sh" + - ".github/workflows/build-xcframework-variant-slices.yml" + - ".github/workflows/assemble-xcframework-variant.yml" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-benchmark-test-target: + name: Build app and test runner + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - run: ./scripts/ci-select-xcode.sh 15.2 + - uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + - run: make init-ci-build + - run: make xcode-ci + - name: Install SentryCli + run: brew install getsentry/tools/sentry-cli + - name: Cache iOS-Swift App and dSYM build products + id: ios-swift-cache + uses: actions/cache@v4 + with: + path: | + DerivedData/Build/Products/Debug-iphoneos/iOS-Swift.app.dSYM + DerivedData/Build/Products/Debug-iphoneos/iOS-Swift.app + key: ios-swift-for-ui-testing-cache-key-${{ hashFiles('Samples/iOS-Swift/**') }}-${{ hashFiles('Sources/Sentry/**') }} + - name: Cache iOS-Swift UI Test Runner App build product + id: ios-swift-benchmark-runner-cache + uses: actions/cache@v4 + with: + path: | + DerivedData/Build/Products/Debug-iphoneos/iOS-Benchmarking-Runner.app + key: ios-swift-for-ui-testing-cache-key-${{ hashFiles('Samples/iOS-Benchmarking/**') }} + - run: bundle exec fastlane build_ios_swift_for_tests + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} + FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} + MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} + - run: bundle exec fastlane build_ios_benchmark_test + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} + FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} + MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} + - name: Upload dSYMs + run: | + sentry-cli --auth-token ${{ secrets.SENTRY_AUTH_TOKEN }} upload-dif --org sentry-sdks --project sentry-cocoa DerivedData/Build/Products/Debug-iphoneos/iOS-Swift.app.dSYM + - name: Archiving DerivedData + uses: actions/upload-artifact@v4 + with: + name: DerivedData-Xcode + path: | + **/Debug-iphoneos/iOS-Swift.app + **/Debug-iphoneos/iOS-Benchmarking-Runner.app + + run-ui-tests-with-sauce: + name: Run benchmarks on Sauce Labs + runs-on: ubuntu-latest + needs: build-benchmark-test-target + strategy: + fail-fast: false + matrix: + suite: ["High-end device", "Mid-range device", "Low-end device"] + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: DerivedData-Xcode + - run: npm install -g saucectl@0.186.0 + - name: Run Benchmarks in SauceLab + id: run-benchmarks-in-sauce-lab + env: + SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} + SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} + # Note: We are not setting continue-on-error here, because we want the step to be marked as failed. + run: | + set -o pipefail && saucectl run \ + --select-suite "${{matrix.suite}}" \ + --config .sauce/benchmarking-config.yml \ + --tags benchmark \ + --verbose \ + 2>&1 | tee output.log + + - name: Recovery - Extract Test ID from output + id: should-retry-test + # Note: We need to use always() here, because the previous run step might be marked as failed. + if: ${{ always() && steps.run-benchmarks-in-sauce-lab.outcome == 'failure' }} + uses: actions/github-script@v7 + env: + SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} + SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} + with: + script: | + const fs = require('fs'); + const { execSync } = require('child_process'); + + console.log("Extracting test ID from output log"); + const outputLog = fs.readFileSync('output.log', 'utf8'); + + // Lookup for the test ID in the output log + // Note: The CLI output might change over time, so this might need to be updated. + const match = outputLog.match(/https:\/\/app\.saucelabs\.com\/tests\/([^\s]+)/); + const testId = match?.[1] ?? ''; + + if (!testId) { + core.warning("No SauceLabs test ID found in CLI output, it might have changed, retrying..."); + core.setOutput('RETRY_TEST', 'true'); + + return; + } + + try { + console.log(`Checking if the test exists in SauceLabs: ${testId}`); + execSync(`saucectl jobs get ${testId}`, { + env: process.env, + stdio: 'inherit' + }); + + console.log("Test exists but failed, not retrying."); + core.setFailed('Test exists but failed'); + } catch (error) { + console.log("Failed to get job, retrying..."); + core.setOutput('RETRY_TEST', 'true'); + } + + - name: Run Benchmarks in SauceLab - Retry 1 + id: run-benchmarks-in-sauce-lab-retry-1 + # Note: We need to use always() here, because the previous run step might be marked as failed. + if: ${{ always() && steps.should-retry-test.outputs.RETRY_TEST == 'true' }} + env: + SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} + SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} + run: | + echo "::warning SauceLabs benchmark tests need to be retried" + saucectl run \ + --select-suite "${{matrix.suite}}" \ + --config .sauce/benchmarking-config.yml \ + --tags benchmark \ + --verbose diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000000..ee4967a4ed6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,228 @@ +name: Build +on: + push: + branches: + - main + - release/** + + pull_request: + paths: + - "Sources/**" + - "test-server/**" + - "Samples/**" + - ".github/workflows/build.yml" + - "fastlane/**" + - "scripts/ci-select-xcode.sh" + - Sentry.xcworkspace/** + - Sentry.xcodeproj/** + - Gemfile.lock + - "Package.swift" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + # We had issues that the release build was broken on main. + # With this we catch potential issues already in the PR. + ios-swift-release: + name: Release Build of iOS Swift + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + - run: ./scripts/ci-select-xcode.sh 16.4 + - uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + - run: make init-ci-build + - run: make xcode-ci + - name: Run Fastlane + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} + FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} + MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} + run: bundle exec fastlane build_ios_swift + + build-sample: + name: Sample ${{ matrix.scheme }} ${{ matrix.config }} + runs-on: macos-15 + strategy: + fail-fast: false + matrix: + # other sample projects are built in ui-tests + include: + - scheme: macOS-Swift + config: Debug + - scheme: iOS13-Swift + config: Debug + - scheme: watchOS-Swift WatchKit App + config: Debug + - scheme: macOS-SwiftUI + config: Debug + - scheme: SessionReplay-CameraTest + config: Debug + - scheme: visionOS-Swift + config: Debug + - scheme: iOS-Swift + config: DebugV9 + - scheme: macOS-Swift + config: DebugV9 + - scheme: tvOS-Swift + config: DebugV9 + - scheme: visionOS-Swift + config: DebugV9 + - scheme: iOS-SwiftUI + config: DebugV9 + - scheme: iOS-ObjectiveC + config: DebugV9 + + steps: + - uses: actions/checkout@v4 + - run: ./scripts/ci-select-xcode.sh 16.4 + - run: make init-ci-build + - run: make xcode-ci + + # Note: Due to complexity in implementing the CODE_SIGNING_ALLOWED flag in the sentry-xcodebuild.sh script, + # we did not yet migrate this step to use the script yet. + - run: >- + env NSUnbufferedIO=YES + xcodebuild + -workspace Sentry.xcworkspace + -scheme '${{matrix.scheme}}' + -configuration ${{matrix.config}} + CODE_SIGNING_ALLOWED="NO" + build + + - name: Archiving Raw Build Logs + uses: actions/upload-artifact@v4 + if: ${{ failure() || cancelled() }} + with: + name: raw-build-output-scheme-${{matrix.scheme}} + path: | + raw-build-output.log + build-spm: + name: Build with SPM + runs-on: macos-15 + # Don't run this on release branches, cause the SPM Package.swift points to the unreleased versions. + if: startsWith(github.ref, 'refs/heads/release/') == false + steps: + - uses: actions/checkout@v4 + - run: rm -r Sentry.xcodeproj && rm -r Sentry.xcworkspace && EXPERIMENTAL_SPM_BUILDS=1 xcodebuild build -scheme SentrySPM -sdk watchos -destination 'generic/platform=watchOS' + shell: sh + - run: EXPERIMENTAL_SPM_BUILDS=1 xcodebuild build -scheme SentrySPM -sdk iphoneos -destination 'generic/platform=iphoneos' + shell: sh + + build-v9: + name: Build SDK v9 + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + - run: ./scripts/sentry-xcodebuild.sh --platform iOS --os latest --device "iPhone 16" --command build --configuration DebugV9 + + check-debug-without-UIKit: + name: Check no UIKit linkage (DebugWithoutUIKit) + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - name: Build for Debug + run: | + ./scripts/sentry-xcodebuild.sh \ + --platform iOS \ + --os latest \ + --ref ${{ github.ref }} \ + --command build \ + --device "iPhone 14" \ + --configuration DebugWithoutUIKit \ + --derived-data uikit-check-build + - name: Ensure UIKit is not linked + run: ./scripts/check-uikit-linkage.sh DebugWithoutUIKit uikit-check-build unlinked SentryWithoutUIKit + + check-release-without-UIKit: + name: Check no UIKit linkage (ReleaseWithoutUIKit) + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - name: Build for Release + run: | + ./scripts/sentry-xcodebuild.sh \ + --platform iOS \ + --os latest \ + --ref ${{ github.ref }} \ + --command build \ + --device "iPhone 14" \ + --configuration ReleaseWithoutUIKit \ + --derived-data uikit-check-build + - name: Ensure UIKit is not linked + run: ./scripts/check-uikit-linkage.sh ReleaseWithoutUIKit uikit-check-build unlinked SentryWithoutUIKit + + check-debug-with-UIKit: + name: Check UIKit linkage (Debug) + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - name: Build for Debug + run: | + ./scripts/sentry-xcodebuild.sh \ + --platform iOS \ + --os latest \ + --ref ${{ github.ref }} \ + --command build \ + --device "iPhone 14" \ + --configuration Debug \ + --derived-data uikit-check-build + - name: Ensure UIKit is linked + run: ./scripts/check-uikit-linkage.sh Debug uikit-check-build linked Sentry + + check-release-with-UIKit: + name: Check UIKit linkage (Release) + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - name: Build for Release + run: | + ./scripts/sentry-xcodebuild.sh \ + --platform iOS \ + --os latest \ + --ref ${{ github.ref }} \ + --command build \ + --device "iPhone 14" \ + --configuration Release \ + --derived-data uikit-check-build + - name: Ensure UIKit is linked + run: ./scripts/check-uikit-linkage.sh Release uikit-check-build linked Sentry + + # The compiler only evaluates SentryAsyncSafeLogs that get printed based on the SENTRY_ASYNC_SAFE_LOG_LEVEL. + # So if the level is set to error, which is the default, and a SENTRY_ASYNC_SAFE_LOG_DEBUG has a compiler error, + # you only get the compiler error when setting the SENTRY_ASYNC_SAFE_LOG_LEVEL to SENTRY_ASYNC_SAFE_LOG_LEVEL_DEBUG or lower. + + check-compiling-async-safe-logs: + name: Check compiling Async Safe Logs + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + # If the SentryAsyncSafeLog doesn't contain the SENTRY_ASYNC_SAFE_LOG_LEVEL_ERROR this fails. + - name: Async Safe Log Level is Error + run: grep -c "SENTRY_ASYNC_SAFE_LOG_LEVEL SENTRY_ASYNC_SAFE_LOG_LEVEL_ERROR" Sources/Sentry/SentryAsyncSafeLog.h + + - name: Set Async Safe Log Level to Debug + run: | + sed -i '' 's/#define SENTRY_ASYNC_SAFE_LOG_LEVEL SENTRY_ASYNC_SAFE_LOG_LEVEL_ERROR/#define SENTRY_ASYNC_SAFE_LOG_LEVEL SENTRY_ASYNC_SAFE_LOG_LEVEL_TRACE/' Sources/Sentry/SentryAsyncSafeLog.h + shell: bash + + - run: ./scripts/ci-select-xcode.sh 16.4 + + - name: Build for Debug + run: | + ./scripts/sentry-xcodebuild.sh \ + --platform iOS \ + --os latest \ + --ref ${{ github.ref }} \ + --command build \ + --device "iPhone 16" \ + --configuration Debug diff --git a/.github/workflows/changes-in-high-risk-code.yml b/.github/workflows/changes-in-high-risk-code.yml new file mode 100644 index 00000000000..4f8e16d95d9 --- /dev/null +++ b/.github/workflows/changes-in-high-risk-code.yml @@ -0,0 +1,75 @@ +name: Changes In High Risk Code +on: + pull_request: + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + files-changed: + name: Detect changed files + runs-on: ubuntu-latest + # Map a step output to a job output + outputs: + high_risk_code: ${{ steps.changes.outputs.high_risk_code }} + high_risk_code_files: ${{ steps.changes.outputs.high_risk_code_files }} + steps: + - uses: actions/checkout@v4 + - name: Get changed files + id: changes + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + with: + token: ${{ github.token }} + filters: .github/file-filters.yml + + # Enable listing of files matching each filter. + # Paths to files will be available in `${FILTER_NAME}_files` output variable. + list-files: csv + + validate-high-risk-code: + if: needs.files-changed.outputs.high_risk_code == 'true' + needs: files-changed + runs-on: ubuntu-latest + steps: + - name: Remove previous comments + uses: actions/github-script@v7 + with: + script: | + core.debug('Listing comments') + const response = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }) + if (!response.data) { + core.info('No comments found') + return + } + core.debug(`Found ${response.data.length} comments`) + for (const comment of response.data) { + if (comment.user.login === 'github-actions[bot]' && comment.body.includes('### 🚨 Detected changes in high risk code 🚨')) { + core.info(`Deleting comment ${comment.id}`) + await github.rest.issues.deleteComment({ + comment_id: comment.id, + owner: context.repo.owner, + repo: context.repo.repo, + }) + } + } + - name: Comment on PR to notify of changes in high risk files + uses: actions/github-script@v7 + env: + high_risk_code: ${{ needs.files-changed.outputs.high_risk_code_files }} + with: + script: | + const highRiskFiles = process.env.high_risk_code; + const fileList = highRiskFiles.split(',').map(file => `- [ ] ${file}`).join('\n'); + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `### 🚨 Detected changes in high risk code 🚨 \n High-risk code can easily blow up and is hard to test. We had severe bugs in the past. Be extra careful when changing these files, and have an extra careful look at these:\n ${fileList}` + }) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..e22f4b94738 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,47 @@ +name: "CodeQL" + +on: + push: + branches: [main] + pull_request: + branches: + - main + schedule: + - cron: "40 4 * * 6" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + analyze: + name: Analyze + runs-on: macos-13 + + strategy: + fail-fast: false + matrix: + language: ["cpp"] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - run: | + set -o pipefail && NSUnbufferedIO=YES xcodebuild \ + -workspace Sentry.xcworkspace \ + -scheme Sentry \ + -configuration Release \ + -destination platform="iOS Simulator,OS=latest,name=iPhone 14 Pro" \ + build 2>&1 | + tee raw-analyze-output.log | + xcbeautify + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml new file mode 100644 index 00000000000..000b75ff3ee --- /dev/null +++ b/.github/workflows/danger.yml @@ -0,0 +1,9 @@ +name: Danger + +on: + pull_request: + types: [opened, synchronize, reopened, edited, ready_for_review] + +jobs: + danger: + uses: getsentry/github-workflows/.github/workflows/danger.yml@v2 diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml new file mode 100644 index 00000000000..79ab0045907 --- /dev/null +++ b/.github/workflows/integration-test.yml @@ -0,0 +1,46 @@ +name: CocoaPods Integration Tests +on: + push: + branches: + - main + + pull_request: + paths: + - ".github/workflows/integration-test.yml" + - "*.xcodeproj" + - "*.xcworkspace" + - "Samples/iOS-Cocoapods-*/**" + - "scripts/ci-select-xcode.sh" + - "Sources/**" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + cocoapods: + name: Integration Test + runs-on: macos-15 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Select Xcode + run: ./scripts/ci-select-xcode.sh 16.4 + + - name: Setup Ruby + uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0 + with: + bundler-cache: true + + - name: Run Integration Test + run: bundle exec fastlane cocoapods_integration_test + working-directory: Samples/iOS-Cocoapods-Swift6 + + - name: Upload Result Bundle + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: integration-test-iOS-Cocoapods-Swift6.xcresult + path: Samples/iOS-Cocoapods-Swift6/fastlane/test_results/results.xcresult diff --git a/.github/workflows/lint-clang-formatting.yml b/.github/workflows/lint-clang-formatting.yml new file mode 100644 index 00000000000..e9315874bac --- /dev/null +++ b/.github/workflows/lint-clang-formatting.yml @@ -0,0 +1,50 @@ +name: Check Code Formatting +on: + push: + branches: + - main + paths: + - "**/*.h" + - "**/*.hpp" + - "**/*.c" + - "**/*.cpp" + - "**/*.m" + - "**/*.mm" + - ".github/workflows/lint-clang-formatting.yml" + - ".clang-format" + + pull_request: + paths: + - "**/*.h" + - "**/*.hpp" + - "**/*.c" + - "**/*.cpp" + - "**/*.m" + - "**/*.mm" + - ".github/workflows/lint-clang-formatting.yml" + - ".clang-format" + +jobs: + format-code: + # While ubuntu runners have clang-format preinstalled, they use an older version. We want to use the most recent one, + # that we can easily install locally via brew. + name: Check Formatting of Clang Format + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + - name: Install tooling + run: make init-ci-format + + - name: Format with Clang + run: make format-clang + + - name: Check for Formatting Changes + run: | + if [[ -n "$(git status --porcelain)" ]]; then + echo "❌ Some code formatted with clang-format is not formatted correctly. Please run 'make format' and commit the changes." + git status + git diff + exit 1 + else + echo "✅ All code is formatted correctly." + fi diff --git a/.github/workflows/lint-dprint.yml b/.github/workflows/lint-dprint.yml new file mode 100644 index 00000000000..56d56e0247d --- /dev/null +++ b/.github/workflows/lint-dprint.yml @@ -0,0 +1,29 @@ +# We want to run dprint for only the files it checks without running the other linters, which are +# expensive. For example, dprint should run for markdown changes, but pod lib lint doesn't need to +# run for markdown changes. Therefore, we run it in an extra workflow. + +name: lint-dprint +on: + push: + branches: + - main + paths: + - "**/*.yml" + - "**/*.yaml" + - "**/*.json" + - "**/*.md" + + pull_request: + paths: + - "**/*.yml" + - "**/*.yaml" + - "**/*.json" + - "**/*.md" + +jobs: + lint-dprint: + name: Run dprint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dprint/check@v2.3 diff --git a/.github/workflows/lint-shellcheck.yml b/.github/workflows/lint-shellcheck.yml new file mode 100644 index 00000000000..d18d53abc6a --- /dev/null +++ b/.github/workflows/lint-shellcheck.yml @@ -0,0 +1,25 @@ +# We want only to run the shellcheck when sh files change without running the other linters, which are +# expensive. For example, pod lib lint doesn't need to run for sh changes. Therefore, we run it in an +# extra workflow. + +name: lint-shellcheck +on: + push: + branches: + - main + paths: + - ".github/workflows/lint-shellcheck.yml" + - "**/*.sh" + + pull_request: + paths: + - ".github/workflows/lint-shellcheck.yml" + - "**/*.sh" + +jobs: + shellcheck: + name: Run Shellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: shellcheck **/*.sh diff --git a/.github/workflows/lint-swift-formatting.yml b/.github/workflows/lint-swift-formatting.yml new file mode 100644 index 00000000000..4e6ac0efd80 --- /dev/null +++ b/.github/workflows/lint-swift-formatting.yml @@ -0,0 +1,39 @@ +name: Check Code Formatting +on: + push: + branches: + - main + paths: + - "**/*.swift" + - ".github/workflows/lint-swift-formatting.yml" + - ".swiftlint.yml" + + pull_request: + paths: + - "**/*.swift" + - ".github/workflows/lint-swift-formatting.yml" + - ".swiftlint.yml" + +jobs: + format-code: + name: Check Formatting of Swiftlint Code + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Install tooling + run: make init-ci-format + + - name: Run SwiftLint + run: make format-swift-all + + - name: Check for Formatting Changes + run: | + if [[ -n "$(git status --porcelain)" ]]; then + echo "❌ Some Swift code is not formatted correctly. Please run 'make format' and commit the changes." + git status + git diff + exit 1 + else + echo "✅ All code is formatted correctly." + fi diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000000..9e06c438eef --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,76 @@ +name: lint +on: + push: + branches: + - main + paths: + - "Sources/**" + - "Tests/**" + - "test-server/**" + - "Samples/**" + - ".github/workflows/lint.yml" + - "scripts/ci-select-xcode.sh" + + pull_request: + paths: + - "Sources/**" + - "Tests/**" + - "test-server/**" + - "Samples/**" + - ".github/workflows/lint.yml" + - "scripts/ci-select-xcode.sh" + - "Sentry.xcodeproj/**" + - "*.podspec" + - "Gemfile.lock" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + swift-lint: + name: Swift Lint + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - run: swiftlint --version + - name: Run SwiftLint + run: swiftlint --strict + + xcode-analyze: + name: Xcode Analyze + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + - run: ./scripts/ci-select-xcode.sh 16.4 + - run: make analyze + + lint-podspec: + name: pod lint ${{ matrix.podspec}} ${{ matrix.library_type }} ${{ matrix.platform}} + runs-on: macos-14 + strategy: + fail-fast: false + matrix: + podspec: ["Sentry", "SentrySwiftUI"] + platform: ["ios", "macos", "tvos", "watchos"] + library_type: ["dynamic", "static"] + + steps: + - uses: actions/checkout@v4 + - run: ./scripts/ci-select-xcode.sh 15.4 + # We need to update the spec-repo, because it can happen that it is not up to date and then the lint fails. + - run: pod repo update + - name: Validate Podspec + run: ./scripts/pod-lib-lint.sh ${{ matrix.platform }} ${{ matrix.podspec}} ${{ matrix.library_type}} + + lint-hybrid-sdk-podspec: + name: pod lint Sentry/HybridSDK + runs-on: macos-14 + + steps: + - uses: actions/checkout@v4 + - run: ./scripts/ci-select-xcode.sh 15.4 + - run: pod repo update + - name: Validate HybridPod Podspec + run: pod lib lint ./Tests/HybridSDKTest/HybridPod.podspec --allow-warnings --verbose --platforms=ios "--include-podspecs={Sentry.podspec}" diff --git a/.github/workflows/objc-conversion-analysis.yml b/.github/workflows/objc-conversion-analysis.yml new file mode 100644 index 00000000000..6c0af7b65a5 --- /dev/null +++ b/.github/workflows/objc-conversion-analysis.yml @@ -0,0 +1,58 @@ +name: Objective-C Conversion Analysis + +on: + push: + branches: + - main + pull_request: + paths: + - ".github/workflows/objc-conversion-analysis.yml" + - "SwiftConversion/**" + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + analyze-objc-conversion: + name: Analyze Objective-C to Swift Conversion + runs-on: macos-15 + timeout-minutes: 10 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Ruby + uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # pin@v5.4.3 + with: + ruby-version: "3.2" + bundler-cache: true + + - name: Install Graphviz + run: brew install graphviz + + - name: Run Objective-C conversion analyzer + working-directory: SwiftConversion + run: | + ruby objc_conversion_analyzer.rb + + - name: Generate Graphviz DOT file + working-directory: SwiftConversion + run: | + ruby generate_graphviz.rb + + - name: Convert DOT to SVG + working-directory: SwiftConversion + run: | + dot -Tsvg objc_dependencies_topo.dot -o objc_dependencies_topo.svg + + - name: Upload analysis artifacts + uses: actions/upload-artifact@v4 + with: + name: objc-conversion-analysis + path: | + SwiftConversion/objc_conversion_analysis.json + SwiftConversion/objc_dependencies_topo.dot + SwiftConversion/objc_dependencies_topo.svg + retention-days: 30 diff --git a/.github/workflows/release-comment-issues.yml b/.github/workflows/release-comment-issues.yml new file mode 100644 index 00000000000..ecf61b50824 --- /dev/null +++ b/.github/workflows/release-comment-issues.yml @@ -0,0 +1,33 @@ +name: "Automation: Notify issues for release" +on: + release: + types: + - published + workflow_dispatch: + inputs: + version: + description: Which version to notify issues for + required: false + +# This workflow is triggered when a release is published +jobs: + release-comment-issues: + runs-on: ubuntu-24.04 + name: Notify issues + steps: + - name: Get version + id: get_version + run: echo "version=${VERSION}" >> $GITHUB_OUTPUT + env: + VERSION: ${{ github.event.inputs.version || github.event.release.tag_name }} + + - name: Comment on linked issues that are mentioned in release + if: | + steps.get_version.outputs.version != '' + && !contains(steps.get_version.outputs.version, 'a') + && !contains(steps.get_version.outputs.version, 'b') + && !contains(steps.get_version.outputs.version, 'rc') + uses: getsentry/release-comment-issues-gh-action@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + version: ${{ steps.get_version.outputs.version }} diff --git a/.github/workflows/release-upload-xcframework.yml b/.github/workflows/release-upload-xcframework.yml new file mode 100644 index 00000000000..f72e906b45a --- /dev/null +++ b/.github/workflows/release-upload-xcframework.yml @@ -0,0 +1,47 @@ +name: Upload XCFrameworks +on: + push: + branches: + - release/** + +jobs: + # Craft uses the Git commit hash to query GitHub Actions for artifacts + # uploaded in a workflow run associated with that commit. + # + # To support this, we download the XCFramework already built and uploaded + # in release.yml (triggered via workflow_dispatch), and reupload it here. + # This associates it with the new commit in the release branch, which is + # created by getsentry/action-prepare-release in release.yml. + # + # This is necessary because Swift Package Manager requires a checksum for + # XCFrameworks, creating a chicken-and-egg problem: we need the XCFramework + # to generate the checksum, but we also need the checksum to update Package.swift. + # + # The sequence is: + # 1. Build the XCFrameworks in release.yml. + # 2. getsentry/action-prepare-release updates Package.swift with the checksum. + # 3. Upload the XCFrameworks again here so Craft can find it by commit. + upload-xcframeworks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Get Release workflow run ID + run: echo "FRAMEWORK_RUN_ID=$(./scripts/xcframework-generated-run.sh)" >> $GITHUB_ENV + + - uses: actions/download-artifact@v4 + with: + name: xcframeworks.zip + path: Carthage/ + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ env.FRAMEWORK_RUN_ID }} + + - name: Archive XCFrameworks for Craft + uses: actions/upload-artifact@v4 + with: + # Craft uses the git commit hash of the release branch to download the release artifacts. + name: ${{ github.sha }} + if-no-files-found: error + overwrite: true + path: | + ${{github.workspace}}/Carthage/*.zip diff --git a/.github/workflows/test-cross-platform.yml b/.github/workflows/test-cross-platform.yml new file mode 100644 index 00000000000..61637eca5b7 --- /dev/null +++ b/.github/workflows/test-cross-platform.yml @@ -0,0 +1,68 @@ +name: Test Cross-Platform Sentry SDK Installation + +on: + push: + branches: + - main + pull_request: + paths: + - ".github/workflows/test-cross-platform.yml" + - "Sources/**" + - "Sentry.podspec" + +jobs: + test-react-native: + name: React Native + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + with: + repository: getsentry/sentry-cocoa + path: sentry-cocoa + + - name: Initialize tools + run: make init-ci-build + working-directory: sentry-cocoa + + - name: Clone Sentry React Native Repository + uses: actions/checkout@v4 + with: + repository: getsentry/sentry-react-native + path: sentry-react-native + + - name: Enable Corepack + working-directory: sentry-react-native + run: npm i -g corepack + + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: "yarn" + cache-dependency-path: sentry-react-native/yarn.lock + + - name: Install SDK JS Dependencies + working-directory: sentry-react-native + run: yarn install + + - name: Remove Sentry/HybridSDK Dependency from RNSentry.podspec + run: sed -i '' "s/s.dependency 'Sentry\/HybridSDK', '[0-9]*\.[0-9]*\.[0-9]*'/s.dependency 'Sentry\/HybridSDK'/" sentry-react-native/packages/core/RNSentry.podspec + + - name: Add Sentry/HybridSDK Dependency to RNSentryCocoaTester/Podfile + run: sed -i '' -e "s/RNSentry.podspec'/RNSentry.podspec'\\n pod 'Sentry\/HybridSDK', :path => '..\/..\/..\/..\/sentry-cocoa'/" sentry-react-native/packages/core/RNSentryCocoaTester/Podfile + + - name: Install App Pods + working-directory: sentry-react-native/packages/core/RNSentryCocoaTester + run: pod install + + - name: Run iOS Tests + working-directory: sentry-react-native/packages/core/RNSentryCocoaTester + env: + SCHEME: RNSentryCocoaTester + CONFIGURATION: Release + DESTINATION: "platform=iOS Simulator,OS=latest,name=iPhone 16" + run: | + env NSUnbufferedIO=YES \ + xcodebuild -workspace *.xcworkspace \ + -scheme $SCHEME -configuration $CONFIGURATION \ + -destination "$DESTINATION" \ + test | xcbeautify diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..c81489a703a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,281 @@ +name: Test +on: + push: + branches: + - main + - release/** + + pull_request: + paths: + - "Sources/**" + - "Tests/**" + - "SentryTestUtils/**" + - "test-server/**" + - ".github/workflows/test.yml" + - "fastlane/**" + - "scripts/tests-with-thread-sanitizer.sh" + - "scripts/ci-select-xcode.sh" + - "scripts/sentry-xcodebuild.sh" + - ".codecov.yml" + - "Sentry.xcodeproj" + - "**/*.xctestplan" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-test-server: + name: Build test server + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - name: Cache for Test Server + id: cache_test_server + uses: actions/cache@v4 + with: + path: ./test-server/.build + key: test-server-${{ hashFiles('./test-server') }} + restore-keys: | + test-server-${{ hashFiles('./test-server') }} + test-server- + + - name: Build Test Server + if: steps.cache_test_server.outputs.cache-hit != 'true' + working-directory: test-server + run: >- + swift build -c release 2>&1 | tee test-server-build.log + + - name: Copy exec + working-directory: test-server + run: cp $(swift build --show-bin-path -c release)/Run test-server-exec + + - name: Archiving DerivedData + uses: actions/upload-artifact@v4 + with: + name: test-server + path: | + ./test-server/test-server-exec + + - name: Archiving Raw Test Logs + uses: actions/upload-artifact@v4 + if: ${{ failure() || cancelled() }} + with: + name: test-server-build-log-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + path: | + raw-test-output.log + + unit-tests: + name: Unit ${{matrix.platform}} - Xcode ${{matrix.xcode}} - OS ${{matrix.test-destination-os}} ${{matrix.scheme}} + runs-on: ${{matrix.runs-on}} + timeout-minutes: 20 + needs: build-test-server + + 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 16 + - runs-on: macos-13 + platform: "iOS" + xcode: "14.3.1" + test-destination-os: "16.4" + device: "iPhone 14" + scheme: "Sentry" + + # iOS 17 + - runs-on: macos-14 + platform: "iOS" + xcode: "15.4" + test-destination-os: "17.2" + device: "iPhone 15" + scheme: "Sentry" + + # iOS 18 + - runs-on: macos-15 + platform: "iOS" + xcode: "16.4" + test-destination-os: "18.2" + device: "iPhone 16" + 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 + - runs-on: macos-14 + platform: "macOS" + xcode: "15.4" + test-destination-os: "latest" + scheme: "Sentry" + + # macOS 15 + - runs-on: macos-15 + platform: "macOS" + xcode: "16.4" + test-destination-os: "latest" + 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. + - runs-on: macos-14 + platform: "Catalyst" + xcode: "15.4" + test-destination-os: "latest" + scheme: "Sentry" + + - runs-on: macos-15 + platform: "Catalyst" + xcode: "16.4" + test-destination-os: "latest" + scheme: "Sentry" + + # 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 + - runs-on: macos-14 + platform: "tvOS" + xcode: "15.4" + test-destination-os: "17.5" + scheme: "Sentry" + + # iOS 17 + - runs-on: macos-14 + platform: "iOS" + xcode: "15.4" + test-destination-os: "17.2" + device: "iPhone 15" + scheme: "SentrySwiftUI" + + # tvOS 18 + - runs-on: macos-15 + platform: "tvOS" + xcode: "16.4" + test-destination-os: "18.1" + scheme: "Sentry" + + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: test-server + + - name: Print hardware info + run: system_profiler SPHardwareDataType + + - name: Start Test Server + run: ./scripts/start-test-server.sh + + - run: ./scripts/ci-select-xcode.sh ${{matrix.xcode}} + + - name: Install Slather + run: gem install slather + + # 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 \ + --device "${{matrix.device}}" \ + --configuration TestCI \ + --scheme ${{matrix.scheme}} + + - name: Run tests + # We call a script with the platform so the destination + # passed to xcodebuild doesn't end up in the job name, + # because GitHub Actions don't provide an easy way of + # manipulating string in expressions. + run: | + ./scripts/sentry-xcodebuild.sh \ + --platform ${{matrix.platform}} \ + --os ${{matrix.test-destination-os}} \ + --ref ${{ github.ref_name }} \ + --command test-without-building \ + --device "${{matrix.device}}" \ + --configuration TestCI \ + --scheme ${{matrix.scheme}} + + - name: Publish Test Report + uses: mikepenz/action-junit-report@3585e9575db828022551b4231f165eb59a0e74e3 # v5.6.2 + if: always() + with: + report_paths: "build/reports/junit.xml" + fail_on_failure: true + fail_on_parse_error: true + detailed_summary: true + + - name: Slowest Tests + if: ${{ always() }} + run: ./scripts/xcode-slowest-tests.sh + + - name: Archiving DerivedData Logs + uses: actions/upload-artifact@v4 + if: steps.build_tests.outcome == 'failure' + with: + name: derived-data-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + path: | + /Users/runner/Library/Developer/Xcode/DerivedData/**/Logs/** + + - name: Archiving Raw Logs + uses: actions/upload-artifact@v4 + if: ${{ failure() || cancelled() }} + with: + name: raw-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + path: | + raw-build-output.log + raw-build-for-testing-output.log + raw-test-output.log + + - name: Archiving Crash Logs + uses: actions/upload-artifact@v4 + if: ${{ failure() || cancelled() }} + with: + name: crash-logs-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + path: | + ~/Library/Logs/DiagnosticReports/** + + # We can upload all coverage reports, because codecov merges them. + # See https://docs.codecov.io/docs/merging-reports + # Checkout .codecov.yml to see the config of Codecov + # We don't upload codecov for release branches, as we don't want a failing coverage check to block a release. + # We don't upload codecov for scheduled runs as CodeCov only accepts a limited amount of uploads per commit. + - name: Push code coverage to codecov + id: codecov_1 + uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # pin@v5.4.3 + if: ${{ contains(matrix.platform, 'iOS') && !contains(github.ref, 'release') && github.event.schedule == '' }} + with: + # Although public repos should not have to specify a token there seems to be a bug with the Codecov GH action, which can + # be solved by specifying the token, see https://github.com/codecov/codecov-action/issues/557#issuecomment-1224970469 + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + verbose: true + + # Sometimes codecov uploads etc can fail. Retry one time to rule out e.g. intermittent network failures. + - name: Push code coverage to codecov + id: codecov_2 + uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # pin@v5.4.3 + if: ${{ steps.codecov_1.outcome == 'failure' && contains(matrix.platform, 'iOS') && !contains(github.ref, 'release') && github.event.schedule == '' }} + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + verbose: true + + - name: Codecov test analytics + if: ${{ !cancelled() && !contains(github.ref, 'release') && github.event.schedule == '' }} + uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # pin@v1.1.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + name: sentry-cocoa-unit-tests diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml new file mode 100644 index 00000000000..32513b2f64c --- /dev/null +++ b/.github/workflows/testflight.yml @@ -0,0 +1,66 @@ +name: Upload to Testflight +on: + push: + branches: + - main + - release/** + + paths: + - "Sources/**" + - "Samples/iOS-Swift/**" + - ".github/workflows/testflight.yml" + - "fastlane/**" + - "scripts/ci-select-xcode.sh" + + pull_request: + paths: + - ".github/workflows/testflight.yml" + workflow_dispatch: + +jobs: + upload_to_testflight: + name: Build and Upload iOS-Swift to Testflight + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + - run: ./scripts/ci-select-xcode.sh 16.4 + - uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - run: make init-ci-build + - run: make xcode-ci + + # We upload a new version to TestFlight on every commit on main + # So we need to bump the build number each time + - name: Bump Build Version + env: + FASTLANE_BUILD_NUMBER: ${{ github.run_number }} + run: bundle exec fastlane bump_build_number + + - name: Remove preview version suffixes + run: bundle exec fastlane remove_preview_version_suffixes + + - name: Run Fastlane + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} + FASTLANE_BUNDLE_VERSION: ${{ github.run_number }} + FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} + MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + run: | + bundle exec fastlane build_ios_swift + bundle exec fastlane ios_swift_to_testflight + + - name: Archiving + uses: actions/upload-artifact@v4 + with: + name: dSYMs + path: | + ${{ github.workspace }}/iOS-Swift.* + ${{ github.workspace }}/*.dSYM.zip + ${{ github.workspace }}/dSYMs/ diff --git a/.github/workflows/ui-tests-critical.yml b/.github/workflows/ui-tests-critical.yml new file mode 100644 index 00000000000..d0dd557db02 --- /dev/null +++ b/.github/workflows/ui-tests-critical.yml @@ -0,0 +1,78 @@ +name: UI Tests Critical +on: + push: + branches: + - main + + pull_request: + paths: + - "Sources/**" + - ".github/workflows/ui-tests-critical.yml" + - ".github/workflows/ui-tests-common.yml" + - "fastlane/**" + - "TestSamples/**" + - "**/*.xctestplan" + # Explicitly list used scripts to avoid unnecessary runs + - "scripts/ci-boot-simulator.sh" + - "scripts/ci-select-xcode.sh" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + run-tests: + name: Test iOS on Xcode ${{matrix.platform.xcode}} - ${{ matrix.command.fastlane_command }} - V4 # Up the version with every change to keep track of flaky tests + uses: ./.github/workflows/ui-tests-common.yml + with: + fastlane_command: ${{ matrix.command.fastlane_command }} + build_with_make: true + xcode_version: ${{matrix.platform.xcode}} + macos_version: ${{matrix.platform.runs-on}} + files_suffix: _${{matrix.platform.xcode}} + strategy: + fail-fast: false + matrix: + platform: + # As of 25th March 2025, the preinstalled iOS simulator version is 16.4 for macOS 13 and Xcode 14.3.1; see + # https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md#installed-sdks + - runs-on: macos-13 + xcode: "14.3.1" + + # macos-14 iOS 17 not included due to the XCUIServerNotFound errors causing flaky tests + + # As of 25th March 2025, the preinstalled iOS simulator version is 18.2 for macOS 15 and Xcode 16.2; see + # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md#installed-sdks + - runs-on: macos-15 + xcode: "16.2" + command: + - fastlane_command: ui_critical_tests_ios_swiftui_envelope + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + run-swiftui-crash-test: + name: Run SwiftUI Crash Test + runs-on: macos-15 + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + + - run: ./scripts/ci-select-xcode.sh 16.4 + + - run: make init-ci-build + - run: make xcode-ci + + - name: Boot simulator + run: ./scripts/ci-boot-simulator.sh + + - name: Run SwiftUI Crash Test + run: | + ./TestSamples/SwiftUICrashTest/test-crash-and-relaunch.sh --screenshots-dir "swiftui-crash-test-screenshots" + + - name: Upload SwiftUI Crash Test Screenshots + uses: actions/upload-artifact@v4 + if: always() + with: + name: swiftui-crash-test-screenshots + path: swiftui-crash-test-screenshots diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml new file mode 100644 index 00000000000..8e88d37a7af --- /dev/null +++ b/.github/workflows/ui-tests.yml @@ -0,0 +1,99 @@ +name: UI Tests +on: + push: + branches: + - main + + pull_request: + paths: + - "Sources/**" + - "Tests/**" + - ".github/workflows/ui-tests.yml" + - ".github/workflows/ui-tests-common.yml" + - "fastlane/**" + - ".sauce/config.yml" + - "scripts/ci-select-xcode.sh" + - "**/*.xctestplan" + - "Samples/iOS-SwiftUI/**" + - "Samples/iOS-Swift/**" + - "Samples/iOS-Swift6/**" + - "Samples/SentrySampleShared/**" + - "Samples/Shared/**" + - "scripts/build-xcframework-slice.sh" + - "scripts/assemble-xcframework.sh" + - ".github/workflows/build-xcframework-variant-slices.yml" + - ".github/workflows/assemble-xcframework-variant.yml" + +# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + ui-tests: + name: UI Tests for ${{matrix.target}} - V3 # Up the version with every change to keep track of flaky tests + uses: ./.github/workflows/ui-tests-common.yml + strategy: + matrix: + target: ["ios_objc", "tvos_swift"] + with: + fastlane_command: ui_tests_${{matrix.target}} + xcode_version: 16.2 + build_with_make: true + macos_version: macos-14 + codecov_test_analytics: true + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + # SwiftUI only supports iOS 14+ so we run it in a separate matrix here + ui-tests-swift-ui: + name: UI Tests for SwiftUI - V4 # Up the version with every change to keep track of flaky tests + uses: ./.github/workflows/ui-tests-common.yml + with: + fastlane_command: ui_tests_ios_swiftui + xcode_version: 16.4 + build_with_make: true + macos_version: macos-15 + fastlane_command_extra_arguments: device:iPhone 16 (18.5) + codecov_test_analytics: true + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + ui-tests-swift: + name: UI Tests for iOS-Swift Xcode ${{matrix.xcode}} - V5 # Up the version with every change to keep track of flaky tests + uses: ./.github/workflows/ui-tests-common.yml + strategy: + fail-fast: false + matrix: + include: + - runs-on: macos-13 + xcode: "14.3.1" + device: iPhone 14 (16.4) + - runs-on: macos-14 + xcode: "15.4" + device: iPhone 15 (17.5) + - runs-on: macos-15 + xcode: "16.4" + device: iPhone 16 (18.5) + with: + fastlane_command: ui_tests_ios_swift + fastlane_command_extra_arguments: device:${{matrix.device}} + files_suffix: _xcode_${{matrix.xcode}}-${{matrix.device}} + xcode_version: ${{matrix.xcode}} + build_with_make: true + macos_version: ${{matrix.runs-on}} + codecov_test_analytics: true + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + ui-tests-swift6: + name: UI Tests for iOS-Swift6 - V3 # Up the version with every change to keep track of flaky tests + uses: ./.github/workflows/ui-tests-common.yml + with: + fastlane_command: ui_tests_ios_swift6 + xcode_version: 16.2 + build_with_make: true + macos_version: macos-15 + codecov_test_analytics: true + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/version-bump-util.yml b/.github/workflows/version-bump-util.yml new file mode 100644 index 00000000000..71c94ae5353 --- /dev/null +++ b/.github/workflows/version-bump-util.yml @@ -0,0 +1,81 @@ +name: Test Version Bump Util + +on: + push: + branches: + - main + + pull_request: + paths: + - "Utils/VersionBump/**" + - ".github/workflows/version-bump-util.yml" + - "./Sentry.podspec" + - "./Package.swift" + - "./SentryPrivate.podspec" + - "./SentrySwiftUI.podspec" + - "./Sources/Sentry/SentryMeta.m" + - "./Tests/HybridSDKTest/HybridPod.podspec" + - "./Sources/Configuration/SDK.xcconfig" + - "./Sources/Configuration/Versioning.xcconfig" + - "./Sources/Configuration/SentrySwiftUI.xcconfig" + - "./Samples/Shared/Config/Versioning.xcconfig" + - "./scripts/bump.sh" + +jobs: + run-version-bump: + # The release workflow uses the Makefile to bump the version so it needs to be tested. + name: Run Version Bump (Makefile) + # We intentionally run this on ubuntu because the release workflow also runs on ubuntu, which uses the version bump util. + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Generate Version Number + id: generate-version-number + run: | + TIMESTAMP=$(date +%Y%m%d%H%M%S) + echo "VERSION=100.0.$TIMESTAMP" >> $GITHUB_OUTPUT + # We don't care which version we bump to, as long as it's a valid semver + - run: make bump-version TO=${{ steps.generate-version-number.outputs.VERSION }} + - run: make verify-version TO=${{ steps.generate-version-number.outputs.VERSION }} + + run-version-bump-script: + # Craft uses the shell script to bump the version so it needs to be tested. + name: Run Version Bump (Shell Script) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Generate Version Number + id: generate-version-number + run: | + OLD_VERSION=$(cat ./Sources/Configuration/Versioning.xcconfig | grep MARKETING_VERSION | cut -d '=' -f 2 | tr -d ' ') + echo "Read old version: ${OLD_VERSION}" + echo "OLD_VERSION=${OLD_VERSION}" >> $GITHUB_OUTPUT + + NEW_VERSION="100.0.$(date +%Y%m%d%H%M%S)" + echo "Generated new version: ${NEW_VERSION}" + echo "NEW_VERSION=${NEW_VERSION}" >> $GITHUB_OUTPUT + + - name: Verify OLD_VERSION is defined + if: ${{ steps.generate-version-number.outputs.OLD_VERSION == '' }} + run: | + echo "OLD_VERSION is not defined. Make sure this script is reading the version from the correct file." + exit 1 + + - name: Create fake xcframework for update-package-sha.sh + run: | + mkdir -p Carthage + echo "" > Carthage/Sentry.xcframework.zip + echo "" > Carthage/Sentry-Dynamic.xcframework.zip + + - name: Bump version + run: ./scripts/bump.sh ${{ steps.generate-version-number.outputs.OLD_VERSION }} ${{ steps.generate-version-number.outputs.NEW_VERSION }} + + - name: Verify outputs of bump.sh + run: make verify-version TO=${{ steps.generate-version-number.outputs.NEW_VERSION }} + + - name: Verify outputs of update-package-sha.sh + run: | + ./scripts/verify-package-sha.sh \ + --static-checksum "7062a80f8a80f8b6d812698af87384751567a6aaa0df6f03b0596d728b22dcfd" \ + --dynamic-checksum "f6325cd8f05523d60222451fa61b3cd3d58148e5a21236f82abfd3f92750c87c" \ + --last-release-runid "${{ github.run_id }}" From 61520994e3c15d09e02ab8cfc73e547adc60358c Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 23 Jul 2025 17:45:50 -0300 Subject: [PATCH 8/9] Remove Xcode select in version bump step --- .github/workflows/build-xcframework-variant-slices.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build-xcframework-variant-slices.yml b/.github/workflows/build-xcframework-variant-slices.yml index 9125804c35b..c4f695e045d 100644 --- a/.github/workflows/build-xcframework-variant-slices.yml +++ b/.github/workflows/build-xcframework-variant-slices.yml @@ -94,9 +94,7 @@ jobs: - name: Bump version if: steps.cache-xcarchive.outputs.cache-hit != 'true' - run: | - ./scripts/ci-select-xcode.sh 15.2 - make bump-version TO=${{ env.VERSION }} + run: make bump-version TO=${{ env.VERSION }} - name: Build ${{inputs.name}}${{inputs.suffix}} XCFramework slice for ${{matrix.sdk}} if: steps.cache-xcarchive.outputs.cache-hit != 'true' From 8681c49d7fec759501c5193ed4afcea215ccc8d5 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Thu, 24 Jul 2025 00:00:30 -0300 Subject: [PATCH 9/9] Try prefixing `Data` with `Foundation.` --- .../Performance/IO/Data+SentryTracing.swift | 6 +++--- sdk_api.json | 15 +++++++++++---- sdk_api_V9.json | 15 +++++++++++---- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift b/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift index ded0e7d17a5..94325fabfc0 100644 --- a/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift +++ b/Sources/Swift/Integrations/Performance/IO/Data+SentryTracing.swift @@ -18,9 +18,9 @@ public extension Data { /// - url: The location on disk of the data to read. /// - options: The mask specifying the options to use when reading the data. For more information, see ``NSData.ReadingOptions``. /// - Note: See ``Data.init(contentsOf:options:)`` for more information. - init(contentsOfWithSentryTracing url: URL, options: NSData.ReadingOptions = []) throws { + init(contentsOfWithSentryTracing url: URL, options: Foundation.Data.ReadingOptions = []) throws { // Gets a tracker instance if the SDK is enabled, otherwise uses the original method. - let method = { (url: URL, options: NSData.ReadingOptions) throws -> Data in + let method = { (url: URL, options: Data.ReadingOptions) throws -> Data in try Data(contentsOf: url, options: options) } guard let tracker = SentryFileIOTracker.sharedInstance() else { @@ -49,7 +49,7 @@ public extension Data { /// - url: The location to write the data into. /// - options: Options for writing the data. Default value is `[]`. /// - Note: See ``Data.write(to:options:)`` for more information. - func writeWithSentryTracing(to url: URL, options: Data.WritingOptions = []) throws { + func writeWithSentryTracing(to url: URL, options: Foundation.Data.WritingOptions = []) throws { // Gets a tracker instance if the SDK is enabled, otherwise uses the original method. let method = { (data: Data, url: URL, options: Data.WritingOptions) throws in try data.write(to: url, options: options) diff --git a/sdk_api.json b/sdk_api.json index a9cb9a6e7ee..47bac207404 100644 --- a/sdk_api.json +++ b/sdk_api.json @@ -56887,11 +56887,18 @@ "usr": "s:10Foundation3URLV" }, { - "kind": "TypeNominal", + "kind": "TypeNameAlias", "name": "ReadingOptions", - "printedName": "Foundation.NSData.ReadingOptions", - "hasDefaultArg": true, - "usr": "c:@E@NSDataReadingOptions" + "printedName": "Foundation.Data.ReadingOptions", + "children": [ + { + "kind": "TypeNominal", + "name": "ReadingOptions", + "printedName": "Foundation.NSData.ReadingOptions", + "usr": "c:@E@NSDataReadingOptions" + } + ], + "hasDefaultArg": true } ], "declKind": "Constructor", diff --git a/sdk_api_V9.json b/sdk_api_V9.json index 595e5dd672d..e8a530c1824 100644 --- a/sdk_api_V9.json +++ b/sdk_api_V9.json @@ -53936,11 +53936,18 @@ "usr": "s:10Foundation3URLV" }, { - "kind": "TypeNominal", + "kind": "TypeNameAlias", "name": "ReadingOptions", - "printedName": "Foundation.NSData.ReadingOptions", - "hasDefaultArg": true, - "usr": "c:@E@NSDataReadingOptions" + "printedName": "Foundation.Data.ReadingOptions", + "children": [ + { + "kind": "TypeNominal", + "name": "ReadingOptions", + "printedName": "Foundation.NSData.ReadingOptions", + "usr": "c:@E@NSDataReadingOptions" + } + ], + "hasDefaultArg": true } ], "declKind": "Constructor",