Skip to content

feat(SPM): Add package traits for UI framework opt-out and macOS CLI sample#7578

Merged
philprime merged 13 commits intomainfrom
sentry-cocoa-7369
Mar 6, 2026
Merged

feat(SPM): Add package traits for UI framework opt-out and macOS CLI sample#7578
philprime merged 13 commits intomainfrom
sentry-cocoa-7369

Conversation

@philprime
Copy link
Copy Markdown
Member

@philprime philprime commented Mar 3, 2026

Add Swift Package Manager traits support (Swift 6.1+) so compile-from-source users can build without UIKit/AppKit. Introduces Package@swift-6.1.swift with a NoUIFramework trait that sets SENTRY_NO_UI_FRAMEWORK when enabled; single SentrySPM product, no source changes.

Add a macOS command-line tool sample (Samples/macOS-CLI-Xcode) that depends on SentrySPM with the trait enabled. The sample uses a committed .xcodeproj with traits set (XcodeGen does not support traits yet; see yml comment and XcodeGen #1585).

Verification: Without the NoUIFramework trait, the build still succeeds but the binary links AppKit and SwiftUI. With the trait, the binary links only Foundation, CoreFoundation, CoreGraphics, MetricKit, and Swift runtime—no AppKit or UIKit. CI job check-macOS-CLI-Xcode-no-UI-framework builds the sample and runs check-ui-framework-linkage.sh to enforce this.

Check without trait NoUIFramework:

[notice] [16:36:22] Checking AppKit linkage for:
[notice] [16:36:22]  - Configuration:     Debug
[notice] [16:36:22]  - Derived Data Path: /tmp/cli-xcode-build
[notice] [16:36:22]  - Linkage Test:      unlinked
[notice] [16:36:22]  - Module Name:       macOS-CLI-Xcode
[notice] [16:36:22]  - Framework Type:    AppKit
[notice] [16:36:22] Checking build product path: /tmp/cli-xcode-build/Build/Products/Debug/macOS-CLI-Xcode
[notice] [16:36:22] Checking if Sentry build product is linked to AppKit.

== OTool output ==
/tmp/cli-xcode-build/Build/Products/Debug/macOS-CLI-Xcode:
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 2100.41.0)
        /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 4423.1.0)
        /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1356.0.0)
        /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 2685.50.114)
        /System/Library/Frameworks/CoreData.framework/Versions/A/CoreData (compatibility version 1.0.0, current version 1526.0.0)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 4423.1.0)
        /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1965.4.2)
        /System/Library/Frameworks/MetricKit.framework/Versions/A/MetricKit (compatibility version 1.0.0, current version 1.0.0, weak)
        /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.12)
        /usr/lib/swift/libswiftCore.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/swift/libswiftCoreFoundation.dylib (compatibility version 1.0.0, current version 120.100.0, weak)
        /usr/lib/swift/libswiftCoreImage.dylib (compatibility version 1.0.0, current version 2.2.0, weak)
        /usr/lib/swift/libswiftDarwin.dylib (compatibility version 1.0.0, current version 377.100.15)
        /usr/lib/swift/libswiftDispatch.dylib (compatibility version 1.0.0, current version 1542.100.32)
        /usr/lib/swift/libswiftIOKit.dylib (compatibility version 1.0.0, current version 1.0.0, weak)
        /usr/lib/swift/libswiftMetal.dylib (compatibility version 1.0.0, current version 372.12.0, weak)
        /usr/lib/swift/libswiftOSLog.dylib (compatibility version 1.0.0, current version 10.0.0, weak)
        /usr/lib/swift/libswiftObjectiveC.dylib (compatibility version 1.0.0, current version 951.6.0)
        /usr/lib/swift/libswiftQuartzCore.dylib (compatibility version 1.0.0, current version 5.0.0, weak)
        /usr/lib/swift/libswiftSpatial.dylib (compatibility version 1.0.0, current version 1.0.0, weak)
        /usr/lib/swift/libswiftUniformTypeIdentifiers.dylib (compatibility version 1.0.0, current version 877.4.9, weak)
        /usr/lib/swift/libswiftXPC.dylib (compatibility version 1.0.0, current version 128.100.14, weak)
        /usr/lib/swift/libswiftos.dylib (compatibility version 1.0.0, current version 1082.0.0, weak)
        /usr/lib/swift/libswiftsimd.dylib (compatibility version 1.0.0, current version 23.0.0, weak)
        /usr/lib/swift/libswiftFoundation.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/swift/libswiftCoreGraphics.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/swift/libswiftNetwork.dylib (compatibility version 1.0.0, current version 5812.100.255)
        /System/Library/Frameworks/SwiftUI.framework/Versions/A/SwiftUI (compatibility version 1.0.0, current version 7.4.24, weak)
