|
| 1 | +# 71. Android 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 Android platform currently lacks this capability. |
| 12 | + |
| 13 | +Android crash reports on Sentry are currently unreadable due to two levels of obfuscation: |
| 14 | + |
| 15 | +1. **Java/Kotlin Obfuscation:** The Android native code is minified and obfuscated by R8/ProGuard during the release build (e.g., classes appear as `a.b.c`). |
| 16 | +2. **Dart Obfuscation:** The compiled Dart native code (ARM64/ARM) lacks debug information, displaying raw memory addresses instead of file names and line numbers. |
| 17 | + |
| 18 | +This limitation makes debugging production crashes—especially `NullPointerExceptions` in native layers or logic errors deep within Dart code—nearly impossible. |
| 19 | + |
| 20 | +There is a requirement to automate the upload of both **ProGuard Mapping** and **Dart Debug Symbols** to Sentry within the CI/CD pipeline for every release. |
| 21 | + |
| 22 | +## Decision |
| 23 | + |
| 24 | +We have decided to update the Android Build and Release workflow to support comprehensive de-obfuscation on Sentry. |
| 25 | + |
| 26 | +### 1. Build Configuration (Fastlane) |
| 27 | + |
| 28 | +We updated the `Fastfile` to modify the Flutter build command. Instead of a standard release build, we now enforce code obfuscation and the separation of debug information. |
| 29 | + |
| 30 | +| Parameter | Value | Purpose | |
| 31 | +| --- | --- | --- | |
| 32 | +| `--obfuscate` | `true` | Minifies code to reduce size and obfuscate logic (Standard practice). | |
| 33 | +| `--split-debug-info` | `../build/app/outputs/symbols` | **New Decision:** Extracts debug information from the app binary into a separate directory. These files map binary instructions back to Dart source code. | |
| 34 | + |
| 35 | +**Command:** |
| 36 | + |
| 37 | +```ruby |
| 38 | +sh "flutter build appbundle --release --obfuscate --split-debug-info=../build/app/outputs/symbols ..." |
| 39 | + |
| 40 | +``` |
| 41 | + |
| 42 | +### 2. CI Pipeline Strategy (GitHub Actions) |
| 43 | + |
| 44 | +The GitHub Actions `release.yaml` workflow has been expanded to include specific Sentry artifact upload steps immediately following a successful build. |
| 45 | + |
| 46 | +The process flow is as follows: |
| 47 | + |
| 48 | +1. **Build App:** Fastlane generates the `.aab`, the `mapping.txt` file, and the `symbols` directory. |
| 49 | +2. **Create Release:** A Sentry release is created, matching the version defined in `pubspec.yaml`. |
| 50 | +3. **Upload ProGuard:** The `mapping.txt` is uploaded to de-obfuscate Java/Kotlin stack traces (Android System crashes). |
| 51 | +4. **Upload Debug Files:** The `.symbols` directory is scanned and uploaded to de-obfuscate Dart stack traces (Flutter crashes). |
| 52 | +5. **Finalize:** The release is marked as final. |
| 53 | + |
| 54 | +### 3. Artifact Locations |
| 55 | + |
| 56 | +We standardized the artifact output locations in the CI environment to ensure the upload script can locate them reliably: |
| 57 | + |
| 58 | +* **ProGuard Mapping:** `build/app/outputs/mapping/release/mapping.txt` (Gradle/Flutter default). |
| 59 | +* **Dart Symbols:** `build/app/outputs/symbols` (Defined by the `--split-debug-info` flag). |
| 60 | + |
| 61 | +## Consequences |
| 62 | + |
| 63 | +### Benefits |
| 64 | + |
| 65 | +* **Full Stacktrace Visibility:** Sentry will accurately display filenames, function names, and line numbers for both Dart and Java/Kotlin crashes. |
| 66 | +* **Automated Workflow:** Removes the need for manual uploads by developers, preventing human error or missing mapping files for releases. |
| 67 | +* **Optimized App Size:** Using `--split-debug-info` reduces the final download size of the application for users, as debug data is stripped from the binary. |
| 68 | +* **Web Parity:** Brings Mobile debugging capabilities up to par with the existing Web implementation. |
| 69 | + |
| 70 | +### Trade-offs |
| 71 | + |
| 72 | +* **Build Time:** Release build times will increase slightly due to the symbol separation process and the network time required to upload artifacts. |
| 73 | +* **CI Complexity:** The YAML configuration and Fastfile are more complex, requiring maintenance of environment variables (`SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, etc.). |
| 74 | +* **Storage:** Temporary storage is required on the CI runner for symbol files (though these are cleaned up after the job). |
| 75 | + |
| 76 | +## Developer Guidelines |
| 77 | + |
| 78 | +### Verification |
| 79 | + |
| 80 | +To verify a successful upload: |
| 81 | + |
| 82 | +1. Navigate to Sentry Project > **Releases**. |
| 83 | +2. Select the recently built version (e.g., `1.0.0+1`). |
| 84 | +3. Check the **Artifacts** tab. |
| 85 | +* You must see a `mapping.txt` file (Type: *ProGuard*). |
| 86 | +* You must see files ending in `.symbols` (Type: *Debug Information*, e.g., `app.android-arm64.symbols`). |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | +### Troubleshooting |
| 91 | + |
| 92 | +* **"No such file or directory":** Ensure that no `flutter clean` commands are executed between the **Build** step and the **Upload** step in the CI pipeline. |
| 93 | +* **Sentry Auth Errors:** Verify that `SENTRY_AUTH_TOKEN` is correctly set in GitHub Secrets and that `SENTRY_ORG`/`SENTRY_PROJECT` environment variables are correct. |
| 94 | +* **"Missing debug image":** If Sentry reports a missing debug image for a specific crash, the uploaded symbols do not match the binary on the user's device. Ensure the upload happens in the exact same workflow run as the build. |
0 commit comments