Skip to content

Commit 8690f8d

Browse files
committed
TF-4269 docs: add ADR-0084 for iOS Sentry dSYM and Dart symbols automation
1 parent aa154cc commit 8690f8d

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# 0084. iOS Sentry dSYM & Dart Symbols Automation
2+
3+
Date: 2026-04-20
4+
5+
## Status
6+
7+
Accepted
8+
9+
## Context
10+
11+
iOS crash reports on Sentry are unreadable due to two levels of obfuscation:
12+
13+
1. **Native (Swift/Objective-C/C++):** Xcode strips debug symbols from the release binary — only raw memory addresses are shown instead of function names and line numbers.
14+
2. **Dart:** ARM binaries lack debug info — only raw memory addresses are shown instead of Flutter stack traces.
15+
16+
This makes production crashes nearly impossible to debug.
17+
18+
## Decision
19+
20+
Update the iOS Fastlane build and CI/CD pipeline to automatically generate and upload de-obfuscation artifacts to Sentry on every release.
21+
22+
### Build (Fastlane — `ios/fastlane/Fastfile`)
23+
24+
Pass Flutter obfuscation build settings to `build_app` via `xcargs`. Flutter's `xcode_backend.sh` reads these Xcode build settings during the build phase:
25+
26+
```ruby
27+
symbols_path = File.expand_path("../build/ios/outputs/symbols")
28+
build_app(
29+
...
30+
xcargs: "DART_OBFUSCATION=true SPLIT_DEBUG_INFO=#{symbols_path}",
31+
dsym_output_path: "../build/ios/outputs/dsym"
32+
)
33+
```
34+
35+
- `DART_OBFUSCATION=true` — instructs Flutter to obfuscate Dart code (value must be lowercase `true`, not `YES`).
36+
- `SPLIT_DEBUG_INFO=<abs_path>` — strips Dart debug symbols from the binary into `build/ios/outputs/symbols/`.
37+
- `dsym_output_path` — instructs Gym (Fastlane) to export the Xcode-generated dSYM to `build/ios/outputs/dsym/`.
38+
39+
### Pod dependency (`ios/Podfile`)
40+
41+
The `TwakeMailNSE` (Notification Service Extension) target must use `Sentry/HybridSDK` at the **exact same version** as `sentry_flutter` requires. Using plain `pod 'Sentry'` (Core subspec, pulls latest) causes a version conflict and `PrivateSentrySDKOnly not found` compile errors.
42+
43+
```ruby
44+
target 'TwakeMailNSE' do
45+
use_frameworks!
46+
pod 'Sentry/HybridSDK', '8.56.2' # must match sentry_flutter's requirement
47+
end
48+
```
49+
50+
### CI Pipeline (GitHub Actions — `.github/workflows/release.yaml`)
51+
52+
The two separate Sentry upload steps (iOS and Android) are merged into a single **"Upload Debug Symbols to Sentry"** step that runs on both matrix jobs independently. The step branches internally based on `${{ matrix.os }}`.
53+
54+
After a successful build, the step:
55+
56+
1. Validates that the git tag version matches the version in `pubspec.yaml`.
57+
2. Creates a Sentry release.
58+
3. For **iOS**:
59+
- Uploads `build/ios/outputs/dsym/` (dSYM — de-obfuscates native Swift/ObjC/C++ crashes).
60+
- Uploads `build/ios/outputs/symbols/` (Dart debug symbols — de-obfuscates Flutter stack traces).
61+
4. For **Android**:
62+
- Uploads `build/app/outputs/mapping/release/mapping.txt` (ProGuard — de-obfuscates Java/Kotlin).
63+
- Uploads `build/app/outputs/symbols/` (Dart debug symbols).
64+
5. Finalizes the release.
65+
66+
Independence between platforms is guaranteed by the matrix strategy (`fail-fast: false`) — iOS and Android run on separate runners, so a failure on one does not affect the other.
67+
68+
## Consequences
69+
70+
**Benefits:**
71+
- Full readable stack traces for both Dart and native (Swift/ObjC/C++) crashes in Sentry.
72+
- Automated — no manual upload step needed.
73+
- Smaller app binary (debug info stripped from the IPA).
74+
- Single unified Sentry upload step for both platforms — easier to maintain.
75+
76+
**Trade-offs:**
77+
- Slightly longer CI build time (symbol separation + upload).
78+
- `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT` must be maintained as CI secrets.
79+
- `pod 'Sentry/HybridSDK'` version in `Podfile` must be kept in sync manually when upgrading `sentry_flutter`.
80+
- Symbol files must be uploaded in the **same workflow run** as the build — running `flutter clean` between build and upload will break de-obfuscation.

0 commit comments

Comments
 (0)