Skip to content

chore(mobile): upload source maps to PostHog on release and OTA builds#84

Open
GSTJ wants to merge 2 commits into
mainfrom
GSTJ/posthog-sourcemaps
Open

chore(mobile): upload source maps to PostHog on release and OTA builds#84
GSTJ wants to merge 2 commits into
mainfrom
GSTJ/posthog-sourcemaps

Conversation

@GSTJ

@GSTJ GSTJ commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

Production JS stack traces in PostHog error tracking become readable: source maps now upload automatically on native release builds and OTA updates.

Details

  • Metro config wraps PostHog's Expo helper so every bundle gets a chunk/debug id injected.
  • The posthog-react-native/expo config plugin wires the upload into the Xcode bundle phase and the Android Gradle release task, added only when POSTHOG_CLI_API_KEY is present, so plain local expo run:ios / prebuild stays untouched.
  • OTA path: a small script runs expo export --dump-sourcemap + posthog-cli hermes upload, wired into the deploy workflow via eas env:exec (replaces a stale TODO claiming this CLI didn't exist).
  • No CI secret changes needed: the key lives in EAS with "sensitive" visibility, readable where the config plugin needs it.
  • Verified with real uploads to the PostHog project from both paths (native release sim build and an OTA export), server confirming the upload keys.

Testing steps

  1. Merge and let the next release or OTA update go out normally.
  2. In PostHog, open Error tracking and click any new exception from that build: the stack trace should show real file names and lines instead of minified frames.
  3. Do a local debug run of the app as usual and confirm nothing new happens at build time (no upload step, no extra output).

GSTJ added 2 commits July 8, 2026 22:51
…ve builds

Enables readable Release JS stack traces in PostHog error tracking:
- metro.config.js now wraps the default config with
  getPostHogExpoConfig, injecting a debug/chunk id into every JS
  bundle (native builds and OTA exports alike) so uploaded sourcemaps
  can be matched back to the exact bundle a crash came from.
- app.config.ts conditionally adds the posthog-react-native/expo
  plugin, which wires posthog-cli into the generated Xcode "Bundle
  React Native code and images" build phase and the Android Gradle
  release bundle task. Gated on POSTHOG_CLI_API_KEY being present so a
  bare local `expo prebuild`/`run:ios`/`run:android` never gets the
  upload step injected -- only EAS-configured builds (which pull that
  key from the EAS "production" environment) activate it.
- scripts/upload-posthog-sourcemaps-ota.sh handles the other half:
  `eas update` OTA bundles have no build phase to hook into, so this
  re-exports the JS with sourcemaps and uploads them via
  `posthog-cli hermes upload` separately. Also guarded on
  POSTHOG_CLI_API_KEY, so it's a silent no-op without credentials.

Verified locally: a Release iOS simulator build successfully created a
PostHog release and uploaded its sourcemap (server confirmed via
posthog-cli's own output), and the OTA script independently exported
+ uploaded sourcemaps for both platforms against the real PostHog
project.
deploy-mobile.yml's `eas update` step publishes the OTA bundle but
never uploaded sourcemaps anywhere -- the stale TODO here claimed
PostHog RN had no build-time upload CLI, which is no longer true
(posthog-cli's `hermes upload` command covers this).

Runs the new sourcemaps:upload:ota script through `eas env:exec
production`, which pulls POSTHOG_CLI_API_KEY/HOST/PROJECT_ID from the
EAS "production" environment (the key is stored there as "sensitive",
not "secret", so it's readable by the CLI outside the builder) and
injects them into the script's shell env.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant