Skip to content
Open
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Expose `addConsoleInstrumentationFilter` from `@sentry/core` ([#6180](https://github.com/getsentry/sentry-react-native/pull/6180))
- Expose experimental `captureSurfaceViews` option for Android Session Replay ([#6175](https://github.com/getsentry/sentry-react-native/pull/6175))
- Add OTA SDK version to native `sdk.packages` when JS bundle version differs from built-in version ([#6191](https://github.com/getsentry/sentry-react-native/pull/6191))
- Add `disableAutoUpload` option to Expo plugin to disable source map and debug symbol uploads ([#6195](https://github.com/getsentry/sentry-react-native/pull/6195))
Comment thread
antonis marked this conversation as resolved.
Outdated

### Fixes

Expand Down
13 changes: 11 additions & 2 deletions packages/core/plugin/src/withSentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
authToken?: string;
url?: string;
useNativeInit?: boolean;
disableAutoUpload?: boolean;
Comment thread
lucas-zimerman marked this conversation as resolved.
options?: Record<string, unknown>;
experimental_android?: SentryAndroidGradlePluginOptions;
}
Expand Down Expand Up @@ -67,7 +68,11 @@
}
if (sentryProperties !== null) {
try {
cfg = withSentryAndroid(cfg, { sentryProperties, useNativeInit: props?.useNativeInit });
cfg = withSentryAndroid(cfg, {

Check warning on line 71 in packages/core/plugin/src/withSentry.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

[EVY-6SJ] `shouldSentryAutoUploadGeneral` override is never removed when `disableAutoUpload` switches back to `false` (additional location)

When `disableAutoUpload` is toggled from `true` to `false` and prebuild is re-run, the `project.ext.shouldSentryAutoUploadGeneral = { -> return false }` line stays in `build.gradle` and uploads remain disabled โ€” contradicting the user's new config.
sentryProperties,
useNativeInit: props?.useNativeInit,
disableAutoUpload: props?.disableAutoUpload,

Check warning on line 74 in packages/core/plugin/src/withSentry.ts

View check run for this annotation

@sentry/warden / warden: code-review

[GWL-P7H] `disableAutoUpload: false` does not remove a previously written `shouldSentryAutoUploadGeneral` override (additional location)

If a project was pre-built with `disableAutoUpload: true` and then re-built with `disableAutoUpload: false`, the `shouldSentryAutoUploadGeneral = { -> return false }` line already in `build.gradle` is never removed, so uploads remain silently disabled despite the option being turned off.
});
} catch (e) {
warnOnce(`There was a problem with configuring your native Android project: ${e}`);
}
Expand All @@ -80,7 +85,11 @@
}
}
try {
cfg = withSentryIOS(cfg, { sentryProperties, useNativeInit: props?.useNativeInit });
cfg = withSentryIOS(cfg, {

Check warning on line 88 in packages/core/plugin/src/withSentry.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

`disableAutoUpload: false` does not remove `export SENTRY_DISABLE_AUTO_UPLOAD=true` from Xcode build phases on re-prebuild

If a project was previously prebuilt with `disableAutoUpload: true` and is prebuilt again with `disableAutoUpload: false` (or the option omitted), the `export SENTRY_DISABLE_AUTO_UPLOAD=true` line remains in both the 'Bundle React Native code and images' and 'Upload Debug Symbols to Sentry' shell scripts. Neither `modifyExistingXcodeBuildScript` nor the existing-`sentryBuildPhase` branch in `withSentryIOS` removes the export when `disableAutoUpload` is false, and `addDisableAutoUploadToExistingScript` only adds the line. As a result, toggling the option off does not actually re-enable auto-upload on iOS without a `--clean` prebuild.
sentryProperties,
useNativeInit: props?.useNativeInit,
disableAutoUpload: props?.disableAutoUpload,
});
} catch (e) {
warnOnce(`There was a problem with configuring your native iOS project: ${e}`);
}
Expand Down
24 changes: 17 additions & 7 deletions packages/core/plugin/src/withSentryAndroid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
import { warnOnce } from './logger';
import { writeSentryPropertiesTo } from './utils';

export const withSentryAndroid: ConfigPlugin<{ sentryProperties: string; useNativeInit: boolean | undefined }> = (
config,
{ sentryProperties, useNativeInit = false },
) => {
export const withSentryAndroid: ConfigPlugin<{
sentryProperties: string;
useNativeInit: boolean | undefined;
disableAutoUpload: boolean | undefined;
}> = (config, { sentryProperties, useNativeInit = false, disableAutoUpload = false }) => {
const appBuildGradleCfg = withAppBuildGradle(config, config => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = modifyAppBuildGradle(config.modResults.contents);
config.modResults.contents = modifyAppBuildGradle(config.modResults.contents, disableAutoUpload);
} else {
throw new Error('Cannot configure Sentry in the app gradle because the build.gradle is not groovy');
}
Expand All @@ -39,10 +40,16 @@
* Writes to projectDirectory/android/app/build.gradle,
* adding the relevant @sentry/react-native script.
*/
export function modifyAppBuildGradle(buildGradle: string): string {
export function modifyAppBuildGradle(buildGradle: string, disableAutoUpload: boolean = false): string {
if (buildGradle.includes('sentry.gradle')) {
if (disableAutoUpload && !buildGradle.includes('shouldSentryAutoUploadGeneral')) {
Comment thread
sentry-warden[bot] marked this conversation as resolved.
return buildGradle.replace(
/^(apply from:.*sentry\.gradle.*)$/m,
`$1\nproject.ext.shouldSentryAutoUploadGeneral = { -> return false }`,
);
}
return buildGradle;

Check warning on line 51 in packages/core/plugin/src/withSentryAndroid.ts

View check run for this annotation

@sentry/warden / warden: code-review

`disableAutoUpload: false` does not remove a previously written `shouldSentryAutoUploadGeneral` override

If a project was pre-built with `disableAutoUpload: true` and then re-built with `disableAutoUpload: false`, the `shouldSentryAutoUploadGeneral = { -> return false }` line already in `build.gradle` is never removed, so uploads remain silently disabled despite the option being turned off.
Comment thread
antonis marked this conversation as resolved.
}

Check warning on line 52 in packages/core/plugin/src/withSentryAndroid.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

`shouldSentryAutoUploadGeneral` override is never removed when `disableAutoUpload` switches back to `false`

When `disableAutoUpload` is toggled from `true` to `false` and prebuild is re-run, the `project.ext.shouldSentryAutoUploadGeneral = { -> return false }` line stays in `build.gradle` and uploads remain disabled โ€” contradicting the user's new config.

// Use the same location that sentry-wizard uses
// See: https://github.com/getsentry/sentry-wizard/blob/e9b4522f27a852069c862bd458bdf9b07cab6e33/lib/Steps/Integrations/ReactNative.ts#L232
Expand All @@ -56,17 +63,20 @@
}

const applyFrom = `apply from: new File(${resolveSentryReactNativePackageJsonPath}, "sentry.gradle")`;
const disableUploadOverride = disableAutoUpload
? `\nproject.ext.shouldSentryAutoUploadGeneral = { -> return false }`
: '';

return buildGradle.replace(pattern, match => `${applyFrom}\n\n${match}`);
return buildGradle.replace(pattern, match => `${applyFrom}${disableUploadOverride}\n\n${match}`);
}

export function modifyMainApplication(config: ExpoConfig): ExpoConfig {
return withMainApplication(config, config => {
if (!config.modResults?.path) {
warnOnce("Can't add 'RNSentrySDK.init' to Android MainApplication, because the file was not found.");
return config;
}

Check warning on line 79 in packages/core/plugin/src/withSentryAndroid.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

[VWK-SSV] `disableAutoUpload: false` does not remove `export SENTRY_DISABLE_AUTO_UPLOAD=true` from Xcode build phases on re-prebuild (additional location)

If a project was previously prebuilt with `disableAutoUpload: true` and is prebuilt again with `disableAutoUpload: false` (or the option omitted), the `export SENTRY_DISABLE_AUTO_UPLOAD=true` line remains in both the 'Bundle React Native code and images' and 'Upload Debug Symbols to Sentry' shell scripts. Neither `modifyExistingXcodeBuildScript` nor the existing-`sentryBuildPhase` branch in `withSentryIOS` removes the export when `disableAutoUpload` is false, and `addDisableAutoUploadToExistingScript` only adds the line. As a result, toggling the option off does not actually re-enable auto-upload on iOS without a `--clean` prebuild.
// oxlint-disable-next-line typescript-eslint(no-unsafe-member-access)
const fileName = path.basename(config.modResults.path);

Expand Down
46 changes: 36 additions & 10 deletions packages/core/plugin/src/withSentryIOS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
"`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"`";
const SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH =
"`${NODE_BINARY:-node} --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode-debug-files.sh'\"`";
const SENTRY_DISABLE_AUTO_UPLOAD_EXPORT = 'export SENTRY_DISABLE_AUTO_UPLOAD=true';

export const withSentryIOS: ConfigPlugin<{ sentryProperties: string; useNativeInit: boolean | undefined }> = (
config,
{ sentryProperties, useNativeInit = false },
) => {
export const withSentryIOS: ConfigPlugin<{
sentryProperties: string;
useNativeInit: boolean | undefined;
disableAutoUpload: boolean | undefined;
}> = (config, { sentryProperties, useNativeInit = false, disableAutoUpload = false }) => {
const xcodeProjectCfg = withXcodeProject(config, config => {
const xcodeProject: XcodeProject = config.modResults;

Expand All @@ -27,17 +29,22 @@
'PBXShellScriptBuildPhase',
);
if (!sentryBuildPhase) {
const debugFilesScript = disableAutoUpload
? `${SENTRY_DISABLE_AUTO_UPLOAD_EXPORT}\n/bin/sh ${SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH}`
: `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH}`;
xcodeProject.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Upload Debug Symbols to Sentry', null, {
shellPath: '/bin/sh',
shellScript: `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH}`,
shellScript: debugFilesScript,
});
} else if (disableAutoUpload) {
addDisableAutoUploadToExistingScript(sentryBuildPhase);
}

const bundleReactNativePhase = xcodeProject.pbxItemByComment(
'Bundle React Native code and images',
'PBXShellScriptBuildPhase',
);
modifyExistingXcodeBuildScript(bundleReactNativePhase);
modifyExistingXcodeBuildScript(bundleReactNativePhase, disableAutoUpload);

return config;
});
Expand All @@ -53,17 +60,20 @@
]);
};

export function modifyExistingXcodeBuildScript(script: BuildPhase): void {
export function modifyExistingXcodeBuildScript(script: BuildPhase, disableAutoUpload: boolean = false): void {
if (!script.shellScript.match(/(packager|scripts)\/react-native-xcode\.sh\b/)) {
warnOnce(
`'react-native-xcode.sh' not found in 'Bundle React Native code and images'.
Please open a bug report at https://github.com/getsentry/sentry-react-native`,
);
return;
}

if (script.shellScript.includes('sentry-xcode.sh')) {
if (disableAutoUpload) {
addDisableAutoUploadToExistingScript(script);
}
warnOnce("The latest 'sentry-xcode.sh' script already exists in 'Bundle React Native code and images'.");

Check warning on line 76 in packages/core/plugin/src/withSentryIOS.ts

View check run for this annotation

@sentry/warden / warden: code-review

`SENTRY_DISABLE_AUTO_UPLOAD=true` is never removed when `disableAutoUpload` is toggled back to `false`

If a user sets `disableAutoUpload: true`, runs `expo prebuild`, then later changes to `disableAutoUpload: false` and re-runs `expo prebuild`, the injected `export SENTRY_DISABLE_AUTO_UPLOAD=true` line is never removed from the Xcode build phases โ€” uploads remain silently disabled. Consider adding a cleanup pass that removes the export line when `disableAutoUpload` is `false` and the line is present, or documenting that `--clean` is required to re-enable uploads.

Check warning on line 76 in packages/core/plugin/src/withSentryIOS.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

[VWK-SSV] `disableAutoUpload: false` does not remove `export SENTRY_DISABLE_AUTO_UPLOAD=true` from Xcode build phases on re-prebuild (additional location)

If a project was previously prebuilt with `disableAutoUpload: true` and is prebuilt again with `disableAutoUpload: false` (or the option omitted), the `export SENTRY_DISABLE_AUTO_UPLOAD=true` line remains in both the 'Bundle React Native code and images' and 'Upload Debug Symbols to Sentry' shell scripts. Neither `modifyExistingXcodeBuildScript` nor the existing-`sentryBuildPhase` branch in `withSentryIOS` removes the export when `disableAutoUpload` is false, and `addDisableAutoUploadToExistingScript` only adds the line. As a result, toggling the option off does not actually re-enable auto-upload on iOS without a `--clean` prebuild.
return;
}

Expand All @@ -77,16 +87,32 @@
}

const code = JSON.parse(script.shellScript);
script.shellScript = JSON.stringify(addSentryWithBundledScriptsToBundleShellScript(code));
script.shellScript = JSON.stringify(addSentryWithBundledScriptsToBundleShellScript(code, disableAutoUpload));
}

export function addSentryWithBundledScriptsToBundleShellScript(script: string): string {
export function addSentryWithBundledScriptsToBundleShellScript(
script: string,
disableAutoUpload: boolean = false,
): string {
const disableAutoUploadExport = disableAutoUpload ? `${SENTRY_DISABLE_AUTO_UPLOAD_EXPORT}\n` : '';
return script.replace(
/^.*?(packager|scripts)\/react-native-xcode\.sh\s*(\\'\\\\")?/m,
(match: string) => `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_PATH} ${match}`,
(match: string) => `${disableAutoUploadExport}/bin/sh ${SENTRY_REACT_NATIVE_XCODE_PATH} ${match}`,
);
}

export function addDisableAutoUploadToExistingScript(script: BuildPhase): void {
if (script.shellScript.includes('SENTRY_DISABLE_AUTO_UPLOAD')) {
return;
}
try {
const code = JSON.parse(script.shellScript);
script.shellScript = JSON.stringify(`${SENTRY_DISABLE_AUTO_UPLOAD_EXPORT}\n${code}`);
} catch {
script.shellScript = `${SENTRY_DISABLE_AUTO_UPLOAD_EXPORT}\n${script.shellScript}`;
}
}
Comment thread
cursor[bot] marked this conversation as resolved.

export function modifyAppDelegate(config: ExpoConfig): ExpoConfig {
return withAppDelegate(config, async config => {
if (!config.modResults?.path) {
Expand Down
28 changes: 28 additions & 0 deletions packages/core/test/expo-plugin/modifyAppBuildGradle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,32 @@
modifyAppBuildGradle(buildGradleWithOutReactGradleScript);
expect(warnOnce).toHaveBeenCalled();
});

it('Adds shouldSentryAutoUploadGeneral override when disableAutoUpload is true', () => {
const result = modifyAppBuildGradle(buildGradleWithOutSentry, true);
expect(result).toContain('project.ext.shouldSentryAutoUploadGeneral = { -> return false }');
expect(result).toContain('sentry.gradle');
});

Check warning on line 60 in packages/core/test/expo-plugin/modifyAppBuildGradle.test.ts

View check run for this annotation

@sentry/warden / warden: code-review

[GWL-P7H] `disableAutoUpload: false` does not remove a previously written `shouldSentryAutoUploadGeneral` override (additional location)

If a project was pre-built with `disableAutoUpload: true` and then re-built with `disableAutoUpload: false`, the `shouldSentryAutoUploadGeneral = { -> return false }` line already in `build.gradle` is never removed, so uploads remain silently disabled despite the option being turned off.
it('Does not add shouldSentryAutoUploadGeneral override when disableAutoUpload is false', () => {
const result = modifyAppBuildGradle(buildGradleWithOutSentry, false);
expect(result).not.toContain('shouldSentryAutoUploadGeneral');
});

it('Adds override to already-configured build.gradle on re-prebuild', () => {
const result = modifyAppBuildGradle(buildGradleWithSentry, true);

Check warning on line 67 in packages/core/test/expo-plugin/modifyAppBuildGradle.test.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

[EVY-6SJ] `shouldSentryAutoUploadGeneral` override is never removed when `disableAutoUpload` switches back to `false` (additional location)

When `disableAutoUpload` is toggled from `true` to `false` and prebuild is re-run, the `project.ext.shouldSentryAutoUploadGeneral = { -> return false }` line stays in `build.gradle` and uploads remain disabled โ€” contradicting the user's new config.
expect(result).toContain('project.ext.shouldSentryAutoUploadGeneral = { -> return false }');
});

it('Does not duplicate override if already present', () => {
const gradleWithOverride = `
apply from: new File(["node", "--print", "require('path').dirname(require.resolve('@sentry/react-native/package.json'))"].execute().text.trim(), "sentry.gradle")
project.ext.shouldSentryAutoUploadGeneral = { -> return false }

android {
}
`;
const result = modifyAppBuildGradle(gradleWithOverride, true);
expect(result).toBe(gradleWithOverride);
});
});
125 changes: 124 additions & 1 deletion packages/core/test/expo-plugin/modifyXcodeProject.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { warnOnce } from '../../plugin/src/logger';
import { modifyExistingXcodeBuildScript } from '../../plugin/src/withSentryIOS';
import {

Check warning on line 2 in packages/core/test/expo-plugin/modifyXcodeProject.test.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

[VWK-SSV] `disableAutoUpload: false` does not remove `export SENTRY_DISABLE_AUTO_UPLOAD=true` from Xcode build phases on re-prebuild (additional location)

If a project was previously prebuilt with `disableAutoUpload: true` and is prebuilt again with `disableAutoUpload: false` (or the option omitted), the `export SENTRY_DISABLE_AUTO_UPLOAD=true` line remains in both the 'Bundle React Native code and images' and 'Upload Debug Symbols to Sentry' shell scripts. Neither `modifyExistingXcodeBuildScript` nor the existing-`sentryBuildPhase` branch in `withSentryIOS` removes the export when `disableAutoUpload` is false, and `addDisableAutoUploadToExistingScript` only adds the line. As a result, toggling the option off does not actually re-enable auto-upload on iOS without a `--clean` prebuild.
addDisableAutoUploadToExistingScript,
addSentryWithBundledScriptsToBundleShellScript,
modifyExistingXcodeBuildScript,
} from '../../plugin/src/withSentryIOS';

jest.mock('../../plugin/src/logger');

Expand Down Expand Up @@ -77,6 +81,125 @@
});
});

describe('disableAutoUpload option for Bundle React Native code phase', () => {
let consoleWarnMock: jest.SpyInstance<void, [message?: any, ...optionalParams: any[]], any>;

beforeEach(() => {
consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation();
});

afterEach(() => {
consoleWarnMock.mockRestore();
});

it('Prepends export on its own line when disableAutoUpload is true', () => {
const script = Object.assign({}, buildScriptWithoutSentry);
modifyExistingXcodeBuildScript(script, true);
const parsed = JSON.parse(script.shellScript);
expect(parsed).toMatch(/^export SENTRY_DISABLE_AUTO_UPLOAD=true\n/m);
expect(parsed).toContain('sentry-xcode.sh');
});

it('Does not prepend export when disableAutoUpload is false', () => {
const script = Object.assign({}, buildScriptWithoutSentry);
modifyExistingXcodeBuildScript(script, false);
const parsed = JSON.parse(script.shellScript);
expect(parsed).not.toContain('SENTRY_DISABLE_AUTO_UPLOAD');
});

it('Injects export into already-configured bundle script on re-prebuild', () => {
const script = Object.assign({}, buildScriptWithSentry);
modifyExistingXcodeBuildScript(script, true);
const parsed = JSON.parse(script.shellScript);
expect(parsed).toMatch(/^export SENTRY_DISABLE_AUTO_UPLOAD=true\n/);
expect(parsed).toContain('sentry-xcode.sh');
});

it('Does not duplicate export if already present in bundle script', () => {
const scriptWithExport = {
shellScript: JSON.stringify(`export SENTRY_DISABLE_AUTO_UPLOAD=true
"
export NODE_BINARY=node
/bin/sh \`"$NODE_BINARY" --print "require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'"\` ../node_modules/react-native/scripts/react-native-xcode.sh
"`),
};
const before = scriptWithExport.shellScript;
modifyExistingXcodeBuildScript(scriptWithExport, true);
expect(scriptWithExport.shellScript).toBe(before);
});

it('Does not modify already-configured script when disableAutoUpload is false', () => {
const script = Object.assign({}, buildScriptWithSentry);
const before = script.shellScript;
modifyExistingXcodeBuildScript(script, false);
expect(script.shellScript).toBe(before);
});

Check warning on line 136 in packages/core/test/expo-plugin/modifyXcodeProject.test.ts

View check run for this annotation

@sentry/warden / warden: code-review

[JZY-6K5] `SENTRY_DISABLE_AUTO_UPLOAD=true` is never removed when `disableAutoUpload` is toggled back to `false` (additional location)

If a user sets `disableAutoUpload: true`, runs `expo prebuild`, then later changes to `disableAutoUpload: false` and re-runs `expo prebuild`, the injected `export SENTRY_DISABLE_AUTO_UPLOAD=true` line is never removed from the Xcode build phases โ€” uploads remain silently disabled. Consider adding a cleanup pass that removes the export line when `disableAutoUpload` is `false` and the line is present, or documenting that `--clean` is required to re-enable uploads.

it('addSentryWithBundledScriptsToBundleShellScript uses real newline, not literal backslash-n', () => {
const input = `"
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
"`;
const result = addSentryWithBundledScriptsToBundleShellScript(input, true);
expect(result).toContain('export SENTRY_DISABLE_AUTO_UPLOAD=true\n/bin/sh');
expect(result).not.toContain('true\\n');
});

it('Produces a valid shell script after JSON round-trip', () => {
const script = Object.assign({}, buildScriptWithoutSentry);
modifyExistingXcodeBuildScript(script, true);
const parsed = JSON.parse(script.shellScript);
const lines = parsed.split('\n');
expect(lines).toContainEqual('export SENTRY_DISABLE_AUTO_UPLOAD=true');
});
});

describe('addDisableAutoUploadToExistingScript', () => {
const debugFilesShellScript =
"/bin/sh `${NODE_BINARY:-node} --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode-debug-files.sh'\"`";

it('injects export into JSON-encoded shellScript', () => {
const script = { shellScript: JSON.stringify(debugFilesShellScript) };
addDisableAutoUploadToExistingScript(script);
const parsed = JSON.parse(script.shellScript);
expect(parsed).toMatch(/^export SENTRY_DISABLE_AUTO_UPLOAD=true\n/);
expect(parsed).toContain('sentry-xcode-debug-files.sh');
});

it('injects export into non-JSON-encoded shellScript via fallback', () => {
const script = { shellScript: debugFilesShellScript };
addDisableAutoUploadToExistingScript(script);
expect(script.shellScript).toMatch(/^export SENTRY_DISABLE_AUTO_UPLOAD=true\n/);
expect(script.shellScript).toContain('sentry-xcode-debug-files.sh');
});

it('does not duplicate export if already present in JSON-encoded script', () => {
const script = {
shellScript: JSON.stringify(`export SENTRY_DISABLE_AUTO_UPLOAD=true\n${debugFilesShellScript}`),
};
const before = script.shellScript;
addDisableAutoUploadToExistingScript(script);
expect(script.shellScript).toBe(before);
});

it('does not duplicate export if already present in raw script', () => {
const script = {
shellScript: `export SENTRY_DISABLE_AUTO_UPLOAD=true\n${debugFilesShellScript}`,
};
const before = script.shellScript;
addDisableAutoUploadToExistingScript(script);
expect(script.shellScript).toBe(before);
});

it('works on the bundle phase script format (JSON-encoded with inner quotes)', () => {
const script = Object.assign({}, buildScriptWithSentry);
addDisableAutoUploadToExistingScript(script);
const parsed = JSON.parse(script.shellScript);
expect(parsed).toMatch(/^export SENTRY_DISABLE_AUTO_UPLOAD=true\n/);
expect(parsed).toContain('sentry-xcode.sh');
});
});

describe('Upload Debug Symbols to Sentry build phase', () => {
let mockXcodeProject: any;
let addBuildPhaseSpy: jest.Mock;
Expand Down
Loading