Sentry Integration
When you ship OTA updates through DeployPulse, your React Native bundle is minified. Without sourcemaps, crash reports in Sentry show minified stack frames that are nearly impossible to debug. This guide explains how to generate sourcemaps during a dpctl release-react run and upload them to Sentry so every crash — even from a CodePush update — shows fully symbolicated traces.
DeployPulse uses Sentry internally to monitor platform reliability. The integration described here is for your own app.
SDK Wrapper Order
CodePush must be the outermost wrapper so it can swap the bundle before Sentry initializes:
export default codePush(Sentry.wrap(App));
Reversing the order (Sentry.wrap(codePush(App))) causes Sentry to capture the pre-update bundle's module graph, making sourcemap uploads for that release ineffective.
Generate Sourcemaps
Pass --sourcemapOutput to dpctl release-react. Keep the sourcemap outside --outputDir — otherwise the .map file gets bundled into the OTA release zip:
dpctl release-react MyApp-iOS ios \
--outputDir ./release \
--sourcemapOutput ./sourcemaps/main.jsbundle.map
Upload Sourcemaps — JSC Engine
If your app uses the JSC (JavaScriptCore) engine, upload the map file directly:
export SENTRY_ORG=your-org
export SENTRY_PROJECT=your-project
export SENTRY_AUTH_TOKEN=your-token
npx sentry-cli sourcemaps upload \
--dist YOUR_CODEPUSH_LABEL \
--rewrite \
./sourcemaps
Replace YOUR_CODEPUSH_LABEL with the label assigned to your release (e.g. v5). You can find it in the DeployPulse dashboard under the deployment's release history.
Upload Sourcemaps — Hermes Engine
Hermes (the default engine since React Native 0.70) compiles JS to bytecode, producing two map files: a packager map and a compiler map. You must compose them before uploading:
node node_modules/react-native/scripts/compose-source-maps.js \
./sourcemaps/main.jsbundle.packager.map \
./sourcemaps/main.jsbundle.compiler.map \
-o ./sourcemaps/main.jsbundle.map
npx sentry-cli sourcemaps upload \
--dist YOUR_CODEPUSH_LABEL \
--rewrite \
./sourcemaps
Pass --useHermes to dpctl release-react to ensure Hermes bytecode is generated as part of the bundle step.
GitHub Actions Example
Add these steps after your dpctl release-react step:
- name: Release to DeployPulse
env:
DEPLOYPULSE_ACCESS_KEY: ${{ secrets.DEPLOYPULSE_ACCESS_KEY }}
run: |
dpctl release-react MyApp-iOS ios \
--outputDir ./release \
--sourcemapOutput ./sourcemaps/main.jsbundle.map
- name: Compose Hermes sourcemaps
run: |
node node_modules/react-native/scripts/compose-source-maps.js \
./sourcemaps/main.jsbundle.packager.map \
./sourcemaps/main.jsbundle.compiler.map \
-o ./sourcemaps/main.jsbundle.map
- name: Upload sourcemaps to Sentry
env:
DEPLOYPULSE_ACCESS_KEY: ${{ secrets.DEPLOYPULSE_ACCESS_KEY }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: |
LABEL=$(dpctl deployment history MyApp-iOS Production \
--format json | jq -r '.[-1].label')
npx sentry-cli sourcemaps upload \
--dist "$LABEL" \
--rewrite \
./sourcemaps
The jq expression extracts the latest release label automatically so the --dist value stays in sync with what DeployPulse assigned.
Further Reading
- GitHub Actions Integration — full CI/CD workflow for DeployPulse releases
- Bitrise Integration — Bitrise step for automated OTA releases
- Code Signing — sign bundles so devices can verify integrity before applying an update
