test(🍏): minimal SwiftPM example app and CI job - #4044
Open
chrfalch wants to merge 3 commits into
Open
Conversation
React Native 0.87 ships preview SwiftPM support, and CocoaPods trunk goes read-only in December 2026. A library that ships its own Package.swift is referenced verbatim by autolinking, so this is additive: SwiftPM ignores the podspec and CocoaPods ignores Package.swift. Autolinking exposes the library through a symlink under the app's build directory and resolves the manifest's relative paths against it, so the two React Native package paths are fixed for every standard app. Skia's binaries stay out of the package. The manifest prefers the react-native-skia-apple-ios copy npm already installs for the CocoaPods build and falls back to the published Swift package, so a checkout that has run `yarn install` builds without network access. Two defines the podspec never needed: CocoaPods forces RCT_NEW_ARCH_ENABLED and RCT_REMOVE_LEGACY_ARCH project-wide, and the SwiftPM path defines neither, yet Skia's Apple sources still gate on both. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Covers the React Native 0.87 floor, how autolinking resolves the manifest's relative paths, the two architecture defines CocoaPods supplies but SwiftPM does not, where the binaries come from, and the stale Package.resolved pin that silently keeps the previous binary source when switching between them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A bare React Native 0.87.1 app that consumes @shopify/react-native-skia through Swift Package Manager, with no CocoaPods, plus the CI job that builds it. It is the only thing that exercises packages/skia/Package.swift. Ships no lockfile, so CI installs with `npm install`; react and react-native are pinned exactly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
chrfalch
force-pushed
the
spm-support-example
branch
from
September 3, 2026 09:05
5f6ae3d to
5b215e3
Compare
chrfalch
marked this pull request as ready for review
September 3, 2026 09:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Stacked on #4043, which adds
packages/skia/Package.swift. Nothing exercises that manifest without this PR. It pins a source list, four header search paths, six defines and two relative package paths that hold only because autolinking uses a symlink. Any of those can break on a React Native bump, silently.What is here
spm-example/: a bare React Native 0.87.1 app, no CocoaPods, drawing a Skia canvas, plus thebuild-test-ios-spmjob that installs and builds it.It sits outside the yarn workspace on purpose: SwiftPM needs React Native 0.87 or newer,
apps/exampleis on 0.83.1, and the two resolutions must not collide. It is therefore not a turbo workspace, so rootyarn lintandyarn testdo not reach it.Four deliberate oddities:
reactandreact-nativeare pinned exactly, so the native build stays deterministic and CI installs withnpm install. This keeps a 12,000-line generated file out of review.ios/Podfileis not for CocoaPods. React Native's CLI locates the iOS project by finding a Podfile and taking its directory assourceDir; with none it returnsnull, and bothreact-native spmand the Xcode autolinking phase fail withCLI config did not provide project.ios.sourceDir.userConfig.sourceDironly seeds that search, so config cannot override it. The file installs nothing and callsraise, so a straypod installfails clearly.spm update, notspm add --deintegrate. The.xcodeprojis committed already injected, and an injected project resolves toupdate, which also keeps CocoaPods off the runner.HERMES_CLI_PATHcommitted. React Native 0.87.1's injector writes an absolute path tohermescinto the project. The build does not need it, sincereact-native-xcode.shresolveshermescitself, and committing it would put one developer's disk layout in the repository. The README documents the strip.Test plan
The exact CI sequence, from a clean install:
** BUILD SUCCEEDED **. No CocoaPods invoked, and the Podfile'sraisenever fires.hermescthrough the fallback, confirming the omitted setting is unnecessary.Package.swiftabsent the setup exits 2 — the failure this harness exists to catch.build-test-ios-spmhas never run anywhere before, so this PR is its first run.