Skip to content

feat(core): Introduce @sentry/expo-upload-sourcemaps package#6027

Open
antonis wants to merge 9 commits intomainfrom
antonis/expo-upload-sourcemaps-package
Open

feat(core): Introduce @sentry/expo-upload-sourcemaps package#6027
antonis wants to merge 9 commits intomainfrom
antonis/expo-upload-sourcemaps-package

Conversation

@antonis
Copy link
Copy Markdown
Contributor

@antonis antonis commented Apr 21, 2026

📢 Type of change

  • New feature
  • Bugfix
  • Enhancement
  • Refactoring

📜 Description

Adds a new scoped workspace package @sentry/expo-upload-sourcemaps containing the CLI that uploads JavaScript bundles and source maps from Expo builds to Sentry. The script previously lived at packages/core/scripts/expo-upload-sourcemaps.js inside @sentry/react-native; it is moved verbatim to packages/expo-upload-sourcemaps/cli.js, and the original path is replaced by a tiny shim that forwards to the new package.

After this lands, users can invoke the CLI two ways, both producing identical behavior:

# New (preferred)
npx @sentry/expo-upload-sourcemaps dist

# Legacy (still works, unchanged)
npx sentry-expo-upload-sourcemaps dist

Changes at a glance:

  • packages/expo-upload-sourcemaps/ — new workspace: package.json, cli.js (moved), README.md, LICENSE.md.
  • packages/core/scripts/expo-upload-sourcemaps.js — now a shim: require.resolve guard with a friendly MODULE_NOT_FOUND message, then require('@sentry/expo-upload-sourcemaps/cli.js').
  • packages/core/package.json — adds "@sentry/expo-upload-sourcemaps": "workspace:*" to dependencies. Bin surface is unchanged; sentry-expo-upload-sourcemaps is retained.
  • Root package.json — registers the new workspace.
  • .craft.yml — adds a second registry entry so the new tarball lands in the Sentry release registry.
  • yarn.lock — 19-line refresh (workspace entry + reference).

💡 Motivation and Context

The current docs at docs.sentry.io/platforms/react-native/sourcemaps/uploading/expo/ instruct users to run npx sentry-expo-upload-sourcemaps dist. That unscoped name resolves against the public npm registry when no matching local bin is found, and it is currently held by a third-party account (see https://www.npmjs.com/package/sentry-expo-upload-sourcemaps). The payload is a benign forwarder today, but it remains a third-party entry point on the documented happy path.

The first mitigation already shipped in sentry-docs (getsentry/sentry-docs#17391), routing the command through npx --package=@sentry/react-native sentry-expo-upload-sourcemaps dist. This PR is the long-term fix: publishing a Sentry-owned scoped package whose name (@sentry/*) cannot be squatted and whose invocation form is shorter and more idiomatic.

A follow-up docs PR will switch the recommended command to npx @sentry/expo-upload-sourcemaps dist once the new package is published to npm. Until then, the existing scoped command continues to work.

💚 How did you test it?

Locally on this branch:

  • yarn install — workspace linked; packages/core/node_modules/@sentry/expo-upload-sourcemaps points to packages/expo-upload-sourcemaps.
  • yarn build — 2 projects built without error.
  • yarn lint:lerna — 4 projects passed (0 errors; one pre-existing warning in samples/react-native unrelated to this change).
  • yarn circularDepCheck — no cycles.
  • yarn test:
    • packages/core SDK: 108 suites / 1302 tests passed.
    • packages/core tools: 11 suites / 210 tests passed.
    • samples/react-native: 1/1.
  • Existing packages/core/test/scripts/expo-upload-sourcemaps.test.ts (19 tests covering basic functionality, command-injection safety, Hermes flag handling, env-var validation, sentry.properties fallbacks, and _internal.sentryBuildProperties fallbacks) all pass through the shim → new package chain.
  • npm pack --dry-run on the new package produces sentry-expo-upload-sourcemaps-8.8.0.tgz with cli.js, package.json, README.md, LICENSE.md — filename matches the .craft.yml registry regex.
  • End-to-end smoke run: ./node_modules/.bin/sentry-expo-upload-sourcemaps from samples/expo successfully routes through the shim to the new package's cli.js, confirmed via the require stack.

📝 Checklist

🔮 Next steps

Moves the Expo sourcemap upload script into a new scoped workspace
package @sentry/expo-upload-sourcemaps and replaces the original
scripts/expo-upload-sourcemaps.js in @sentry/react-native with a shim
that forwards to it.

The existing sentry-expo-upload-sourcemaps bin in @sentry/react-native
keeps working unchanged, so projects with the bin referenced in
package.json scripts or invoked via npx are not affected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • feat(core): Introduce @sentry/expo-upload-sourcemaps package by antonis in #6027
  • feat(ai): Re-export AI SDK manual instrumentation helpers by alwx in #6028
  • feat(core): Expose scope-level attributes API by antonis in #6009
  • chore(deps): Force basic-ftp >=5.3.0 to fix GHSA-rp42-5vxx-qpwr by antonis in #6024
  • feat(core): Add GlobalErrorBoundary for non-rendering errors by alwx in #6023
  • chore(deps): update CLI to v3.4.0 by github-actions in #6026
  • feat: Expose screenshot masking options for error screenshots by antonis in #6007
  • fix(replay): Check captureReplay return value in iOS bridge by antonis in #6008
  • chore(deps): bump getsentry/craft from 2.25.2 to 2.25.4 by dependabot in #6019
  • chore(deps): bump getsentry/craft/.github/workflows/changelog-preview.yml from 2.25.2 to 2.25.4 by dependabot in #6021
  • chore(deps): bump github/codeql-action from 4.35.1 to 4.35.2 by dependabot in #6022
  • chore(deps): bump actions/setup-node from 6.3.0 to 6.4.0 by dependabot in #6020
  • ci(danger): Demote Android SDK version mismatch from fail to warn by antonis in #6018
  • chore(deps): update Android SDK to v8.39.1 by github-actions in #6010
  • chore(deps): update JavaScript SDK to v10.49.0 by github-actions in #6011
  • ci: Integrate Warden for AI-powered PR code review by antonis in #6003
  • chore(lint): Fixes lint issue on main by antonis in #6013
  • feat(expo): Warn when prebuilt native projects are missing Sentry config by alwx in #5984

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 548c668

Comment thread packages/expo-upload-sourcemaps/cli.js
Comment thread packages/expo-upload-sourcemaps/cli.js Outdated
…ckage

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread CHANGELOG.md Outdated
antonis and others added 3 commits April 21, 2026 10:51
…d-sourcemaps bin

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop the callback passed to fs.writeFileSync. writeFileSync is
  synchronous and silently discards the callback argument; the error
  branch never fired and the success log never printed.
- Preserve a non-zero exit code when sentry-cli is terminated by a
  signal. spawnSync returns result.status === null in that case, and
  process.exit(null) coerces to 0, previously reporting success after
  an aborted upload.

Both issues were inherited verbatim from the script's prior location
inside @sentry/react-native. Fixed now that the script has moved to
its own package.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread packages/expo-upload-sourcemaps/cli.js
Comment thread packages/expo-upload-sourcemaps/cli.js
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit f4a48df. Configure here.

antonis and others added 2 commits April 21, 2026 11:21
…arball

Yarn 3's built-in shell errors on unmatched globs, so the inlined
"rm -f *.tgz && npm pack" fails in CI where no prior tarball exists.
Match packages/core's pattern and run through real bash via a script
file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ype check

Yalc rewrites the workspace:* dep to 8.8.0 when publishing @sentry/react-native,
so ts3.8-test's yarn install tries to fetch @sentry/expo-upload-sourcemaps@8.8.0
from the npm registry before the package is published and fails with 404.

Publish and yalc-add the new package alongside @sentry/react-native, and pin
the transitive dep to the same local file reference via resolutions so yarn
doesn't try to resolve it from the registry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@sentry-warden sentry-warden Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New CLI package lacks test coverage

The new @sentry/expo-upload-sourcemaps package contains significant business logic (expo config parsing, sentry.properties file parsing, asset grouping, upload orchestration) but has no test files. The skill guidelines require appropriate test coverage for new functionality, including functional tests for business logic and integration tests for component interactions. Key functions like getSentryPluginPropertiesFromExpoConfig, getSentryPropertiesFromFile, groupAssets, and the upload loop should have tests.

Identified by Warden code-review

@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Apr 21, 2026

Re: #6027 (review)

The business logic Warden flags is covered by the existing 19-test suite at packages/core/test/scripts/expo-upload-sourcemaps.test.ts, which runs the bin end-to-end via spawnSync. After this PR that path goes through the shim → @sentry/expo-upload-sourcemaps/cli.js, so all the functions Warden lists (getSentryPluginPropertiesFromExpoConfig, getSentryPropertiesFromFile, groupAssets, the upload loop) are exercised on every test run.

The tests are intentionally kept in the consumer's test suite because migrating them here would require introducing a new jest/ts-jest/tsconfig pipeline in this package just for one test file. If standalone coverage becomes important later (e.g. if the new package is used independently of @sentry/react-native), we can colocate then.

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Apr 21, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 410.14 ms 418.78 ms 8.64 ms
Size 43.75 MiB 48.14 MiB 4.39 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
2c735cc+dirty 414.09 ms 438.47 ms 24.38 ms
04207c4+dirty 459.19 ms 518.54 ms 59.35 ms
3d377b5+dirty 406.18 ms 453.52 ms 47.34 ms
3ce5254+dirty 410.57 ms 448.48 ms 37.91 ms
df5d108+dirty 527.06 ms 603.58 ms 76.52 ms
a50b33d+dirty 500.81 ms 532.11 ms 31.30 ms
0d9949d+dirty 403.57 ms 437.00 ms 33.43 ms
7ac3378+dirty 404.78 ms 439.84 ms 35.06 ms
5fe1c6c+dirty 401.62 ms 445.28 ms 43.66 ms
890d145+dirty 504.54 ms 491.55 ms -12.99 ms

App size

Revision Plain With Sentry Diff
2c735cc+dirty 43.75 MiB 48.08 MiB 4.33 MiB
04207c4+dirty 43.75 MiB 48.12 MiB 4.37 MiB
3d377b5+dirty 43.75 MiB 48.14 MiB 4.39 MiB
3ce5254+dirty 43.75 MiB 48.12 MiB 4.37 MiB
df5d108+dirty 43.75 MiB 48.08 MiB 4.33 MiB
a50b33d+dirty 43.75 MiB 48.08 MiB 4.33 MiB
0d9949d+dirty 43.75 MiB 48.13 MiB 4.37 MiB
7ac3378+dirty 43.75 MiB 48.13 MiB 4.37 MiB
5fe1c6c+dirty 43.75 MiB 48.14 MiB 4.39 MiB
890d145+dirty 43.75 MiB 48.14 MiB 4.39 MiB

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1223.08 ms 1228.73 ms 5.64 ms
Size 3.38 MiB 4.77 MiB 1.39 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
2c735cc+dirty 1229.67 ms 1221.50 ms -8.17 ms
3d377b5+dirty 1218.48 ms 1219.51 ms 1.03 ms
df5d108+dirty 1225.90 ms 1220.14 ms -5.76 ms
3817909+dirty 1183.90 ms 1187.50 ms 3.60 ms
5fe1c6c+dirty 1220.79 ms 1217.63 ms -3.16 ms
3ce5254+dirty 1219.93 ms 1221.90 ms 1.96 ms
04207c4+dirty 1191.27 ms 1189.78 ms -1.48 ms
7ac3378+dirty 1213.37 ms 1218.15 ms 4.78 ms
890d145+dirty 1223.59 ms 1231.37 ms 7.78 ms
5c1e987+dirty 1204.30 ms 1222.15 ms 17.85 ms

App size

Revision Plain With Sentry Diff
2c735cc+dirty 3.38 MiB 4.74 MiB 1.35 MiB
3d377b5+dirty 3.38 MiB 4.76 MiB 1.38 MiB
df5d108+dirty 3.38 MiB 4.73 MiB 1.35 MiB
3817909+dirty 3.38 MiB 4.73 MiB 1.35 MiB
5fe1c6c+dirty 3.38 MiB 4.77 MiB 1.39 MiB
3ce5254+dirty 3.38 MiB 4.76 MiB 1.38 MiB
04207c4+dirty 3.38 MiB 4.76 MiB 1.38 MiB
7ac3378+dirty 3.38 MiB 4.76 MiB 1.38 MiB
890d145+dirty 3.38 MiB 4.77 MiB 1.38 MiB
5c1e987+dirty 3.38 MiB 4.73 MiB 1.35 MiB

@sentry
Copy link
Copy Markdown

sentry Bot commented Apr 21, 2026

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
Sentry RN io.sentry.reactnative.sample 8.8.0 (83) Release

⚙️ sentry-react-native Build Distribution Settings

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1215.22 ms 1215.54 ms 0.32 ms
Size 3.38 MiB 4.77 MiB 1.39 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
2c735cc+dirty 1223.33 ms 1224.38 ms 1.04 ms
3d377b5+dirty 1201.55 ms 1201.80 ms 0.25 ms
df5d108+dirty 1207.34 ms 1210.50 ms 3.16 ms
3817909+dirty 1210.76 ms 1215.64 ms 4.89 ms
5fe1c6c+dirty 1201.36 ms 1209.15 ms 7.78 ms
3ce5254+dirty 1217.70 ms 1224.69 ms 6.99 ms
04207c4+dirty 1228.55 ms 1226.04 ms -2.51 ms
7ac3378+dirty 1202.35 ms 1198.31 ms -4.04 ms
890d145+dirty 1212.98 ms 1220.10 ms 7.12 ms
5c1e987+dirty 1208.43 ms 1220.72 ms 12.29 ms

App size

Revision Plain With Sentry Diff
2c735cc+dirty 3.38 MiB 4.74 MiB 1.35 MiB
3d377b5+dirty 3.38 MiB 4.76 MiB 1.38 MiB
df5d108+dirty 3.38 MiB 4.73 MiB 1.35 MiB
3817909+dirty 3.38 MiB 4.73 MiB 1.35 MiB
5fe1c6c+dirty 3.38 MiB 4.77 MiB 1.39 MiB
3ce5254+dirty 3.38 MiB 4.76 MiB 1.38 MiB
04207c4+dirty 3.38 MiB 4.76 MiB 1.38 MiB
7ac3378+dirty 3.38 MiB 4.76 MiB 1.38 MiB
890d145+dirty 3.38 MiB 4.77 MiB 1.38 MiB
5c1e987+dirty 3.38 MiB 4.73 MiB 1.35 MiB

antonis and others added 2 commits April 21, 2026 14:12
…etup

The e2e CLI (dev-packages/e2e-tests/cli.mjs) yalc-publishes @sentry/react-native
and yalc-adds it into each matrix RN app. Yalc rewrites the workspace:* dep to
a concrete 8.8.0, so yarn install in the sample app tries to fetch
@sentry/expo-upload-sourcemaps@8.8.0 from the npm registry and 404s.

Mirror the fix applied to the TypeScript 3.8 type check: also yalc-publish the
new package, yalc-add it in the sample, and pin the transitive dep to the file
reference via resolutions so yarn does not touch the registry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@antonis antonis requested a review from cleptric April 21, 2026 12:42
@antonis antonis marked this pull request as ready for review April 21, 2026 12:42
@github-actions
Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 368.15 ms 440.20 ms 72.05 ms
Size 43.94 MiB 49.00 MiB 5.06 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
2c735cc+dirty 435.20 ms 459.48 ms 24.28 ms
04207c4+dirty 395.40 ms 456.55 ms 61.15 ms
3d377b5+dirty 425.38 ms 440.67 ms 15.30 ms
3ce5254+dirty 373.90 ms 427.84 ms 53.94 ms
df5d108+dirty 434.82 ms 447.39 ms 12.57 ms
a50b33d+dirty 353.21 ms 398.48 ms 45.27 ms
0d9949d+dirty 414.88 ms 428.68 ms 13.81 ms
7ac3378+dirty 410.67 ms 442.60 ms 31.92 ms
5fe1c6c+dirty 365.84 ms 408.62 ms 42.78 ms
890d145+dirty 486.42 ms 514.85 ms 28.43 ms

App size

Revision Plain With Sentry Diff
2c735cc+dirty 43.94 MiB 48.94 MiB 5.00 MiB
04207c4+dirty 43.94 MiB 48.98 MiB 5.04 MiB
3d377b5+dirty 43.94 MiB 49.00 MiB 5.06 MiB
3ce5254+dirty 43.94 MiB 48.98 MiB 5.04 MiB
df5d108+dirty 43.94 MiB 48.94 MiB 5.00 MiB
a50b33d+dirty 43.94 MiB 48.94 MiB 5.00 MiB
0d9949d+dirty 43.94 MiB 48.99 MiB 5.05 MiB
7ac3378+dirty 43.94 MiB 48.99 MiB 5.05 MiB
5fe1c6c+dirty 43.94 MiB 49.00 MiB 5.06 MiB
890d145+dirty 43.94 MiB 49.00 MiB 5.06 MiB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant