fix(crashlytics): resolve SPM run script for Flutter 3.44+ and custom -derivedDataPath - #444
Conversation
… -derivedDataPath Fixes invertase#443. `flutterfire configure` injects an Xcode Run Script Build Phase that spawns `firebase-ios-sdk/Crashlytics/run` to upload dSYMs. With Swift Package Manager, the binary lives at `<derivedDataPath>/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run`, but the previous implementation hardcoded a regex that only matches Xcode's standalone DerivedData layout: DERIVED_DATA_PATH=$(echo "$BUILD_ROOT" | sed -E 's|(.*DerivedData/[^/]+).*|\1|') This breaks two real-world layouts: 1. **Flutter 3.44+ project-local builds** (`flutter build ios`) place SourcePackages under `<project>/build/ios/SourcePackages/...`, which contains no `DerivedData/` segment - sed leaves `BUILD_ROOT` untouched and the spawned path doesn't exist (`ProcessException: No such file or directory`). 2. **`xcodebuild -derivedDataPath <custom>`** runs (e.g. fastlane gym with its per-run isolation directory) place SourcePackages under `<custom>/SourcePackages/...`, again no `DerivedData/` segment. Replace the regex with a `resolve_spm_run_script` helper that strips `/Build/...` from `BUILD_DIR` (then `BUILT_PRODUCTS_DIR` / `BUILD_ROOT` as fallbacks) to recover the derived-data root. Xcode build settings guarantee `BUILD_DIR` has the shape `<derivedDataPath>/Build/...` across all three layouts, so the strip-based anchor is reliable everywhere the previous regex was, plus the two cases it missed. Also fall back to `exit 0` with a warning if no candidate `run` file exists, so a misconfigured project surfaces a clear message instead of killing the archive with `ProcessException`. Verified by hand against: - Xcode standalone DerivedData (`~/Library/.../DerivedData/Runner-X`) - Flutter `build/ios` derived-data (Flutter 3.44.0, SPM enabled) - fastlane gym custom `-derivedDataPath`
|
|
|
Can you please take a look at this PR? @Lyokone |
|
@phuongta-pi I think some sort of test would be good to have these cases covered in the future. Maybe this helps pushing this PR. |
|
Hello 👋, this PR has been opened for more than 2 months with no activity on it. If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing! You have 15 days until this gets closed automatically |
|
This is stil broken and relevant! Especially with the soon deprecation of cocoapods. @Lyokone |
Description
Fixes #443.
flutterfire configureinjects an Xcode Run Script Build Phase that spawnsfirebase-ios-sdk/Crashlytics/runto upload dSYMs. With Swift Package Manager the binary lives at<derivedDataPath>/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run, but the previous implementation hardcoded a regex that only matches Xcode's standalone DerivedData layout:DERIVED_DATA_PATH=$(echo "$BUILD_ROOT" | sed -E 's|(.*DerivedData/[^/]+).*|\1|')This breaks two real-world layouts:
flutter build ios) place SourcePackages under<project>/build/ios/SourcePackages/..., which contains noDerivedData/segment — sed leavesBUILD_ROOTuntouched and the spawned path doesn't exist (ProcessException: No such file or directory).xcodebuild -derivedDataPath <custom>runs (e.g.fastlane gymwith its per-run isolation directory) place SourcePackages under<custom>/SourcePackages/..., again noDerivedData/segment.Fix
Replace the regex with a
resolve_spm_run_scripthelper that strips/Build/...fromBUILD_DIR(thenBUILT_PRODUCTS_DIR/BUILD_ROOTas fallbacks) to recover the derived-data root. Xcode build settings guaranteeBUILD_DIRhas the shape<derivedDataPath>/Build/...across all three layouts (Xcode standalone, Flutter project-local, custom -derivedDataPath), so the strip-based anchor is reliable everywhere the previous regex was, plus the two cases it missed.Also fall back to
exit 0with a warning if no candidaterunfile exists, so a misconfigured project surfaces a clear message instead of killing the archive withProcessException.Type of Change
feat-- New feature (non-breaking change which adds functionality)fix-- Bug fix (non-breaking change which fixes an issue)!-- Breaking change (fix or feature that would cause existing functionality to change)refactor-- Code refactorci-- Build configuration changedocs-- Documentationchore-- ChoreTest plan
The existing integration test
Validate flutterfire upload-crashlytics-symbols script is ran when building app(test/configure_test.dart:585) exercises the new resolver end-to-end viaflutter build ios --simulator --debugafter switching the project to SPM. On Flutter 3.44, that test reproduces #443 with the old regex (flutter buildoutputs tobuild/ios, not~/Library/.../DerivedData/Runner-X) and passes with this fix.Verified manually against all three layouts:
~/Library/Developer/Xcode/DerivedData/Runner-XXXXX)flutter build iosFlutter 3.44.0 (<project>/build/ios/SourcePackages/...)xcodebuild -derivedDataPathcustom (fastlane gym per-run dir)Allow edits by maintainers