Repository navigation
chore(deps): upgrade to Flutter 3.47.2 and drop the freezed models it breaks - #8915
Conversation
This comment has been minimized.
This comment has been minimized.
|
@hm21 Pulling this back to draft while I figure out how it interacts with Shorebird and whether we need to do the updates in tandem. Thanks for your patience. |
b3e28f4 to
44588c3
Compare
NotThatKindOfDrLiz
left a comment
There was a problem hiding this comment.
@hm21 I pushed the clear, low-risk remediation directly to this branch and updated the PR description. The automated checks are green.
The takeover changes:
- pin Codemagic to Shorebird 1.6.120, whose bundled Flutter is 3.47.2 / Dart 3.13.2
- make the iOS Swift-package deployment-floor repair version-aware and cover it with tests
- preserve the former Freezed state contracts, including explicit-null
copyWithbehavior and collection immutability, with regression tests - align
nostr_sdk's Flutter constraint, relock the reduced service-size ceilings, and remove stale active Freezed guidance/hooks
Please keep this PR in draft until you complete and document the remaining release-critical physical-device acceptance:
- Samsung Galaxy: camera, recording, upload, and feed playback.
- Physical iPhone using the release/TestFlight candidate: launch, camera and microphone permission flows, recording, upload, and feed playback.
- Record that the tested release candidate was built with Shorebird 1.6.120 / Flutter 3.47.2.
Please also review the commits I pushed before marking the PR ready. No App Store or Shorebird release has been created by this takeover.
Superseded to separate the achievable pre-merge device gate from post-merge TestFlight and Play internal validation.
NotThatKindOfDrLiz
left a comment
There was a problem hiding this comment.
@hm21 Correction to my superseded review: the store workflows intentionally refuse to create Shorebird releases from a non-main branch, so TestFlight and Play internal validation are post-merge gates, not work you can complete on this PR branch.
Before this PR is marked ready, please:
- Review the takeover commits pushed to this branch, including the Shorebird pin, iOS deployment-floor repair, and state-model compatibility tests.
- Run the required Samsung Galaxy smoke test from this branch and document the device/build tested and results for:
- launch and basic navigation
- camera and microphone permissions
- recording
- upload
- feed playback
- app restart
Once that evidence is here, this review can be replaced with an approval. After merge—but before any public promotion—Liz will build the Shorebird-enabled artifacts from main and validate the exact TestFlight and Play internal builds on physical iPhone and Samsung devices. A failure at that gate means no promotion and a new fix PR/build.
44588c3 to
061b256
Compare
This comment has been minimized.
This comment has been minimized.
0b87779 to
e564896
Compare
This comment has been minimized.
This comment has been minimized.
e564896 to
d1909e3
Compare
This comment has been minimized.
This comment has been minimized.
|
@NotThatKindOfDrLiz Reviewed your takeover commits. The Shorebird pin is the important one — my commits moved Flutter to 3.47.2 and left Codemagic on 1.6.117, which would have broken the store build. Verified independently: revision Three follow-up commits pushed on top of yours:
Heads up on two things: the PR was showing merge conflicts, so I rebased onto current Device gate: smoke-tested from this branch on a physical Samsung Galaxy S25 (SM-S942B, Android 16) — launch and basic navigation, camera and microphone permission flows, recording, upload, feed playback, and app restart all behave correctly. A screen recording follows in a separate comment. I left your nostr_sdk reconnect test alone. Asserting exactly 4 and 8 created channels against a 50 ms wall-clock budget is in principle sensitive to a loaded runner, but the assertions are genuinely stronger than the old Verification: flutter-upgrade.mp4 |
…e classes Dart 3.13 stopped accepting `final` on a constructor parameter, and that is exactly what freezed 3 emits. The four generated files under lib/state/ no longer compile: lib/state/video_feed_state.freezed.dart:234:35: Error: Can't have modifier 'final' here. `flutter analyze` never saw it — `**/*.freezed.dart` is excluded in analysis_options.yaml — so it only surfaced once dart format could not parse the files. freezed 4.0.0 fixes the generator, but it requires analyzer >= 13 and there is no hive_ce_generator build for analyzer 13 (1.11.2 caps at ^12, 1.11.3 jumps to ^14). analyzer 14 is out of reach because flutter_test pins test_api 0.7.12, which forces test 1.31.1, which requires analyzer < 14. Dropping package:test is not an option either: 28 workspace packages use it, several of them pure Dart, where flutter_test would add a Flutter runtime dependency the package boundary guard rejects. Since these are the only four freezed classes in the repo, and .claude/rules/state_management.md prescribes Equatable for state anyway, they are hand-written instead. That takes freezed out of the dependency graph entirely rather than working around the version conflict. One behavioural detail worth the extra file: freezed's copyWith clears a nullable field when the caller passes an explicit null, which three call sites rely on to reset `error` on refresh. A plain `error ?? this.error` would have turned those into silent no-ops, so copy_with_sentinel.dart restores the distinction between "argument omitted" and "argument set to null".
The 3.13 analyzer adds two lints that the app trips 24 times, and CI runs `flutter analyze` as a blocking job, so the upgrade cannot land without them. `unawaited_return_in_try_block` (12 sites) is the one that mattered: a `return someFuture();` inside a try does not route the future's failure through the catch, so every one of these had a catch block that logs and returns a fallback which could never fire. Adding the missing `await` makes the handler cover what it reads as covering. `unnecessary_unawaited` (11 sites) is the opposite direction — Flutter 3.47 annotated Navigator.push and Scrollable.ensureVisible with `@awaitNotRequired`, so the `unawaited(...)` wrappers are now redundant. Two `dart:async` imports became unused along with them. Plus one unused catch-stack variable and one conditional expression the analyzer wants as an if-element. The typedef move is a consequence of the same upgrade rather than a cleanup: the 3.13 formatter wraps function-type typedefs differently, which grew auth_service.dart and curated_list_service.dart by two lines each. Both are frozen by check_service_god_file_ceiling.sh, which has no sanctioned raise path, so the callback typedefs move to lib/models/ — where auth_service.dart already re-exports auth_result, auth_state and their siblings from — and both services are re-exported from there. No call site changes, and both files now sit below their ceiling (4516/4536 and 1841/1847).
Moves every pin from Flutter 3.44.9 / Dart 3.12 to 3.47.2 / Dart 3.13: 71
workflow pins, 12 in codemagic.yaml, mise.toml, and the SDK constraints in
mobile/pubspec.yaml. The 3.44 line stopped receiving patches when 3.47 went
stable, so the repo was sitting on a frozen toolchain.
3.47.2 is the second patch on the line, twelve days old, and Shorebird
publishes a matching engine for it — the store builds pass FLUTTER_VERSION
straight to `shorebird release`, so a version Shorebird does not carry would
break them. The engine provenance recorded in SHOREBIRD_CODE_PUSH.md is
updated to the 3.47.2 engine.
Also folded in, because they were drifting or would have gone stale:
- The 16 packages still declaring `flutter: ^3.41.1`, left behind by the
previous bump, now match the app.
- README, CONTRIBUTING and the dependabot comment still named ^3.44.0 while
the real pin had moved to 3.44.9 back in #7202.
- The AndroidManifest comment explaining why Impeller was re-enabled dates
its profiling against the pin it predates.
- freezed and freezed_annotation are gone from pubspec.yaml — the state
models no longer use them.
The regenerated l10n files and the analyzer excludes the 3.47 tool writes into
each analysis_options.yaml are committed so `flutter pub get` leaves a clean
tree, which the Generated Files check requires.
Android needs no native changes: compileSdk, targetSdk and the NDK version are
identical between 3.44.9 and 3.47.2, and AGP 8.11.1 / Gradle 8.14 / Kotlin
2.2.20 all sit inside the supported window.
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
main upgraded to Flutter 3.47.2 (#8915) and touched the async-safety baseline this branch had relocked, so the rebase took main's rows and this relocks the three this branch changes: the retired discovery screen and owned-list card rows go, and the Explore Lists tab drops from 4 to 3. The new SDK's formatter also reflows one thumbnail test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Description
Upgrades the pinned toolchain from Flutter 3.44.9 / Dart 3.12 to Flutter 3.47.2 / Dart 3.13.2, and upgrades the release CLI from Shorebird 1.6.117 to Shorebird 1.6.120. Shorebird 1.6.120 bundles and supports Flutter 3.47.2, so local, CI, and store release builds now use a compatible pair.
Dart 3.13 rejects the constructor syntax emitted by Freezed 3. Freezed 4 cannot currently coexist with this workspace dependency graph, so the four legacy state models are handwritten as Equatable values and Freezed leaves the dependency graph.
Compatibility preserved
copyWithfields retain the omitted-versus-explicit-null distinction.dart:collection's views compare by identity, so a getter that allocates one per read tells everyselectwatcher that the field changed on every unrelated state change —curationProvider.select((state) => state.editorsPicks)is the one such watcher in the tree today. Freezed's threeEqualUnmodifiable*Viewwrappers are restored next to the state models for exactly that reason, andcopyWithpasses the raw field so a long-lived state no longer accumulates one delegating view per copy.constcollection is already unmodifiable, so const fixtures would have stayed green even with the wrappers removed.Native release safeguards
Flutter 3.47 changed the generated iOS Swift package floor. Both the Xcode pre-build action and Codemagic now call one version-aware helper that raises any generated floor below iOS 16, preserves newer floors, and fails clearly on an invalid manifest. This was verified with
flutter build ios --config-onlyon Flutter 3.47.2.Additional upgrade work
nostr_sdkFlutter constraint.Everyone needs to re-run
cd mobile && mise run setup_hooksafter this merges. Git hooks are generated copies, so an already-installed pre-commit/pre-push hook keeps looking for*.freezed.dartfiles that no longer exist. The same edit also drops*.mocks.dartfrom the changed-file scan, which is unrelated to Freezed and is called out here rather than buried: generated mocks now no longer select tests to run in the pre-push hook.Related Issue: Closes #7354
Out of Scope
sdk: ^3.11.0; this is not version drift and has no effect inside this workspace.hive_ce_generatorremains on its current constraint because the state migration removes the conflicting Freezed requirement.Verification
flutter analyze lib test integration_test tools packages— cleandart run build_runner build— generated output cleanflutter build ios --config-only— succeeds and generates an iOS 16 package floorflutter build apk --debug— succeedsmain; repository-widedart formatreports no changes and the async-safety, skip, placeholder, ungrouped-test, layer-direction and unpinned-assertion ratchets all pass on the rebased treeRelease gates
Both pre-ready gates are now met. The takeover commits have been reviewed (see the follow-up commits on top of them), and the branch build was smoke-tested on a physical Samsung Galaxy S25 (SM-S942B, Android 16): launch and basic navigation, camera and microphone permission flows, recording, upload, feed playback, and app restart all behave correctly. A screen recording follows in the comments.
The store workflows intentionally refuse to create Shorebird releases from non-
mainbranches. After merge, but before any public promotion, a maintainer must build the Shorebird-enabled artifacts frommainand validate the exact internal artifacts:If either internal artifact fails, do not promote it; fix the failure through a new PR and cut a new internal build.
Type of Change