Skip to content

fix(ci): disable SPM at CI level instead of via pubspec flag - #2675

Merged
xsahil03x merged 1 commit into
masterfrom
fix/move-spm-disable-to-ci
May 20, 2026
Merged

xsahil03x merged 1 commit into
masterfrom
fix/move-spm-disable-to-ci

Conversation

@xsahil03x

@xsahil03x xsahil03x commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Drop the flutter > config > enable-swift-package-manager: false key added to sample_app/pubspec.yaml in 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 by legacy_version_analyze.yml), breaking master right after chore(samples): disable Swift Package Manager for sample_app #2672 merged with:

    Unexpected child "config" found under "flutter".

  • Instead, run flutter config --no-enable-swift-package-manager in the two workflows that actually produce codesigned IPAs (distribute_internal, distribute_external) — the only place SPM signing errors bite. The PR-validation build (ios) no_codesign:true path in stream_flutter_workflow.yml doesn'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_analyze passes on this PR (sample_app's pubspec is parseable on Flutter 3.27.4 again).
  • Dispatched distribute_internal (ios) on this branch succeeds end-to-end, with the new Disable Swift Package Manager step taking effect.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chore
    • Updated iOS build configuration to ensure consistent behavior across development and distribution workflows.

Review Change Stack

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]>
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Configuration for disabling Swift Package Manager is migrated from the sample_app/pubspec.yaml file to CLI commands executed during iOS workflow jobs. The pubspec configuration entry is removed, and identical behavior is established via flutter config commands in both the external and internal distribution workflows.

Changes

Swift Package Manager Configuration Migration

Layer / File(s) Summary
Remove SPM disable from pubspec configuration
sample_app/pubspec.yaml
The config.enable-swift-package-manager: false configuration block is removed from sample_app pubspec file.
Add SPM disable commands to iOS workflows
.github/workflows/distribute_external.yml, .github/workflows/distribute_internal.yml
Both external and internal distribution workflows add a flutter config --no-enable-swift-package-manager step to the iOS job, positioned before tool installation steps.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • GetStream/stream-chat-flutter#2672: Retrieved PR adds the enable-swift-package-manager: false configuration to sample_app/pubspec.yaml, representing the inverse change to this PR's removal of the same configuration.

Poem

🐰 A config moves from file to flow,
From pubspec's static, old-fashioned glow,
To workflows swift, where commands run free,
SPM disabled, as it ought to be! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: moving SPM disablement from pubspec configuration to CI-level commands in workflows.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/move-spm-disable-to-ci

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented May 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 65.27%. Comparing base (abc8648) to head (6a348d5).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@xsahil03x
xsahil03x enabled auto-merge (squash) May 20, 2026 12:52
@xsahil03x
xsahil03x merged commit 6b6eb93 into master May 20, 2026
27 of 29 checks passed
@xsahil03x
xsahil03x deleted the fix/move-spm-disable-to-ci branch May 20, 2026 13:09
xsahil03x added a commit that referenced this pull request May 21, 2026
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]>
renefloor added a commit that referenced this pull request Sep 10, 2026
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]>
renefloor added a commit that referenced this pull request Sep 15, 2026
* 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]>
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.

2 participants