[4/4] feat(plugin): Auto-install Sentry Cocoa when the spm4Kmp plugin is applied#559
[4/4] feat(plugin): Auto-install Sentry Cocoa when the spm4Kmp plugin is applied#559buenaflor wants to merge 9 commits into
Conversation
2b44fe4 to
0fca03c
Compare
281033d to
2212073
Compare
0fca03c to
df55744
Compare
2212073 to
e81481d
Compare
df55744 to
9ead63f
Compare
cbfc489 to
d156da3
Compare
9ead63f to
50ba5fb
Compare
d156da3 to
fcb454f
Compare
When a consumer applies the spm4Kmp plugin (io.github.frankois944.spmForKmp)
alongside the Sentry KMP Gradle plugin, the matching Sentry Cocoa version is now
added to their Apple targets automatically, so they no longer declare the Sentry
Swift package manually or rely on the fragile DerivedData framework linker.
- Add Spm4KmpAutoInstallExtension (enabled + sentryCocoaVersion, default
BuildConfig.SentryCocoaVersion), exposed as sentryKmp { autoInstall.spm { } }
- installSentryForSpm4Kmp adds remotePackageVersion(getsentry/sentry-cocoa,
products = { add("Sentry") }) to each Apple target via swiftPackageConfig
(link-only: the published SDK klib already carries the Sentry cinterop bindings)
- Register during the configuration phase via plugins.withId, since spm4Kmp
consumes swiftPackageConfig before afterEvaluate; idempotent + opt-out guarded
- Skip the manual CocoaFrameworkLinker when CocoaPods or spm4Kmp is applied;
the linker stays as the fallback for plain SPM-in-Xcode consumers
- compileOnly against the spm4Kmp DSL (gradlePluginPortal); request Java 17 deps
on the compile/test classpaths while keeping Java 11 plugin bytecode
- Convert the kmp-app-spm sample to apply spm4Kmp and use the auto-install
- Tests + README/migration docs
Verified: plugin compileKotlin + test, sample iOS link generates its own
sentryCocoa cinterop, SPM sample xcodebuild BUILD SUCCEEDED, spotless/detekt green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Align the plugin's compileOnly spm4Kmp DSL dependency with the SDK's Config.spmForKmpVersion (1.9.3), which adds watchosArm32 (armv7k) support. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fcb454f to
baa8214
Compare
d61ecb5 to
7e84b40
Compare
…lugin-autoinstall # Conflicts: # sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/AutoInstallExtension.kt # sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryPlugin.kt
…lugin-autoinstall
…ample With the spm4Kmp auto-install in place, the static Sentry product is linked into the dynamic shared.framework (all Sentry ObjC classes are defined symbols there), so embedding Sentry-Dynamic in the iosApp would load a second copy of every Sentry class at runtime. Remove the XCRemoteSwiftPackageReference, its Package.resolved pins, and the pbxproj editing in update-cocoa.sh; the Sentry Cocoa version is now single-sourced from Config.kt and the plugin's gradle.properties. Verified via xcodebuild (BUILD SUCCEEDED) and a simulator launch of the sample app. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds spm4Kmp-aware auto-installation to the Sentry Kotlin Multiplatform Gradle plugin so that, when io.github.frankois944.spmForKmp is applied, the plugin automatically registers the matching getsentry/sentry-cocoa Swift package for Apple targets (removing the need for manual Xcode SwiftPM setup / brittle DerivedData searching).
Changes:
- Introduces
Spm4KmpAutoInstallExtensionand wires it intosentryKmp.autoInstall(plus a top-levelspmextension). - Adds
installSentryForSpm4Kmpand integrates it viaplugins.withId(...)so configuration happens during Gradle configuration phase. - Updates the SPM sample + docs/changelog + update script to rely on the new auto-install path.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| sentry-samples/kmp-app-spm/shared/build.gradle.kts | Applies spm4Kmp plugin in the sample to exercise auto-install. |
| sentry-samples/kmp-app-spm/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved | Removes Xcode SwiftPM lockfile (no longer needed if Xcode project no longer declares Sentry package). |
| sentry-samples/kmp-app-spm/iosApp.xcodeproj/project.pbxproj | Removes the Xcode SwiftPM sentry-cocoa reference + Sentry-Dynamic framework dependency. |
| sentry-samples/kmp-app-spm/iosApp.xcodeproj/.swiftpm/xcode/package.xcworkspace/xcshareddata/swiftpm/Package.resolved | Removes generated SwiftPM lockfile under .swiftpm. |
| sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryPluginTest.kt | Adds unit tests for the new spm extension + spm4Kmp install behavior. |
| sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/Spm4KmpAutoInstallExtension.kt | New extension for spm4Kmp auto-install configuration. |
| sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryPlugin.kt | Implements spm4Kmp auto-install + adjusts DerivedData linker skipping behavior. |
| sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/AutoInstallExtension.kt | Adds spm to the auto-install configuration surface. |
| sentry-kotlin-multiplatform-gradle-plugin/settings.gradle.kts | Adds gradlePluginPortal() to resolve spm4Kmp marker/DSL for compileOnly. |
| sentry-kotlin-multiplatform-gradle-plugin/gradle/libs.versions.toml | Adds spm4Kmp dependency coordinates/version. |
| sentry-kotlin-multiplatform-gradle-plugin/build.gradle.kts | Adds compileOnly/test dependency on spm4Kmp and requests Java 17 variants on build classpaths. |
| scripts/update-cocoa.sh | Stops updating Xcode project SwiftPM pins; version now flows via Gradle plugin config. |
| README.md | Documents spm4Kmp auto-install usage. |
| CHANGELOG.md | Adds unreleased changelog entry for spm4Kmp auto-install feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| name = iosApp; | ||
| packageProductDependencies = ( | ||
| 24E1CB3E2C17E00200F78D70 /* Sentry-Dynamic */, | ||
| ); | ||
| productName = NSExceptionKtSample; |
There was a problem hiding this comment.
The diff is correct; the description was stale. spm4Kmp links the static Sentry product into the dynamic shared.framework, so the iosApp no longer needs its own sentry-cocoa package reference (validated by the sample xcodebuild). PR description updated.
…-out Address review feedback on the spm4Kmp auto-install: - Gate the spm4Kmp install on both the spm4Kmp and Kotlin Multiplatform plugins via nested plugins.withId, so applying KMP after spm4Kmp no longer silently skips the Sentry Swift package registration. - Skip the manual DerivedData fallback linker only when the Sentry Swift package is actually registered with spm4Kmp (auto-installed or user-defined sentryCocoa config), instead of whenever the spm4Kmp plugin is applied. Consumers that use spm4Kmp for other packages but opt out of the Sentry spm auto-install keep the fallback linker. - Document that the sentryKmp spm opt-out and version override must be configured before the kotlin block declares Apple targets, since the Swift package is registered at target creation time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lugin-autoinstall # Conflicts: # CHANGELOG.md
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 127c49c. Configure here.
…ageConfig container
The spm4Kmp auto-install skipped targets based on a sentryCocoa cinterop
on the main compilation, but spm4Kmp creates that cinterop only in its
own afterEvaluate and capitalizes the name (SentryCocoa), so the check
could never match a user-defined Sentry Swift package config. Check the
spm4Kmp swiftPackageConfig container instead (global sentryCocoa entry
or per-target sentryCocoa_<Target> key), which exists from the moment
the config is declared.
Also warn when the spm auto-install opt-out is configured after the
kotlin { } block: the Swift package is registered at target creation,
so a late opt-out (including the global autoInstall.enabled flag) is
read too late to take effect. Document this on AutoInstallExtension and
in the README.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Phase 4 of the stacked spm4Kmp migration (stacked on #560). Adds an spm4Kmp auto-install path to the Sentry Kotlin Multiplatform Gradle plugin: when a consumer applies the spm4Kmp plugin (
io.github.frankois944.spmForKmp) alongside the Sentry plugin, the matching Sentry Cocoa version is added to their Apple targets automatically.Why: SPM consumers previously had to add the Sentry Swift package to Xcode themselves and the plugin resolved the framework via a fragile DerivedData search (
CocoaFrameworkLinker). Mirroring the existing CocoaPods auto-install, detecting spm4Kmp lets the plugin declare the correctly-versioned Sentry package so spm4Kmp fetches and links it, removing the manual step and the brittle path resolution.What changed:
Spm4KmpAutoInstallExtension(enabled+sentryCocoaVersion, defaulting toBuildConfig.SentryCocoaVersion), exposed assentryKmp { autoInstall.spm { ... } }and registered as thespmextension.installSentryForSpm4KmpaddsremotePackageVersion(getsentry/sentry-cocoa, products = { add("Sentry") })to each Apple target viaswiftPackageConfig(cinteropName = "sentryCocoa"). Link-only (exportToKotlin = false) because the published SDK klib already carries the Sentry cinterop bindings; consumers only need the framework at link time. Idempotent and opt-out guarded.plugins.withIdon both the spm4Kmp and Kotlin Multiplatform plugins, so it is robust to plugin application order (spm4Kmp consumesswiftPackageConfigbeforeafterEvaluate, so an afterEvaluate registration is too late — confirmed by the sample initially generating nosentryCocoatasks).CocoaFrameworkLinkeris skipped when CocoaPods is applied or when the Sentry Swift package is actually registered with spm4Kmp (auto-installed or user-definedsentryCocoaconfig). Merely applying spm4Kmp for other Swift packages with the Sentry spm auto-install opted out keeps the fallback linker active for plain SPM-in-Xcode consumers.sentryKmpspm opt-out/version override must precede thekotlin {}block; documented in the README and the extension KDoc.compileOnlydependency on the spm4Kmp DSL (resolved fromgradlePluginPortal()); the compile/test classpaths request Java 17-compatible variants (spm4Kmp ships Java 17) while the plugin keeps emitting Java 11 bytecode, so non-spm4Kmp consumers stay on JDK 11. The linker check deliberately uses only Gradle core types so spm4Kmp classes are never touched unless the consumer applies the plugin.kmp-app-spmsample to apply spm4Kmp and rely on the auto-install. The iosApp's Xcode-sidesentry-cocoapackage reference was removed: spm4Kmp links the staticSentryproduct into the dynamicshared.framework, so the app no longer needs its own Sentry package dependency.Of note for review: the configuration-phase registration via nested
plugins.withId(timing-sensitive) and the link-onlyadd("Sentry")choice — both validated by the samplexcodebuild(BUILD SUCCEEDED) and the sample generating its ownsentryCocoacinterop.Verification: plugin
compileKotlin+test(101 tests),:sentry-samples:kmp-app-spm:shared:linkDebugFrameworkIosSimulatorArm64, SPM samplexcodebuild(BUILD SUCCEEDED),spotlessApply/detekt/apiCheckgreen.Made with Cursor