Skip to content

fix(ios): unlink kits dropped from $RNMParticleSPMKits - #455

Merged
thomson-t merged 2 commits into
mainfrom
fix/spm-kit-list-changes
Oct 20, 2026
Merged

thomson-t merged 2 commits into
mainfrom
fix/spm-kit-list-changes

Conversation

@thomson-t

@thomson-t thomson-t commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Why

Apps that take the mParticle SDK from Swift Package Manager choose their integration kits in one list in their iOS dependency file. Today, changing that list only ever adds: a kit taken off the list stays in the app, and moving a kit to another major version keeps the old one. The app then ships a kit its team removed, or the wrong version of it, with no warning. Separately, the automated tests for embedded placements never ran on pull requests, although the next major release changes how those placements are found. Once this lands, the standard kits an app links follow the list as it changes, and those tests run on every pull request.

Programme

Follow-up to a post-merge review of react-native-mparticle#436, which made Swift Package Manager the iOS default for the next major release.

What changes

Before: pod install added each kit listed in $RNMParticleSPMKits to the app target and never removed one. Taking mParticle-Rokt off the list left it linked. Switching mParticle-Braze-14 to mParticle-Braze-17 added the new repository but kept linking the old one, because both provide the product mParticle-Braze.

After: each pod install points every listed product at its configured package, unlinks any kit from ios/mparticle_spm_kits.json that the list does not include, and removes that package reference once no target links it. Each change is printed. Packages from any other URL are never removed or replaced: if one already provides a listed kit's product, such as a fork added by hand, pod install stops and says so. Listing two kits with the same product also stops pod install; a kit listed twice is linked once. A second pod install leaves the project byte-identical. CI now runs these tests in the SPM leg, and both iOS legs run the embedded-placement tests (RNMPRoktPlaceholderTests).

The README's "What pod install changes" paragraph and two troubleshooting entries moved with it. The changelog is generated from commit titles at release, so it is not edited here.

Start with link_packages in ios/mparticle_spm.rb, then scripts/ios/mparticle_spm_test.rb. Check MANAGED_URLS first: only the core and the kit table's URLs are ever unlinked or re-pointed. Deliberately left alone: a kit given by url: that is taken off the list stays linked, because it cannot be told apart from a package added by hand (documented in the README); the opt-out path still only warns; and making iOS Sample App (SPM) a required check is a repository setting, not part of this pull request.

Linked work

Related: react-native-mparticle#436, the change these fixes follow up.

Rollout

Path: merging publishes nothing. The fix ships in the next major release of the npm package, the first with Swift Package Manager as the default; no published version contains the defect. The CI change applies to pull requests as soon as this merges.
Feature flags: none.
Turning it off: revert this pull request before the release; after it, the next release, since a published version cannot be recalled. Apps that already ran pod install keep the project edits it made, which appear in their own project diff.
What we watch: the iOS Sample App (SPM) check, which now runs the helper tests and the placeholder tests and passes locally today; any failure there blocks the merge. After the release, new GitHub issues about pod install removing a package; one report of a package removed that should have stayed means a patch release. Settled when the release has been out for a month without one.

Risks

  • An app added one of the table's kits by hand without listing it, and loses it on pod install; the migration guide already tells apps to list kits rather than add them by hand, and each removal prints a line naming the kit; seen in pod install output and the project diff the app commits.
  • A package another target still uses is removed; a reference goes only once no target links it, covered by a test; seen as a build failure in that target.
  • A fork of a kit added by hand is silently replaced; pod install stops with an error naming the fork instead, covered by a test; seen as a pod install failure with that message.
  • An app that lists two major versions of one kit now fails pod install; the error and a README entry say to list one; seen as a pod install failure.
  • A kit given by url: and then taken off the list stays linked; not addressed, because it cannot be told apart from a package added by hand, and the README says to remove it in Xcode; seen as no removal line in pod install output and the kit still under the app target's frameworks.
  • A CocoaPods or xcodeproj release changes the project-object API this relies on; the new tests run in CI against the CocoaPods version the sample resolves, 1.15.2 today; seen as a failing SPM leg.
  • Four placeholder tests wait on timers of up to half a second and could be flaky on slow CI runners; the suite took about 1.1 seconds locally; seen as an intermittent iOS failure.

Risk class: low.

Who

