fix(ci): disable SPM at CI level instead of via pubspec flag - #2675
Conversation
The `flutter > config > enable-swift-package-manager: false` pubspec key introduced in #2672 was only added in Flutter ~3.38, so the sample_app's pubspec failed to parse under Flutter 3.27.4 — the legacy floor pinned by `legacy_version_analyze.yml`. Bootstrap failed with: Unexpected child "config" found under "flutter". Drop the pubspec key and instead run `flutter config --no-enable-swift-package-manager` in the two codesigned-iOS workflows that actually need it (distribute_internal, distribute_external). The PR-validation `build (ios) no_codesign:true` path doesn't hit SPM signing errors and doesn't need the disable. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
📝 WalkthroughWalkthroughConfiguration for disabling Swift Package Manager is migrated from the ChangesSwift Package Manager Configuration Migration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2675 +/- ##
=======================================
Coverage 65.27% 65.27%
=======================================
Files 423 423
Lines 26622 26622
=======================================
Hits 17377 17377
Misses 9245 9245 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Audit by a second Claude agent surfaced four real gaps from the merge. Closes them. 1. **#2672 / #2675 — iOS SPM disable + dSYM upload** - Add `upload_dsyms_to_crashlytics` private lane to `sample_app/ios/fastlane/Fastfile` and wire it into `distribute_to_firebase` and `distribute_to_testflight` before the Firebase/TestFlight upload. Without this lane the release Fastfile never uploads Crashlytics symbol files, so iOS crash reports stay unsymbolicated. Master moved this into the Fastfile itself. - Add `flutter config --no-enable-swift-package-manager` step to all three iOS install blocks in `distribute_external.yml` and `distribute_internal.yml`. This follows master's #2675 pattern (disable SPM at CI level, not via the now-removed `pubspec.yaml` `flutter.config` knob). 2. **#2653 — `maximumMessageLimit` API surface on the public view** - `MessageListCore` already exposed `maximumMessageLimit` / `retentionTrimBuffer`, but the public `StreamMessageListView` constructor did not forward them, so consumers couldn't enable trim without dropping down to `MessageListCore`. Add both parameters to `StreamMessageListView` and forward them at the `MessageListCore(...)` call site. Default for `retentionTrimBuffer` is inlined (`30`) because the canonical constant on `MessageRetentionGate` is `@visibleForTesting`. 3. **#2653 — `pruneOldest` LLC tests** - Port master's `group('\`.state.pruneOldest\`', ...)` (7 tests) into `channel_test.dart`. v10's `ChannelClientState.pruneOldest` was already present from the merge; only the regression tests were missing. Not ported (intentionally): - #2667's two duplicate-id regression tests (`should not duplicate when server echoes back…` and `should not duplicate when the locally-sent message is no longer the latest`). v10's `_updateMessages` keyed-map merge can't produce the duplicate shape these tests guard against, and porting them would require splicing into a v10 group with a different setUp. - Master's `scrollPhysics` nullable default — v10's `ClampingScrollPhysics()` default is the documented v10 contract. - Master's `updateMessage`-side `lastIndexWhere` fast path — v10 rewrote the state-update path to a keyed-map merge (O(N+M)) which is functionally equivalent. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Restores what #2672 / #2675 worked around, rather than re-disabling SPM. `FLUTTER_XCODE_CODE_SIGN_IDENTITY` / `..._PROVISIONING_PROFILE_SPECIFIER` reach xcodebuild as command-line build settings, and those apply to every target in the build graph. With CocoaPods that was harmless — podhelper.rb sets `CODE_SIGNING_ALLOWED = NO` on pod resource bundles and on Pods-Runner. Swift Package plugin bundles have no such hook, so they inherited the app's manual identity and failed the archive with `Signing for "<plugin>" requires a development team` — 40+ of them. Writing the same two settings into Flutter/Signing.xcconfig instead fixes it: Flutter/Release.xcconfig is the base configuration of the Runner target alone (the project-level configurations have no xcconfig), and Runner's Release config leaves identity and profile unset, so an xcconfig can supply them. Verified locally via `fastlane ios build_ipa export_method:"app-store"`: zero package signing errors, only the expected missing distribution certificate. `no_codesign:true` still archives successfully and removes any stale generated file. The env-var approach itself is still needed in spirit because flutter/flutter#113977 is open; only its scope changes. Xcode selection moves to a shared .github/actions/setup-xcode, defaulting to the newest Xcode on the image. The Fastfile no longer calls `select_xcode` — it cannot express "latest", since it resolves to /Applications/Xcode_<version>.app, and it was silently overriding the workflows' own choice with a pinned 26.2 that the xcode-27 image does not have. The two e2e jobs opt into 26.2 explicitly: they run on macos-15, whose default is Xcode 16.4, and their pinned simulator runtimes need 26.x. Co-Authored-By: Claude Opus 5 <[email protected]>
* chore(samples): adopt Xcode 27 and drop CocoaPods for iOS/macOS Moves the sample app's iOS build to Swift Package Manager and removes the CocoaPods integration from both the iOS and macOS Runner projects. `media_kit_video` was the only remaining pod-only plugin. It backed `SampleAppVideoPlayer`, whose desktop branch is gated on Windows/Linux — platforms the sample app has no runner directories for — so on every platform it can actually be built for the widget already fell through to `DefaultStreamVideoPlayer`. Dropping the dependency leaves iOS, macOS, Android and web behaviour unchanged and makes every remaining plugin SPM-compatible. macOS deployment target goes 11.5 -> 12.0, the floor Flutter 3.47 declares in its generated `FlutterMacOS.podspec` and uses in its own app template; below it the build fails to resolve. The highest floor any plugin asks for is 11.0. CI iOS jobs move to the `xcode-27` runner image with `xcode-version: latest`, and the "Disable Swift Package Manager" steps are gone — with them the tool would regenerate a Podfile and link plugins through CocoaPods again. The pod cache action is deleted along with its last consumers; the SwiftPM equivalent is ~1.5 GB, too large to be worth caching. Co-Authored-By: Claude Opus 5 <[email protected]> * fix(ci): scope iOS signing to the Runner target so SPM archives work Restores what #2672 / #2675 worked around, rather than re-disabling SPM. `FLUTTER_XCODE_CODE_SIGN_IDENTITY` / `..._PROVISIONING_PROFILE_SPECIFIER` reach xcodebuild as command-line build settings, and those apply to every target in the build graph. With CocoaPods that was harmless — podhelper.rb sets `CODE_SIGNING_ALLOWED = NO` on pod resource bundles and on Pods-Runner. Swift Package plugin bundles have no such hook, so they inherited the app's manual identity and failed the archive with `Signing for "<plugin>" requires a development team` — 40+ of them. Writing the same two settings into Flutter/Signing.xcconfig instead fixes it: Flutter/Release.xcconfig is the base configuration of the Runner target alone (the project-level configurations have no xcconfig), and Runner's Release config leaves identity and profile unset, so an xcconfig can supply them. Verified locally via `fastlane ios build_ipa export_method:"app-store"`: zero package signing errors, only the expected missing distribution certificate. `no_codesign:true` still archives successfully and removes any stale generated file. The env-var approach itself is still needed in spirit because flutter/flutter#113977 is open; only its scope changes. Xcode selection moves to a shared .github/actions/setup-xcode, defaulting to the newest Xcode on the image. The Fastfile no longer calls `select_xcode` — it cannot express "latest", since it resolves to /Applications/Xcode_<version>.app, and it was silently overriding the workflows' own choice with a pinned 26.2 that the xcode-27 image does not have. The two e2e jobs opt into 26.2 explicitly: they run on macos-15, whose default is Xcode 16.4, and their pinned simulator runtimes need 26.x. Co-Authored-By: Claude Opus 5 <[email protected]> * fix(ci): find Crashlytics upload-symbols in the Swift Package checkout `upload_dsyms_to_crashlytics` pointed `binary_path` at ios/Pods/FirebaseCrashlytics/upload-symbols, which no longer exists now that the sample app has no CocoaPods integration. Both iOS distribute jobs archived, signed and exported their IPAs successfully and then died here: [!] Couldn't find file at path '.../sample_app/ios/Pods/FirebaseCrashlytics/upload-symbols' Under Swift Package Manager the binary lives in the firebase-ios-sdk checkout instead. fastlane's own discovery only searches Pods/ and Fabric.app, so the path is globbed and passed explicitly, with a clear error if it moves again. Co-Authored-By: Claude Opus 5 <[email protected]> * docs(ci): correct why the e2e jobs pin Xcode 26.2 The comment claimed macos-15 defaults to Xcode 16.4 and therefore needs a 26.x toolchain. The image default is indeed 16.4, but setup-xcode's 'latest' resolves to the newest Xcode installed, which on macos-15 is 26.3 — so that was never the reason. The actual constraint is runtime alignment: macos-15 ships iOS simulator runtimes 18.5, 18.6, 26.0, 26.1 and 26.2, but no 26.3. Co-Authored-By: Claude Opus 5 <[email protected]> * chore(samples): make the example apps buildable again, without CocoaPods The per-package examples pinned deployment targets far below what Flutter 3.47 supports, so none of them could build. Raises iOS to 15.0 and macOS to 12.0 — the values Flutter's own app template uses, and for macOS the floor its generated FlutterMacOS.podspec declares, below which `pod install` refuses to resolve. Four Podfiles also declared a `RunnerTests` target that no project defines, which failed `pod install` outright: [!] Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`. stream_chat_flutter's two Podfiles already had that stanza commented out, which is why only those examples still built. Every plugin these examples use is a Swift Package, so Flutter resolved them all through SPM and then asked for CocoaPods to be removed by hand: All plugins found for ios are Swift Packages, but your project still has CocoaPods integration. [...] will need to be migrated to Swift Package Manager manually. Done here, so the six Podfiles are gone rather than fixed: `pod deintegrate` on each project, Podfiles deleted, `Pods-Runner` includes stripped from all twelve xcconfigs, and `Pods/Pods.xcodeproj` dropped from the workspaces. Some of those includes were a hard `#include`, so removing the Pods directory alone would have broken the build outright. Building each example also applied Flutter 3.47's pending project migrations — `@main`, `FlutterImplicitEngineDelegate`, `UIApplicationSceneManifest`, and dropping the stale `MinimumOSVersion` from AppFrameworkInfo.plist. All seven configurations verified from a wiped build directory on Xcode 27.0 / Flutter 3.47.0 — no Podfile regenerated, no `pod install`, and no migration warning: stream_chat, stream_chat_flutter, stream_chat_flutter_core, stream_chat_localizations and stream_chat_persistence on iOS, plus stream_chat_flutter and stream_chat_persistence on macOS. Co-Authored-By: Claude Opus 5 <[email protected]> * docs(ci): trim rationale out of code comments Keeps the mechanism a future reader needs to avoid reintroducing the bug, drops the history and the point-in-time cache measurements — those belong in the pull request. Co-Authored-By: Claude Opus 5 <[email protected]> * fix(ci): do not fail a release when the dSYM upload path is missing upload_dsyms_to_crashlytics runs after build_ipa but before firebase_app_distribution and upload_to_testflight, so a missed glob aborted an already-built, signed release over a symbol upload. Both the SourcePackages directory and the firebase-ios-sdk checkout name can move under a Flutter or Firebase bump. Symbols can be uploaded after the fact; a failed release costs a full rebuild. Logs an error and skips instead. Co-Authored-By: Claude Opus 5 <[email protected]> --------- Co-authored-by: Claude Opus 5 <[email protected]>
Summary
Drop the
flutter > config > enable-swift-package-manager: falsekey added tosample_app/pubspec.yamlin chore(samples): disable Swift Package Manager for sample_app #2672. That key was introduced in Flutter ~3.38, so it fails to parse under our legacy floor (Flutter 3.27.4 pinned bylegacy_version_analyze.yml), breaking master right after chore(samples): disable Swift Package Manager for sample_app #2672 merged with:Instead, run
flutter config --no-enable-swift-package-managerin the two workflows that actually produce codesigned IPAs (distribute_internal,distribute_external) — the only place SPM signing errors bite. The PR-validationbuild (ios) no_codesign:truepath instream_flutter_workflow.ymldoesn't need it (no signing → no SPM signing failures).Failing master run for context: https://github.com/GetStream/stream-chat-flutter/actions/runs/26162346822
Test plan
legacy_version_analyzepasses on this PR (sample_app's pubspec is parseable on Flutter 3.27.4 again).distribute_internal(ios) on this branch succeeds end-to-end, with the newDisable Swift Package Managerstep taking effect.🤖 Generated with Claude Code
Summary by CodeRabbit