Skip to content

Commit b6d0b6c

Browse files
committed
TF-4269 chore(docs): Update ADR 071 documenting the mobile de-obfuscation strategy
1 parent 6e9c56f commit b6d0b6c

File tree

2 files changed

+119
-94
lines changed

2 files changed

+119
-94
lines changed

docs/adr/0071-android-sentry-source-maps-native-symbols-automation.md

Lines changed: 0 additions & 94 deletions
This file was deleted.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# 71. Mobile Sentry Source Maps & Native Symbols Automation
2+
3+
Date: 2026-02-11
4+
5+
## Status
6+
7+
Accepted
8+
9+
## Context
10+
11+
The `tmail-flutter` application utilizes Sentry for error monitoring. While the Web platform successfully uploads source maps for readable stack traces, the Mobile platforms (Android & iOS) currently lack this capability.
12+
13+
Mobile crash reports on Sentry are currently unreadable due to platform-specific obfuscation:
14+
15+
1. **Android (Java/Kotlin):** Native code is minified and obfuscated by R8/ProGuard (e.g., classes appear as `a.b.c`).
16+
2. **iOS (Obj-C/Swift):** Native crash reports contain raw memory addresses (hexadecimal) instead of symbols, requiring **dSYM** files to resolve.
17+
3. **Flutter (Dart - Both Platforms):** The compiled Dart native code (ARM64) lacks debug information, displaying raw memory addresses instead of file names and line numbers.
18+
19+
This limitation makes debugging production crashes—whether they are `NullPointerExceptions` on Android, `EXC_BAD_ACCESS` on iOS, or logic errors deep within Dart code—nearly impossible.
20+
21+
There is a requirement to automate the upload of **ProGuard Mapping** (Android), **dSYMs** (iOS), and **Dart Debug Symbols** (Both) to Sentry within the CI/CD pipeline for every release.
22+
23+
## Decision
24+
25+
We have decided to update the Android and iOS Build/Release workflows to support comprehensive de-obfuscation on Sentry.
26+
27+
### 1. Build Configuration (Fastlane)
28+
29+
We updated the `Fastfile` for both platforms to enforce code obfuscation and the separation of debug information.
30+
31+
#### Android
32+
33+
We modified the build command to use `--obfuscate` and `--split-debug-info`.
34+
35+
| Parameter | Value | Purpose |
36+
| --- | --- | --- |
37+
| `--obfuscate` | `true` | Minifies code to reduce size and obfuscate logic. |
38+
| `--split-debug-info` | `../build/app/outputs/symbols` | Extracts debug info into a separate directory. |
39+
40+
#### iOS (Hybrid Strategy)
41+
42+
We adopted a **Hybrid Build Strategy** because the standard Fastlane `build_app` (gym) action does not natively support Flutter's obfuscation flags.
43+
44+
1. **Compile & Archive:** We use `flutter build ipa` directly via shell to compile code with obfuscation flags and generate an `.xcarchive`.
45+
2. **Export:** We use Fastlane's `build_app` only to sign and export the pre-built archive into an `.ipa`.
46+
47+
**iOS Command (Fastfile):**
48+
49+
```ruby
50+
# Step 1: Compile with obfuscation and symbols
51+
sh "flutter", "build", "ipa", "--release", "--obfuscate", "--split-debug-info=../build/ios/outputs/symbols", "--export-method=app-store"
52+
53+
# Step 2: Export IPA using Fastlane Gym
54+
build_app(..., skip_build_archive: true, archive_path: "../build/ios/archive/Runner.xcarchive")
55+
56+
```
57+
58+
### 2. CI Pipeline Strategy (GitHub Actions)
59+
60+
The GitHub Actions `release.yaml` workflow has been expanded to include a unified **Sentry Artifact Upload** step immediately following a successful build.
61+
62+
The process flow is as follows:
63+
64+
1. **Build App:** Fastlane generates the binaries (`.aab`/`.ipa`) and the debug artifacts (`mapping.txt`, `dSYMs`, `symbols/`).
65+
2. **Create Release:** A Sentry release is created, matching the version defined in `pubspec.yaml`.
66+
3. **Upload Native Artifacts:**
67+
* **Android:** Uploads `mapping.txt` (ProGuard).
68+
* **iOS:** Finds and uploads `Runner.app.dSYM` located inside the `.xcarchive`.
69+
70+
71+
4. **Upload Dart Artifacts:** The `.symbols` directories for both platforms are scanned and uploaded to de-obfuscate Flutter crashes.
72+
5. **Finalize:** The release is marked as final.
73+
74+
### 3. Artifact Locations
75+
76+
We standardized the artifact output locations in the CI environment:
77+
78+
| Platform | Artifact Type | Path | Purpose |
79+
| --- | --- | --- | --- |
80+
| **Android** | ProGuard Mapping | `build/app/outputs/mapping/release/mapping.txt` | De-obfuscate Java/Kotlin |
81+
| **Android** | Dart Symbols | `build/app/outputs/symbols` | De-obfuscate Flutter (Android) |
82+
| **iOS** | Native dSYM | `build/ios/archive/Runner.xcarchive/dSYMs` | De-obfuscate Obj-C/Swift |
83+
| **iOS** | Dart Symbols | `build/ios/outputs/symbols` | De-obfuscate Flutter (iOS) |
84+
85+
## Consequences
86+
87+
### Benefits
88+
89+
* **Full Stacktrace Visibility:** Sentry will accurately display filenames, function names, and line numbers for Dart, Java/Kotlin, and Swift/Obj-C crashes.
90+
* **Automated Workflow:** Eliminates manual upload steps, preventing "missing dSYM" errors common in iOS releases.
91+
* **Optimized App Size:** Using `--split-debug-info` reduces the final download size of the application for users on both platforms.
92+
* **Platform Parity:** Ensures debugging capabilities are consistent across Web, Android, and iOS.
93+
94+
### Trade-offs
95+
96+
* **Build Time:** Release build times increase slightly due to symbol separation and network upload time.
97+
* **Fastlane Complexity (iOS):** The iOS Fastfile is more complex due to the split between "Build Archive" and "Export IPA" steps.
98+
* **CI Configuration:** Requires careful management of pathing (`working-directory`) in GitHub Actions to distinguish between Android and iOS build artifacts.
99+
100+
## Developer Guidelines
101+
102+
### Verification
103+
104+
To verify a successful upload:
105+
106+
1. Navigate to Sentry Project > **Releases**.
107+
2. Select the recently built version.
108+
3. Check the **Artifacts** tab. You should see:
109+
* **Android:** `mapping.txt` (Type: *ProGuard*).
110+
* **iOS:** Files ending in `.dSYM` (Type: *Debug Information*).
111+
* **Both:** Files ending in `.symbols` (Type: *Debug Information*).
112+
113+
114+
115+
### Troubleshooting
116+
117+
* **iOS "Missing dSYM":** If Sentry says dSYMs are missing, ensure `Bitcode` is disabled in Xcode (standard for Flutter). Also, verify the CI script is looking inside the `.xcarchive`.
118+
* **"No such file or directory":** Ensure no `flutter clean` commands run between the **Build** and **Upload** steps.
119+
* **Sentry Auth:** Verify `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, and `SENTRY_PROJECT` secrets are active.

0 commit comments

Comments
 (0)