Written by: an automated coding agent (Claude Code), from a post-merge review of #436 that the maintainer handed over.
Code reviewed before opening: a separate automated review agent, on 20 October 2026. It found that a hand-added package with a listed kit's product would be silently replaced, that a kit listed twice failed pod install, and that reference removals were not printed; all three were fixed and are covered by tests.
Design reviewed before opening: no one.
Decision this implements: the post-merge review findings on #436 of 20 October 2026 (not public).
Checked: on 20 October 2026, the new Ruby tests failed on main for kit removal and switching, and all 7 pass with this change. A real pod install on the sample app in Swift Package Manager mode, stepping the kit list through mParticle-Rokt, mParticle-Braze-14, mParticle-Braze-17, none and mParticle-Rokt twice, printed each change, and the last run left the project byte-identical. The sample's native tests in Swift Package Manager mode on an iOS 18.6 simulator with Xcode 27: 55 ran, none failed; the placeholder suite passed 14 and skipped 1, its legacy-architecture-only test. Also 39 JavaScript tests, both TypeScript checks, ESLint and Trunk.
Not checked: the CocoaPods leg of the native tests, which CI runs; CocoaPods 1.16 (local and CI runs both used 1.15.2, because the sample's Gemfile keeps xcodeproj below 1.26); an Expo prebuild without --clean, which goes through the same pod install hook.

Size

Hand-written: 196 added and 5 removed lines in 4 files, 128 of them the new test.
Generated: none.

Notes for reviewers

Files: ios/mparticle_spm.rb (the fix), scripts/ios/mparticle_spm_test.rb (new minitest suite, run from sample/ with bundle exec ruby ../scripts/ios/mparticle_spm_test.rb; not shipped in the npm package), .github/workflows/pull-request.yml (Ruby test step in the SPM leg; RNMPRoktPlaceholderTests added to -only-testing), README.md.

pod install output on the sample, one run per kit list:

=== ['mParticle-Braze-14']
[mParticle] MParticleSample <- mParticle-Braze 9.6.1
[mParticle] MParticleSample -x mParticle-Rokt (not in $RNMParticleSPMKits)
[mParticle] Removed the unused Swift package https://github.com/mparticle-integrations/mp-apple-integration-rokt
=== ['mParticle-Braze-17']
[mParticle] MParticleSample <- mParticle-Braze 9.6.1
[mParticle] Removed the unused Swift package https://github.com/mparticle-integrations/mparticle-apple-integration-braze-14
=== []
[mParticle] MParticleSample -x mParticle-Braze (not in $RNMParticleSPMKits)
[mParticle] Removed the unused Swift package https://github.com/mparticle-integrations/mparticle-apple-integration-braze-17
=== ['mParticle-Rokt']
[mParticle] MParticleSample <- mParticle-Rokt 9.6.1
=== ['mParticle-Rokt']
(project unchanged)

🤖 Generated with Claude Code

thomson-t and others added 2 commits October 20, 2026 14:51
pod install added the listed kits to the app target but never removed
one. Taking a kit off $RNMParticleSPMKits left it linked, and switching
to another major version of a kit, such as mParticle-Braze-14 to
mParticle-Braze-17, kept the old repository, because both share the
product name mParticle-Braze.

Now each pod install points a listed product at its configured package,
unlinks any product from ios/mparticle_spm_kits.json that is not listed,
and removes those package references once no target links them. It
prints each change. Packages from other URLs, such as hand-added ones or
kits given by url:, are never removed or replaced: if one already
provides a listed kit's product, pod install stops and says so. Listing
two kits with the same product also stops pod install, instead of
switching between them on each run; a kit listed twice is linked once.

scripts/ios/mparticle_spm_test.rb covers removal, switching, repeat
installs, hand-added packages and other targets' references, and runs in
the SPM CI leg.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
RNMPRoktPlaceholderTests is compiled into the sample's test target but
was never in the -only-testing list, so neither iOS leg ran it, though
the next major release changes how placeholders resolve. Both legs now
run it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@thomson-t
thomson-t requested a review from a team as a code owner October 20, 2026 18:55
Copilot AI balanced review requested due to automatic review settings October 20, 2026 18:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No blocking issues were identified, and focused regression coverage supports the reconciliation behavior and package safeguards.

No open issues 🎉

What changed in this PR

Aligns iOS Swift Package Manager kit links with $RNMParticleSPMKits, following the move to SPM by default.

Changes:

  • Removes unlisted managed kits and relinks changed packages while protecting unmanaged packages.
  • Adds regression tests and enables helper and embedded-placement tests in CI.
  • Documents removal behavior and configuration errors.
File Description
scripts/​ios/​mparticle_spm_test.rb Tests kit reconciliation, safeguards, and repeat-install stability.
README.md Explains package cleanup and troubleshooting.
ios/​mparticle_spm.rb Reconciles kit links and removes unused managed references.
.github/​workflows/​pull-request.yml Runs helper and placeholder tests.

Review effort: Balanced

@thomson-t
thomson-t merged commit 392e769 into main Oct 20, 2026
13 checks passed
@thomson-t
thomson-t deleted the fix/spm-kit-list-changes branch October 20, 2026 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants