From f16dfe855c5d25a1a5c341c4edf30a8151d16e1f Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 12 Aug 2026 11:18:10 -0300 Subject: [PATCH 1/4] feat: add SPM traits for 3rd-party integrations Add PrecompiledSentry (default) and SentryFromSource package traits to all 3rd-party integrations so users can select between precompiled xcframeworks and building from source. - Bump swift-tools-version to 6.1 for trait support - Add conditional product dependencies based on active trait - Add conditional imports (Sentry vs SentrySwift) - Add compile-time error if both traits are enabled - Add SentryFromSource trait to CI test matrix --- .../workflows/test-3rd-party-integrations.yml | 7 +++--- .../SentryCocoaLumberjack/Package.swift | 21 ++++++++++++++--- .../Sources/SentryCocoaLumberjackLogger.swift | 4 ++++ .../Sources/SentryTraitValidation.swift | 3 +++ .../SentryCocoaLumberjackLoggerTests.swift | 4 ++++ .../SentryPulse/Package.swift | 23 +++++++++++++++---- .../SentryPulse/Sources/SentryPulse.swift | 4 ++++ .../Sources/SentryTraitValidation.swift | 3 +++ .../SentryPulse/Tests/SentryPulseTests.swift | 4 ++++ .../SentrySwiftLog/Package.swift | 21 ++++++++++++++--- .../Sources/SentryLogHandler.swift | 4 ++++ .../Sources/SentryTraitValidation.swift | 3 +++ .../Tests/SentryLogHandlerTests.swift | 4 ++++ .../SentrySwiftyBeaver/Package.swift | 21 ++++++++++++++--- .../Sources/SentryDestination.swift | 4 ++++ .../Sources/SentryTraitValidation.swift | 3 +++ .../Tests/SentryDestinationTests.swift | 4 ++++ 17 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift create mode 100644 3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift create mode 100644 3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift create mode 100644 3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift diff --git a/.github/workflows/test-3rd-party-integrations.yml b/.github/workflows/test-3rd-party-integrations.yml index b821bfb8591..49a8b3e9496 100644 --- a/.github/workflows/test-3rd-party-integrations.yml +++ b/.github/workflows/test-3rd-party-integrations.yml @@ -78,7 +78,7 @@ jobs: # SPM tests for all 3rd-party integrations test-integrations-spm: - name: SPM Tests | ${{matrix.integration_dir}} + name: SPM Tests (${{matrix.trait}}) | ${{matrix.integration_dir}} needs: [files-changed, build-xcframeworks] if: startsWith(github.ref, 'refs/heads/release/') == false && (github.event_name != 'pull_request' || needs.files-changed.outputs.run_3rd_party_integrations_tests_for_prs == 'true') runs-on: ["bitrise_pool_name:sequoia"] @@ -92,6 +92,7 @@ jobs: "SentryCocoaLumberjack", "SentryPulse", ] + trait: ["PrecompiledSentry", "SentryFromSource"] steps: - name: Warm CoreSimulator run: xcrun simctl list runtimes -j > /dev/null 2>&1 & @@ -115,12 +116,12 @@ jobs: sed -i '' 's|\.package(url: "https://github\.com/getsentry/sentry-cocoa", from: "[^"]*")|.package(name: "sentry-cocoa", path: "../..")|g' Package.swift - name: Run SPM Tests working-directory: 3rd-party-integrations/${{matrix.integration_dir}} - run: swift test + run: swift test --traits ${{ matrix.trait }} - name: Archiving Raw Logs uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 if: ${{ failure() || cancelled() }} with: - name: raw-output-${{matrix.integration_dir}}-integration + name: raw-output-${{matrix.integration_dir}}-${{matrix.trait}}-integration path: | 3rd-party-integrations/${{matrix.integration_dir}}/.build/**/*.log - name: Run CI Diagnostics diff --git a/3rd-party-integrations/SentryCocoaLumberjack/Package.swift b/3rd-party-integrations/SentryCocoaLumberjack/Package.swift index 9bffcaa0ba6..20326b19438 100644 --- a/3rd-party-integrations/SentryCocoaLumberjack/Package.swift +++ b/3rd-party-integrations/SentryCocoaLumberjack/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:6.0 +// swift-tools-version:6.1 import PackageDescription let package = Package( @@ -10,6 +10,11 @@ let package = Package( targets: ["SentryCocoaLumberjack"] ) ], + traits: [ + .default(enabledTraits: ["PrecompiledSentry"]), + .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") + ], dependencies: [ .package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack", from: "3.8.0"), .package(url: "https://github.com/getsentry/sentry-cocoa", from: "9.25.0") @@ -19,7 +24,12 @@ let package = Package( name: "SentryCocoaLumberjack", dependencies: [ .product(name: "CocoaLumberjackSwift", package: "CocoaLumberjack"), - .product(name: "Sentry", package: "sentry-cocoa") + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), .testTarget( @@ -27,7 +37,12 @@ let package = Package( dependencies: [ "SentryCocoaLumberjack", .product(name: "CocoaLumberjackSwift", package: "CocoaLumberjack"), - .product(name: "Sentry", package: "sentry-cocoa") + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ) ] diff --git a/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryCocoaLumberjackLogger.swift b/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryCocoaLumberjackLogger.swift index 37ee42ae0ea..530fc644ca7 100644 --- a/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryCocoaLumberjackLogger.swift +++ b/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryCocoaLumberjackLogger.swift @@ -1,5 +1,9 @@ import CocoaLumberjackSwift +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif /// A CocoaLumberjack logger that forwards log entries to Sentry's structured logging system. /// diff --git a/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift new file mode 100644 index 00000000000..25396118fb1 --- /dev/null +++ b/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift @@ -0,0 +1,3 @@ +#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE +#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#endif diff --git a/3rd-party-integrations/SentryCocoaLumberjack/Tests/SentryCocoaLumberjackLoggerTests.swift b/3rd-party-integrations/SentryCocoaLumberjack/Tests/SentryCocoaLumberjackLoggerTests.swift index 18a6faff399..1017bd164b2 100644 --- a/3rd-party-integrations/SentryCocoaLumberjack/Tests/SentryCocoaLumberjackLoggerTests.swift +++ b/3rd-party-integrations/SentryCocoaLumberjack/Tests/SentryCocoaLumberjackLoggerTests.swift @@ -1,6 +1,10 @@ @_spi(Private) @testable import SentryCocoaLumberjack import CocoaLumberjackSwift +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif import XCTest // swiftlint:disable cyclomatic_complexity file_length type_body_length diff --git a/3rd-party-integrations/SentryPulse/Package.swift b/3rd-party-integrations/SentryPulse/Package.swift index bf2097a643c..d316dcb6786 100644 --- a/3rd-party-integrations/SentryPulse/Package.swift +++ b/3rd-party-integrations/SentryPulse/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:6.0 +// swift-tools-version:6.1 import PackageDescription let package = Package( @@ -10,6 +10,11 @@ let package = Package( targets: ["SentryPulse"] ) ], + traits: [ + .default(enabledTraits: ["PrecompiledSentry"]), + .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") + ], dependencies: [ .package(url: "https://github.com/kean/Pulse", from: "5.0.0"), .package(url: "https://github.com/getsentry/sentry-cocoa", from: "9.25.0") @@ -19,7 +24,12 @@ let package = Package( name: "SentryPulse", dependencies: [ .product(name: "Pulse", package: "Pulse"), - .product(name: "Sentry", package: "sentry-cocoa") + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), .testTarget( @@ -27,8 +37,13 @@ let package = Package( dependencies: [ "SentryPulse", .product(name: "Pulse", package: "Pulse"), - .product(name: "Sentry", package: "sentry-cocoa") + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] - ) + ) ] ) diff --git a/3rd-party-integrations/SentryPulse/Sources/SentryPulse.swift b/3rd-party-integrations/SentryPulse/Sources/SentryPulse.swift index 7d48889fa8b..e9f80a7041d 100644 --- a/3rd-party-integrations/SentryPulse/Sources/SentryPulse.swift +++ b/3rd-party-integrations/SentryPulse/Sources/SentryPulse.swift @@ -1,6 +1,10 @@ import Combine import Pulse +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif /// Automatically forwards Pulse log messages to Sentry's structured logging system. /// diff --git a/3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift new file mode 100644 index 00000000000..25396118fb1 --- /dev/null +++ b/3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift @@ -0,0 +1,3 @@ +#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE +#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#endif diff --git a/3rd-party-integrations/SentryPulse/Tests/SentryPulseTests.swift b/3rd-party-integrations/SentryPulse/Tests/SentryPulseTests.swift index 39e57e22a48..e0782fb77f4 100644 --- a/3rd-party-integrations/SentryPulse/Tests/SentryPulseTests.swift +++ b/3rd-party-integrations/SentryPulse/Tests/SentryPulseTests.swift @@ -1,6 +1,10 @@ @testable import SentryPulse import Pulse +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif import XCTest // swiftlint:disable cyclomatic_complexity diff --git a/3rd-party-integrations/SentrySwiftLog/Package.swift b/3rd-party-integrations/SentrySwiftLog/Package.swift index e67d2ba1972..cfe9fd5cdd3 100644 --- a/3rd-party-integrations/SentrySwiftLog/Package.swift +++ b/3rd-party-integrations/SentrySwiftLog/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:6.0 +// swift-tools-version:6.1 import PackageDescription let package = Package( @@ -10,6 +10,11 @@ let package = Package( targets: ["SentrySwiftLog"] ) ], + traits: [ + .default(enabledTraits: ["PrecompiledSentry"]), + .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") + ], dependencies: [ .package(url: "https://github.com/apple/swift-log", from: "1.5.0"), .package(url: "https://github.com/getsentry/sentry-cocoa", from: "9.25.0") @@ -19,7 +24,12 @@ let package = Package( name: "SentrySwiftLog", dependencies: [ .product(name: "Logging", package: "swift-log"), - .product(name: "Sentry", package: "sentry-cocoa") + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), .testTarget( @@ -27,7 +37,12 @@ let package = Package( dependencies: [ "SentrySwiftLog", .product(name: "Logging", package: "swift-log"), - .product(name: "Sentry", package: "sentry-cocoa") + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ) ] diff --git a/3rd-party-integrations/SentrySwiftLog/Sources/SentryLogHandler.swift b/3rd-party-integrations/SentrySwiftLog/Sources/SentryLogHandler.swift index d1a41524efc..daffc680168 100644 --- a/3rd-party-integrations/SentrySwiftLog/Sources/SentryLogHandler.swift +++ b/3rd-party-integrations/SentrySwiftLog/Sources/SentryLogHandler.swift @@ -1,5 +1,9 @@ import Logging +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif /// A `swift-log` handler that forwards log entries to Sentry's structured logging system. /// diff --git a/3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift new file mode 100644 index 00000000000..25396118fb1 --- /dev/null +++ b/3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift @@ -0,0 +1,3 @@ +#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE +#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#endif diff --git a/3rd-party-integrations/SentrySwiftLog/Tests/SentryLogHandlerTests.swift b/3rd-party-integrations/SentrySwiftLog/Tests/SentryLogHandlerTests.swift index 2f30e23d863..09a76973218 100644 --- a/3rd-party-integrations/SentrySwiftLog/Tests/SentryLogHandlerTests.swift +++ b/3rd-party-integrations/SentrySwiftLog/Tests/SentryLogHandlerTests.swift @@ -1,6 +1,10 @@ @testable import SentrySwiftLog import Logging +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif import XCTest final class SentryLogHandlerTests: XCTestCase { diff --git a/3rd-party-integrations/SentrySwiftyBeaver/Package.swift b/3rd-party-integrations/SentrySwiftyBeaver/Package.swift index ae3bdc31eac..3746998a268 100644 --- a/3rd-party-integrations/SentrySwiftyBeaver/Package.swift +++ b/3rd-party-integrations/SentrySwiftyBeaver/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:6.0 +// swift-tools-version:6.1 import PackageDescription let package = Package( @@ -10,6 +10,11 @@ let package = Package( targets: ["SentrySwiftyBeaver"] ) ], + traits: [ + .default(enabledTraits: ["PrecompiledSentry"]), + .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") + ], dependencies: [ .package(url: "https://github.com/getsentry/sentry-cocoa", from: "9.25.0"), .package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver.git", from: "2.0.0") @@ -18,16 +23,26 @@ let package = Package( .target( name: "SentrySwiftyBeaver", dependencies: [ - .product(name: "Sentry", package: "sentry-cocoa"), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])), .product(name: "SwiftyBeaver", package: "SwiftyBeaver") + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), .testTarget( name: "SentrySwiftyBeaverTests", dependencies: [ "SentrySwiftyBeaver", - .product(name: "Sentry", package: "sentry-cocoa"), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])), .product(name: "SwiftyBeaver", package: "SwiftyBeaver") + ], + swiftSettings: [ + .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ) ] diff --git a/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryDestination.swift b/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryDestination.swift index a78c2c260e3..d7733816d9b 100644 --- a/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryDestination.swift +++ b/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryDestination.swift @@ -1,4 +1,8 @@ +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif import SwiftyBeaver /// A SwiftyBeaver destination that forwards log entries to Sentry's structured logging system. diff --git a/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift new file mode 100644 index 00000000000..25396118fb1 --- /dev/null +++ b/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift @@ -0,0 +1,3 @@ +#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE +#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#endif diff --git a/3rd-party-integrations/SentrySwiftyBeaver/Tests/SentryDestinationTests.swift b/3rd-party-integrations/SentrySwiftyBeaver/Tests/SentryDestinationTests.swift index 4f1f1f6afbf..7ca0b8d4267 100644 --- a/3rd-party-integrations/SentrySwiftyBeaver/Tests/SentryDestinationTests.swift +++ b/3rd-party-integrations/SentrySwiftyBeaver/Tests/SentryDestinationTests.swift @@ -1,5 +1,9 @@ @testable import SentrySwiftyBeaver +#if SENTRY_FROM_SOURCE +import SentrySwift +#else import Sentry +#endif import SwiftyBeaver import XCTest From a1b906800047b4edf423570dcaf395954aad8bc0 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 12 Aug 2026 11:28:47 -0300 Subject: [PATCH 2/4] ref: rename PrecompiledSentry trait to SentryFromBinary --- .github/workflows/test-3rd-party-integrations.yml | 2 +- .../SentryCocoaLumberjack/Package.swift | 12 ++++++------ .../Sources/SentryTraitValidation.swift | 4 ++-- 3rd-party-integrations/SentryPulse/Package.swift | 12 ++++++------ .../SentryPulse/Sources/SentryTraitValidation.swift | 4 ++-- 3rd-party-integrations/SentrySwiftLog/Package.swift | 12 ++++++------ .../Sources/SentryTraitValidation.swift | 4 ++-- .../SentrySwiftyBeaver/Package.swift | 12 ++++++------ .../Sources/SentryTraitValidation.swift | 4 ++-- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/test-3rd-party-integrations.yml b/.github/workflows/test-3rd-party-integrations.yml index 49a8b3e9496..fdab8b2f117 100644 --- a/.github/workflows/test-3rd-party-integrations.yml +++ b/.github/workflows/test-3rd-party-integrations.yml @@ -92,7 +92,7 @@ jobs: "SentryCocoaLumberjack", "SentryPulse", ] - trait: ["PrecompiledSentry", "SentryFromSource"] + trait: ["SentryFromBinary", "SentryFromSource"] steps: - name: Warm CoreSimulator run: xcrun simctl list runtimes -j > /dev/null 2>&1 & diff --git a/3rd-party-integrations/SentryCocoaLumberjack/Package.swift b/3rd-party-integrations/SentryCocoaLumberjack/Package.swift index 20326b19438..f170ad05ffd 100644 --- a/3rd-party-integrations/SentryCocoaLumberjack/Package.swift +++ b/3rd-party-integrations/SentryCocoaLumberjack/Package.swift @@ -11,8 +11,8 @@ let package = Package( ) ], traits: [ - .default(enabledTraits: ["PrecompiledSentry"]), - .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .default(enabledTraits: ["SentryFromBinary"]), + .init(name: "SentryFromBinary", description: "Use precompiled Sentry binary xcframeworks."), .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") ], dependencies: [ @@ -24,11 +24,11 @@ let package = Package( name: "SentryCocoaLumberjack", dependencies: [ .product(name: "CocoaLumberjackSwift", package: "CocoaLumberjack"), - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), @@ -37,11 +37,11 @@ let package = Package( dependencies: [ "SentryCocoaLumberjack", .product(name: "CocoaLumberjackSwift", package: "CocoaLumberjack"), - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ) diff --git a/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift index 25396118fb1..98793042256 100644 --- a/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift +++ b/3rd-party-integrations/SentryCocoaLumberjack/Sources/SentryTraitValidation.swift @@ -1,3 +1,3 @@ -#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE -#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#if SENTRY_FROM_BINARY && SENTRY_FROM_SOURCE +#error("SentryFromBinary and SentryFromSource are mutually exclusive. Enable only one.") #endif diff --git a/3rd-party-integrations/SentryPulse/Package.swift b/3rd-party-integrations/SentryPulse/Package.swift index d316dcb6786..ab4566881c8 100644 --- a/3rd-party-integrations/SentryPulse/Package.swift +++ b/3rd-party-integrations/SentryPulse/Package.swift @@ -11,8 +11,8 @@ let package = Package( ) ], traits: [ - .default(enabledTraits: ["PrecompiledSentry"]), - .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .default(enabledTraits: ["SentryFromBinary"]), + .init(name: "SentryFromBinary", description: "Use precompiled Sentry binary xcframeworks."), .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") ], dependencies: [ @@ -24,11 +24,11 @@ let package = Package( name: "SentryPulse", dependencies: [ .product(name: "Pulse", package: "Pulse"), - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), @@ -37,11 +37,11 @@ let package = Package( dependencies: [ "SentryPulse", .product(name: "Pulse", package: "Pulse"), - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ) diff --git a/3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift index 25396118fb1..98793042256 100644 --- a/3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift +++ b/3rd-party-integrations/SentryPulse/Sources/SentryTraitValidation.swift @@ -1,3 +1,3 @@ -#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE -#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#if SENTRY_FROM_BINARY && SENTRY_FROM_SOURCE +#error("SentryFromBinary and SentryFromSource are mutually exclusive. Enable only one.") #endif diff --git a/3rd-party-integrations/SentrySwiftLog/Package.swift b/3rd-party-integrations/SentrySwiftLog/Package.swift index cfe9fd5cdd3..d025257366f 100644 --- a/3rd-party-integrations/SentrySwiftLog/Package.swift +++ b/3rd-party-integrations/SentrySwiftLog/Package.swift @@ -11,8 +11,8 @@ let package = Package( ) ], traits: [ - .default(enabledTraits: ["PrecompiledSentry"]), - .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .default(enabledTraits: ["SentryFromBinary"]), + .init(name: "SentryFromBinary", description: "Use precompiled Sentry binary xcframeworks."), .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") ], dependencies: [ @@ -24,11 +24,11 @@ let package = Package( name: "SentrySwiftLog", dependencies: [ .product(name: "Logging", package: "swift-log"), - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), @@ -37,11 +37,11 @@ let package = Package( dependencies: [ "SentrySwiftLog", .product(name: "Logging", package: "swift-log"), - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])) ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ) diff --git a/3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift index 25396118fb1..98793042256 100644 --- a/3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift +++ b/3rd-party-integrations/SentrySwiftLog/Sources/SentryTraitValidation.swift @@ -1,3 +1,3 @@ -#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE -#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#if SENTRY_FROM_BINARY && SENTRY_FROM_SOURCE +#error("SentryFromBinary and SentryFromSource are mutually exclusive. Enable only one.") #endif diff --git a/3rd-party-integrations/SentrySwiftyBeaver/Package.swift b/3rd-party-integrations/SentrySwiftyBeaver/Package.swift index 3746998a268..89137f6f29d 100644 --- a/3rd-party-integrations/SentrySwiftyBeaver/Package.swift +++ b/3rd-party-integrations/SentrySwiftyBeaver/Package.swift @@ -11,8 +11,8 @@ let package = Package( ) ], traits: [ - .default(enabledTraits: ["PrecompiledSentry"]), - .init(name: "PrecompiledSentry", description: "Use precompiled Sentry binary xcframeworks."), + .default(enabledTraits: ["SentryFromBinary"]), + .init(name: "SentryFromBinary", description: "Use precompiled Sentry binary xcframeworks."), .init(name: "SentryFromSource", description: "Build Sentry from source instead of using precompiled binaries.") ], dependencies: [ @@ -23,12 +23,12 @@ let package = Package( .target( name: "SentrySwiftyBeaver", dependencies: [ - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])), .product(name: "SwiftyBeaver", package: "SwiftyBeaver") ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ), @@ -36,12 +36,12 @@ let package = Package( name: "SentrySwiftyBeaverTests", dependencies: [ "SentrySwiftyBeaver", - .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["PrecompiledSentry"])), + .product(name: "Sentry", package: "sentry-cocoa", condition: .when(traits: ["SentryFromBinary"])), .product(name: "SentrySPM", package: "sentry-cocoa", condition: .when(traits: ["SentryFromSource"])), .product(name: "SwiftyBeaver", package: "SwiftyBeaver") ], swiftSettings: [ - .define("SENTRY_PRECOMPILED", .when(traits: ["PrecompiledSentry"])), + .define("SENTRY_FROM_BINARY", .when(traits: ["SentryFromBinary"])), .define("SENTRY_FROM_SOURCE", .when(traits: ["SentryFromSource"])) ] ) diff --git a/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift b/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift index 25396118fb1..98793042256 100644 --- a/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift +++ b/3rd-party-integrations/SentrySwiftyBeaver/Sources/SentryTraitValidation.swift @@ -1,3 +1,3 @@ -#if SENTRY_PRECOMPILED && SENTRY_FROM_SOURCE -#error("PrecompiledSentry and SentryFromSource are mutually exclusive. Enable only one.") +#if SENTRY_FROM_BINARY && SENTRY_FROM_SOURCE +#error("SentryFromBinary and SentryFromSource are mutually exclusive. Enable only one.") #endif From 1f24f20d79be4c6c0352603dea71518183832d3c Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 12 Aug 2026 12:00:53 -0300 Subject: [PATCH 3/4] docs: add changelog entry for SPM traits --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6544d330355..f14dc206317 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Promote `enableStandaloneAppStartTracing` from `options.experimental` to a top-level option on `Options` (#8715) +- Add `SentryFromBinary` (default) and `SentryFromSource` SPM package traits to 3rd-party integrations, allowing users to choose between precompiled xcframeworks and building from source. Requires Swift 6.1+ (#8795) - Add experimental option `enableUIViewControllerInitSwizzling` that defers `UIViewController` swizzling to first instantiation instead of eagerly discovering and swizzling all subclasses at SDK start. This avoids realizing `@available`-gated `UIViewController` subclasses on OS versions below their gate, which crashes apps on start (#8687). - Add screenshot picker to feedback (#8655) - Enable it with `form.enableScreenshot = true` in the `configureForm` callback. From f6ad53a5b80ac2326c3e2f4295437302883c9025 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Wed, 12 Aug 2026 12:12:49 -0300 Subject: [PATCH 4/4] docs: add breaking change warning for Swift 6.1 requirement --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f14dc206317..985adc387ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +> [!WARNING] +> The 3rd-party integration packages (SentryCocoaLumberjack, SentryPulse, SentrySwiftLog, SentrySwiftyBeaver) now require Swift 6.1+ to support SPM package traits. Users on older Swift toolchains should pin to an earlier release of these packages. + ### Features - Promote `enableStandaloneAppStartTracing` from `options.experimental` to a top-level option on `Options` (#8715)