Conversation
PR SummaryLow Risk Overview When Also updates the Reviewed by Cursor Bugbot for commit af231a4. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation is consistent, validated, documented, and adequately covered by targeted tests.
Review effort: Balanced
Findings: None
What changed in this PR
Adds Expo config-plugin support for selecting Swift Package Manager for iOS mParticle dependencies while preserving CocoaPods as the default.
Changes:
- Adds SPM plugin options, validation, Podfile generation, and idempotent updates.
- Defaults kit versions to the core SDK version.
- Adds tests and documentation for configuration and migration.
| File | Description |
|---|---|
README.md |
Documents Expo SPM options and usage. |
plugin/src/withMParticleIOS.ts |
Implements CocoaPods/SPM Podfile configuration. |
plugin/src/withMParticle.ts |
Defines the new plugin options and kit type. |
js/__tests__/plugin-ios-spm.test.ts |
Tests generation, validation, and idempotency. |
ios/mparticle_spm.rb |
Applies the core version to unversioned kits. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
With `iosDependencyManager: 'spm'`, the plugin turns on the pod's Swift Package Manager mode and calls mparticle_spm_post_install in post_install. It requires the helper through node resolution and skips the dynamic pre_install hook and the kit pods. iosKits names map to their Swift packages (mParticle-Rokt today); other kits go in iosSpmKits, and iosSdkVersion pins the core. Values are validated before they are written into the Podfile. The default, 'cocoapods', produces exactly the Podfile it did before. The Podfile edits move into an exported applyMParticlePodfileMods so jest can cover both modes. The helper now gives a kit without a version the core's version, since mParticle kits release in lockstep with the core. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
6802b77 to
af231a4
Compare
Why
Expo apps configure this package through its config plugin rather than by editing the Podfile, and Expo regenerates the native iOS project on every clean prebuild. So the opt-in Swift Package Manager mode from the previous pull request is out of reach for them unless the plugin can switch it on. Once this lands, an Expo app sets one option in
app.jsonand gets the mParticle SDK and its kits from Swift Package Manager, with a single copy of each. Apps that don't set it get exactly the project they get today.Programme
Part of the plan to support Swift Package Manager in this package before the CocoaPods central repository becomes read-only on 2026-12-02 (CocoaPods announcement). This is the fourth of eight pull requests, all merging into the
workstation/spm-migrationbranch, which merges intomainonce the series is complete, and shipping together in one release; the plan record is internal and cannot be linked here.What changes
Before: the plugin always adds the mParticle dynamic-framework
pre_installhook and onepodline periosKitsentry.After: a new plugin option,
iosDependencyManager, takes'cocoapods'(the default, unchanged) or'spm'. With'spm', the plugin:mparticle_spm_post_installinpost_install, with one entry per kit;pre_installhook.Two supporting options:
iosSdkVersionpins the core SDK exactly, andiosSpmKitslists kits as{ url, product, version? }.iosKitsnames are mapped to their Swift packages (mParticle-Rokttoday); any other name fails prebuild with a message that points toiosSpmKits. Values are checked before they are written into the Podfile. Re-running prebuild adds nothing twice, and replaces the helper call when the settings change.A small helper change: a kit given without a version now gets the core SDK's version, since mParticle kits are released together with the core. The README documents the three options, the helper change, and that switching modes needs
expo prebuild --clean. The changelog is generated by the release-draft workflow.Start reading at
applyMParticlePodfileModsinplugin/src/withMParticleIOS.ts. The CocoaPods branch is the previous code, unchanged, moved into this exported function so jest can test it.Linked work
Depends on: the opt-in Swift Package Manager mode (branch
thomson-t/spm-03-spm-core-mode), whose helper this calls; merge that first.Unblocks: the Swift layer (branch
thomson-t/spm-05-swift-rokt-bridge).Related: #429, later in this series, makes
'spm'the default and maps every kit of the mParticle Apple SDK iniosKits.Rollout
Path: this merges into
workstation/spm-migration, notmain, so nothing reachesmainor a release until the whole series has merged there and that branch is merged intomain. It then ships in the next release.Feature flags: the plugin option
iosDependencyManager,'cocoapods'by default. An app's developer sets'spm'and runsnpx expo prebuild --clean.Turning it off: an app sets
'cocoapods'(or removes the option) and runsnpx expo prebuild --clean. For the package, reverting this pull request and releasing again removes the option in the next version.What we watch: this repository's issues, for Expo prebuild errors or duplicate-SDK reports from Expo apps.
Risks
app.jsoncould inject Ruby into the generated Podfile; prevented because URLs must behttps://with no quotes, and names and versions are limited to letters, digits and._+-, with a test that a quote is rejected; we would see a prebuild error naming the value.iosKitsname would silently add nothing in this mode; prevented because prebuild fails with a message naming the kit andiosSpmKits; we would see that message.pod install, and the README says to prebuild with--clean; we would see that error.iosKitsandiosSpmKitsgets the last entry's version; not addressed, because it is an unlikely misconfiguration; we would see an unexpected kit version.Risk class: low.
Who
Written by: an automated coding agent (Claude Code), at an engineer's request, following the internal Swift Package Manager migration plan.
Code reviewed before opening: an independent review agent reviewed the change before it was committed; its advisory about switching modes led to the README note.
Design reviewed before opening: the requesting engineer approved the migration plan, which specifies these options and the node-resolved helper path.
Decision this implements: the requesting engineer's approval of the migration plan on 2026-09-28; the record is internal and cannot be linked.
Checked: on 2026-09-28:
jest: 33 tests, including 7 new ones for the Podfile changes, all passing.ExpoTestApp(Expo 57, React Native 0.86.3, New Architecture) in'spm'mode, both without and withuseFrameworks: 'static':expo prebuild --cleanlinked the core and the Rokt kit as Swift packages, with no mParticle pods;'cocoapods'mode, the generated Podfile is byte-identical to the one from the published 3.4.0 plugin.Not checked: Xcode 16; Expo's own Swift Package Manager autolinking preview; Objective-C AppDelegate templates in
'spm'mode (Expo 52, below the supported range).Size
Hand-written: about 410 lines added and 53 removed in 5 files; 163 of the added lines are tests.
Generated: none.
🤖 Generated with Claude Code