From 03daa62021d48e250eb011e3e02307e1637d1a70 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Thu, 26 Feb 2026 16:43:20 +0100 Subject: [PATCH 1/2] fix(ios): resolve relative SOURCEMAP_FILE against project root in Xcode build script When users set SOURCEMAP_FILE to a relative path (e.g. `SOURCEMAP_FILE=maps/main.jsbundle.map`), the value is now resolved against the project root (one level up from `ios/`) rather than against the `ios/` directory where the Xcode build script runs. Without this fix, sentry-cli could not find the source map because the bundle is created relative to the project root. Fixes #3889 Co-Authored-By: Claude Sonnet 4.6 --- packages/core/scripts/sentry-xcode.sh | 7 ++ .../test/scripts/sentry-xcode-scripts.test.ts | 77 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/packages/core/scripts/sentry-xcode.sh b/packages/core/scripts/sentry-xcode.sh index 2ab36fc1b1..973f358b39 100755 --- a/packages/core/scripts/sentry-xcode.sh +++ b/packages/core/scripts/sentry-xcode.sh @@ -15,6 +15,13 @@ RN_PROJECT_ROOT="${PROJECT_DIR}/.." [ -z "$SENTRY_PROPERTIES" ] && export SENTRY_PROPERTIES=sentry.properties [ -z "$SENTRY_DOTENV_PATH" ] && [ -f "$RN_PROJECT_ROOT/.env.sentry-build-plugin" ] && export SENTRY_DOTENV_PATH="$RN_PROJECT_ROOT/.env.sentry-build-plugin" [ -z "$SOURCEMAP_FILE" ] && export SOURCEMAP_FILE="$DERIVED_FILE_DIR/main.jsbundle.map" +# Resolve relative SOURCEMAP_FILE to absolute. The script runs from `ios/` (Xcode's PWD), +# but users typically specify paths relative to the project root. Without this, sentry-cli +# would resolve relative paths against `ios/` and fail to find the file. +# See: https://github.com/getsentry/sentry-react-native/issues/3889 +if [[ "$SOURCEMAP_FILE" != /* ]]; then + export SOURCEMAP_FILE="$(cd "$RN_PROJECT_ROOT" && pwd)/$SOURCEMAP_FILE" +fi if [ -z "$SENTRY_CLI_EXECUTABLE" ]; then # Try standard resolution safely diff --git a/packages/core/test/scripts/sentry-xcode-scripts.test.ts b/packages/core/test/scripts/sentry-xcode-scripts.test.ts index aac5d69566..7e9252ad05 100644 --- a/packages/core/test/scripts/sentry-xcode-scripts.test.ts +++ b/packages/core/test/scripts/sentry-xcode-scripts.test.ts @@ -454,4 +454,81 @@ describe('sentry-xcode.sh', () => { expect(result.stdout).toContain('SENTRY_DISABLE_AUTO_UPLOAD=true'); expect(result.stdout).toContain('skipping sourcemaps upload'); }); + + describe('SOURCEMAP_FILE path resolution', () => { + // Returns a mock sentry-cli that prints the SOURCEMAP_FILE env var it received. + const makeSourcmapEchoScript = (dir: string): string => { + const scriptPath = path.join(dir, 'mock-sentry-cli-echo-sourcemap.js'); + fs.writeFileSync( + scriptPath, + ` + const sourcemapFile = process.env.SOURCEMAP_FILE || 'not-set'; + console.log('SOURCEMAP_FILE=' + sourcemapFile); + process.exit(0); + `, + ); + return scriptPath; + }; + + it('leaves an absolute SOURCEMAP_FILE unchanged', () => { + const absolutePath = path.join(tempDir, 'absolute', 'main.jsbundle.map'); + const echoScript = makeSourcmapEchoScript(tempDir); + + const result = runScript({ + SENTRY_CLI_EXECUTABLE: echoScript, + SOURCEMAP_FILE: absolutePath, + }); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain(`SOURCEMAP_FILE=${absolutePath}`); + }); + + it('resolves a relative SOURCEMAP_FILE against the project root, not ios/', () => { + // PROJECT_DIR is tempDir (simulates the ios/ folder). + // RN_PROJECT_ROOT = PROJECT_DIR/.. = parent of tempDir. + // A user setting SOURCEMAP_FILE=relative/path.map expects it relative to the project root. + const echoScript = makeSourcmapEchoScript(tempDir); + + const result = runScript({ + SENTRY_CLI_EXECUTABLE: echoScript, + SOURCEMAP_FILE: 'relative/path.map', + }); + + const projectRoot = path.dirname(tempDir); // PROJECT_DIR/.. = RN_PROJECT_ROOT + const expectedPath = path.join(projectRoot, 'relative/path.map'); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain(`SOURCEMAP_FILE=${expectedPath}`); + }); + + it('resolves a ./prefixed SOURCEMAP_FILE against the project root', () => { + const echoScript = makeSourcmapEchoScript(tempDir); + + const result = runScript({ + SENTRY_CLI_EXECUTABLE: echoScript, + SOURCEMAP_FILE: './maps/main.jsbundle.map', + }); + + // The script concatenates: "$(cd RN_PROJECT_ROOT && pwd)/./maps/main.jsbundle.map" + // The ./ is preserved but the path is absolute and valid for sentry-cli. + const projectRoot = path.dirname(tempDir); + const expectedPath = `${projectRoot}/./maps/main.jsbundle.map`; + + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain(`SOURCEMAP_FILE=${expectedPath}`); + }); + + it('uses the absolute default SOURCEMAP_FILE when not set by the user', () => { + const echoScript = makeSourcmapEchoScript(tempDir); + + const result = runScript({ + SENTRY_CLI_EXECUTABLE: echoScript, + // SOURCEMAP_FILE intentionally not set — script should default to $DERIVED_FILE_DIR/main.jsbundle.map + DERIVED_FILE_DIR: tempDir, + }); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain(`SOURCEMAP_FILE=${tempDir}/main.jsbundle.map`); + }); + }); }); From f79190d71df8d1e47f7138f143ea1f4ba2c6daa4 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Thu, 26 Feb 2026 16:55:54 +0100 Subject: [PATCH 2/2] changelog: resolve relative SOURCEMAP_FILE in Xcode build script --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77fd7a2dbf..478b9ed917 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ > make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first. +## Unreleased + +### Fixes + +- Resolve relative `SOURCEMAP_FILE` paths against the project root in the Xcode build script ([#5730](https://github.com/getsentry/sentry-react-native/pull/5730)) + ## 8.2.0 ### Fixes