[notice] [16:36:22] Matches: 1
[notice] [16:36:22] Checking if Sentry build product is not linked to AppKit.
[error] [16:36:22] AppKit.framework linkage found, but expected no linkage.

Check with trait NoUIFramework set:

[notice] [16:40:44]  - Configuration:     Debug
[notice] [16:40:44]  - Derived Data Path: /tmp/cli-xcode-build
[notice] [16:40:44]  - Linkage Test:      unlinked
[notice] [16:40:44]  - Module Name:       macOS-CLI-Xcode
[notice] [16:40:44]  - Framework Type:    AppKit
[notice] [16:40:45] Checking build product path: /tmp/cli-xcode-build/Build/Products/Debug/macOS-CLI-Xcode
[notice] [16:40:45] Checking if Sentry build product is linked to AppKit.

== OTool output ==
/tmp/cli-xcode-build/Build/Products/Debug/macOS-CLI-Xcode:
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 2100.41.0)
        /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 4423.1.0)
        /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1356.0.0)
        /System/Library/Frameworks/CoreData.framework/Versions/A/CoreData (compatibility version 1.0.0, current version 1526.0.0)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 4423.1.0)
        /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1965.4.2)
        /System/Library/Frameworks/MetricKit.framework/Versions/A/MetricKit (compatibility version 1.0.0, current version 1.0.0, weak)
        /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.12)
        /usr/lib/swift/libswiftCore.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/swift/libswiftCoreFoundation.dylib (compatibility version 1.0.0, current version 120.100.0, weak)
        /usr/lib/swift/libswiftCoreImage.dylib (compatibility version 1.0.0, current version 2.2.0, weak)
        /usr/lib/swift/libswiftDarwin.dylib (compatibility version 1.0.0, current version 377.100.15)
        /usr/lib/swift/libswiftDispatch.dylib (compatibility version 1.0.0, current version 1542.100.32)
        /usr/lib/swift/libswiftIOKit.dylib (compatibility version 1.0.0, current version 1.0.0, weak)
        /usr/lib/swift/libswiftMetal.dylib (compatibility version 1.0.0, current version 372.12.0, weak)
        /usr/lib/swift/libswiftOSLog.dylib (compatibility version 1.0.0, current version 10.0.0, weak)
        /usr/lib/swift/libswiftObjectiveC.dylib (compatibility version 1.0.0, current version 951.6.0)
        /usr/lib/swift/libswiftQuartzCore.dylib (compatibility version 1.0.0, current version 5.0.0, weak)
        /usr/lib/swift/libswiftSpatial.dylib (compatibility version 1.0.0, current version 1.0.0, weak)
        /usr/lib/swift/libswiftUniformTypeIdentifiers.dylib (compatibility version 1.0.0, current version 877.4.9, weak)
        /usr/lib/swift/libswiftXPC.dylib (compatibility version 1.0.0, current version 128.100.14, weak)
        /usr/lib/swift/libswiftos.dylib (compatibility version 1.0.0, current version 1082.0.0, weak)
        /usr/lib/swift/libswiftsimd.dylib (compatibility version 1.0.0, current version 23.0.0, weak)
        /usr/lib/swift/libswiftFoundation.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/swift/libswiftCoreGraphics.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/swift/libswiftNetwork.dylib (compatibility version 1.0.0, current version 5812.100.255)
[notice] [16:40:45] Matches: 0
[notice] [16:40:45] Checking if Sentry build product is not linked to AppKit.
[notice] [16:40:45] Success! AppKit.framework not linked.

Closes #7369

@philprime philprime self-assigned this Mar 3, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (SPM) Add package traits for UI framework opt-out and macOS CLI sample by philprime in #7578

Bug Fixes 🐛

  • Capture transactions during launch profiling window by philipphofmann in #7602

Internal Changes 🔧

Samples

  • Restructure watchOS-Swift sample by philprime in #7614
  • Restructure visionOS-Swift sample by philprime in #7616
  • Restructure visionOS-SwiftUI-SPM sample by philprime in #7615

Other

  • (test-samples) Restructure SwiftUITestSample and SwiftUICrashTest by philprime in #7612

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against af51c99

Comment thread .gitignore Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.318%. Comparing base (8b755b3) to head (af51c99).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##              main     #7578       +/-   ##
=============================================
+ Coverage   85.314%   85.318%   +0.003%     
=============================================
  Files          483       483               
  Lines        28750     28751        +1     
  Branches     12492     12496        +4     
=============================================
+ Hits         24528     24530        +2     
+ Misses        4177      4174        -3     
- Partials        45        47        +2     

see 5 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8b755b3...af51c99. Read the comment docs.

@philprime philprime added the ready-to-merge Use this label to trigger all PR workflows label Mar 3, 2026
@philprime
Copy link
Copy Markdown
Member Author

@sentry review

philprime added a commit that referenced this pull request Mar 3, 2026
…wift-6.1.swift in version bump script

Correct the Xcode version in the changelog entry for the NoUIFramework trait from 26.2 to 26.4. Additionally, include Package@swift-6.1.swift in the version bump script to ensure proper handling of Swift 6.1+ builds.

Refs #7578
@philprime philprime marked this pull request as ready for review March 3, 2026 16:32
@philprime philprime enabled auto-merge (squash) March 3, 2026 16:33
Comment thread Makefile
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1223.70 ms 1257.76 ms 34.06 ms
Size 24.14 KiB 1.12 MiB 1.10 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
bed2eb7 1215.88 ms 1247.14 ms 31.27 ms
47c9f79 1216.57 ms 1240.94 ms 24.37 ms
b882255 1216.49 ms 1253.66 ms 37.17 ms
dbfeb41 1215.17 ms 1237.41 ms 22.23 ms
bb418da 1227.60 ms 1265.90 ms 38.30 ms
c424b6a 1220.38 ms 1248.18 ms 27.80 ms
70fb69e 1230.45 ms 1257.00 ms 26.55 ms
98a16ef 1227.45 ms 1258.19 ms 30.74 ms
e01eafa 1223.36 ms 1252.43 ms 29.07 ms
b984142 1219.17 ms 1250.17 ms 31.00 ms

App size

Revision Plain With Sentry Diff
bed2eb7 24.14 KiB 1.07 MiB 1.04 MiB
47c9f79 24.14 KiB 1.09 MiB 1.06 MiB
b882255 24.14 KiB 1.12 MiB 1.09 MiB
dbfeb41 24.14 KiB 1.04 MiB 1.02 MiB
bb418da 24.14 KiB 1.04 MiB 1.02 MiB
c424b6a 24.14 KiB 1.06 MiB 1.04 MiB
70fb69e 24.14 KiB 1.11 MiB 1.09 MiB
98a16ef 24.14 KiB 1.09 MiB 1.07 MiB
e01eafa 24.14 KiB 1.07 MiB 1.04 MiB
b984142 24.14 KiB 1.11 MiB 1.09 MiB

Previous results on branch: sentry-cocoa-7369

Startup times

Revision Plain With Sentry Diff
88d0ca1 1215.96 ms 1250.54 ms 34.59 ms
9da863e 1223.27 ms 1258.53 ms 35.26 ms
6bd7987 1208.81 ms 1235.45 ms 26.64 ms

App size

Revision Plain With Sentry Diff
88d0ca1 24.14 KiB 1.12 MiB 1.10 MiB
9da863e 24.14 KiB 1.12 MiB 1.10 MiB
6bd7987 24.14 KiB 1.12 MiB 1.09 MiB

Comment thread Package@swift-6.1.swift
@philprime philprime disabled auto-merge March 5, 2026 10:04
philprime and others added 9 commits March 5, 2026 11:08
…sample

Add Package@swift-6.1.swift with NoUIFramework trait so SPM compile-from-source
users can build without UIKit/AppKit (e.g. macOS/Linux CLIs). Trait maps to
SENTRY_NO_UI_FRAMEWORK; no source changes. Add macOS-CLI-Xcode sample (xcodegen
+ .xcodeproj with traits), Makefile targets and post-step to inject traits after
xcodegen until XcodeGen supports them. Track .xcodeproj; ignore only xcuserdata.

Refs #7369
…trait injection

Build workflow: select Xcode 26.4 for ios-swift-release and build-sample-spm
(required for Swift 6.1 package traits). Add build-sample-macOS-CLI-Xcode to
the SPM sample matrix. Makefile: remove xcodegen and perl trait injection from
build-sample-macOS-CLI-Xcode; use committed .xcodeproj only.

Refs #7369
…ecutables

Add dedicated check-macOS-CLI-Xcode-no-UI-framework job on macos-26 with
Xcode 26.4. Builds the sample and verifies the binary does not link
AppKit or UIKit. Extend check-ui-framework-linkage.sh to support bare
executables (not just .framework bundles).

Refs #7369
Add Unreleased changelog entry for NoUIFramework trait with usage
instructions: Swift 6.1+, Xcode setup, SentrySPM product, and sample
reference.

Refs #7369
Swift 6.1+ uses Package@swift-6.1.swift instead of Package.swift.
prepare-package.sh only modifies Package.swift, so when the 6.1
manifest exists it was used unmodified, causing 'Multiple commands
produce Sentry.framework' from conflicting binary targets.

Temporarily rename Package@swift-6.1.swift so the stripped
Package.swift is used.

Refs #7369
…wift-6.1.swift in version bump script

Correct the Xcode version in the changelog entry for the NoUIFramework trait from 26.2 to 26.4. Additionally, include Package@swift-6.1.swift in the version bump script to ensure proper handling of Swift 6.1+ builds.

Refs #7578
Extend all 4 "Prepare Package.swift" steps in release.yml to also
process Package@swift-6.1.swift. This ensures binary targets are
properly prepared for both package manifests during release
validation.

Addresses review feedback from philipphofmann.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Log source/target versions, per-file replacement counts, and
warnings when a file is left unchanged during update. On verify
failures, print the regex used and versions found vs expected.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread .github/workflows/build.yml
Update binary target URLs and checksums from 9.5.1 to 9.6.0 to
match Package.swift after rebasing on main.
@philprime philprime force-pushed the sentry-cocoa-7369 branch from f99e696 to e06426f Compare March 5, 2026 10:10
After rebasing on main, the entry landed under the released 9.6.0
section. Move it to Unreleased where it belongs.
@philprime philprime requested a review from philipphofmann March 5, 2026 10:32
@philprime philprime enabled auto-merge (squash) March 5, 2026 10:32
Copy link
Copy Markdown
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

Comment thread Samples/macOS-CLI-Xcode/Sources/main.swift Outdated
Comment thread CHANGELOG.md Outdated
Comment thread CHANGELOG.md
Refine changelog entry for NoUIFramework trait by removing reference to macOS CLI sample. Update the DSN in the macOS CLI sample to a valid Sentry endpoint for improved functionality.
philprime added a commit to getsentry/sentry-docs that referenced this pull request Mar 6, 2026
Add documentation for the new NoUIFramework Swift Package Manager trait
that allows building the Sentry SDK without UIKit or AppKit linkage.
Covers both Xcode UI setup and Package.swift configuration using the
SentrySPM compile-from-source product.

Refs getsentry/sentry-cocoa#7578
Co-Authored-By: Claude <noreply@anthropic.com>
@sentry
Copy link
Copy Markdown

sentry Bot commented Mar 6, 2026

Sentry Build Distribution

App Version Configuration
SDK-Size 9.6.0 (1) Release

Copy link
Copy Markdown
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again, LGTM

@philprime philprime merged commit 20ff716 into main Mar 6, 2026
252 of 256 checks passed
@philprime philprime deleted the sentry-cocoa-7369 branch March 6, 2026 12:43
philprime added a commit to getsentry/sentry-docs that referenced this pull request Mar 16, 2026
## DESCRIBE YOUR PR

Document the new `NoUIFramework` Swift Package Manager trait added in
getsentry/sentry-cocoa#7578. This trait lets compile-from-source users
build the Sentry SDK without UIKit or AppKit linkage — useful for
command-line tools, headless servers, and other non-UI contexts.

Adds a "Building Without UIKit or AppKit" section to the SPM install
page covering:
- Requirements (Swift 6.1+, Xcode 26.4+)
- Xcode UI setup (selecting `SentrySPM` product, enabling the trait)
- `Package.swift` configuration with a runnable example
- Note explaining why `SentrySPM` (compile-from-source) is needed

Refs getsentry/sentry-cocoa#7578

## IS YOUR CHANGE URGENT?

- [ ] Urgent deadline (GA date, etc.):
- [ ] Other deadline:
- [x] None: Not urgent, can wait up to 1 week+

## PRE-MERGE CHECKLIST

- [x] Checked Vercel preview for correctness, including links
- [x] PR was reviewed and approved by any necessary SMEs (subject matter
experts)
- [ ] PR was reviewed and approved by a member of the [Sentry docs
team](https://github.com/orgs/getsentry/teams/docs)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Use this label to trigger all PR workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract all code using UIKit into separate module / Swift target

2 participants