Skip to content
Open
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
> make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first.
<!-- prettier-ignore-end -->
## Unreleased

### Features

- Add `disableAutoUpload` option to Expo plugin to disable source map and debug symbol uploads ([#6195](https://github.com/getsentry/sentry-react-native/pull/6195))

## 8.12.0

### Features
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;

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

View check run for this annotation

@sentry/warden / warden: find-bugs

`disableAutoUpload: false` does not remove the override injected by a prior `disableAutoUpload: true` run

Once `expo prebuild` is run with `disableAutoUpload: true`, the `shouldSentryAutoUploadGeneral = { -> return false }` line is permanently baked into `build.gradle`. Re-running prebuild with `disableAutoUpload: false` silently does nothing โ€” uploads remain disabled, violating user expectations.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

might be worth checking the warden checks, not sure why it didnt post as a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for catching this @lucas-zimerman. Updated with eaa6ae2

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: code-review

Switching `disableAutoUpload` from `true` back to `false` leaves uploads permanently disabled until `--clean` prebuild

Once `disableAutoUpload: true` is applied and then changed to `false`, neither the Android `shouldSentryAutoUploadGeneral` override nor the iOS `export SENTRY_DISABLE_AUTO_UPLOAD=true` injection is removed on subsequent prebuilds, so uploads remain silently disabled. Consider adding removal logic, or at minimum documenting that `--clean` is required when toggling this flag.
sentryProperties,
useNativeInit: props?.useNativeInit,
disableAutoUpload: props?.disableAutoUpload,
});
} 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, {
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 @@ -38,11 +39,17 @@
/**
* 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 }`,
);

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

View check run for this annotation

@sentry/warden / warden: find-bugs

[CVS-2BB] `disableAutoUpload: false` does not remove the override injected by a prior `disableAutoUpload: true` run (additional location)

Once `expo prebuild` is run with `disableAutoUpload: true`, the `shouldSentryAutoUploadGeneral = { -> return false }` line is permanently baked into `build.gradle`. Re-running prebuild with `disableAutoUpload: false` silently does nothing โ€” uploads remain disabled, violating user expectations.
}
return buildGradle;
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: code-review

[HPF-K3K] Switching `disableAutoUpload` from `true` back to `false` leaves uploads permanently disabled until `--clean` prebuild (additional location)

Once `disableAutoUpload: true` is applied and then changed to `false`, neither the Android `shouldSentryAutoUploadGeneral` override nor the iOS `export SENTRY_DISABLE_AUTO_UPLOAD=true` injection is removed on subsequent prebuilds, so uploads remain silently disabled. Consider adding removal logic, or at minimum documenting that `--clean` is required when toggling this flag.

// 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,8 +63,11 @@
}

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 {
Expand Down
54 changes: 44 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,22 +29,27 @@
'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;
});

const appDelegateCfc = useNativeInit ? modifyAppDelegate(xcodeProjectCfg) : xcodeProjectCfg;

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

View check run for this annotation

@sentry/warden / warden: find-bugs

[MVS-QQ9] `export SENTRY_DISABLE_AUTO_UPLOAD=true` is never removed from Xcode build phases when `disableAutoUpload` toggles back to `false` (additional location)

After running prebuild with `disableAutoUpload: true`, changing to `disableAutoUpload: false` and re-running prebuild silently keeps `export SENTRY_DISABLE_AUTO_UPLOAD=true` in both Xcode build phases, so auto-upload remains disabled.

return withDangerousMod(appDelegateCfc, [
'ios',
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: find-bugs

`export SENTRY_DISABLE_AUTO_UPLOAD=true` is never removed from Xcode build phases when `disableAutoUpload` toggles back to `false`

After running prebuild with `disableAutoUpload: true`, changing to `disableAutoUpload: false` and re-running prebuild silently keeps `export SENTRY_DISABLE_AUTO_UPLOAD=true` in both Xcode build phases, so auto-upload remains disabled.
return;
}

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

View check run for this annotation

@sentry/warden / warden: code-review

[HPF-K3K] Switching `disableAutoUpload` from `true` back to `false` leaves uploads permanently disabled until `--clean` prebuild (additional location)

Once `disableAutoUpload: true` is applied and then changed to `false`, neither the Android `shouldSentryAutoUploadGeneral` override nor the iOS `export SENTRY_DISABLE_AUTO_UPLOAD=true` injection is removed on subsequent prebuilds, so uploads remain silently disabled. Consider adding removal logic, or at minimum documenting that `--clean` is required when toggling this flag.
Expand All @@ -77,16 +87,40 @@
}

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(insertExportAfterDelimiter(code));
} catch {
script.shellScript = `${SENTRY_DISABLE_AUTO_UPLOAD_EXPORT}\n${script.shellScript}`;
}
}
Comment thread
cursor[bot] marked this conversation as resolved.

function insertExportAfterDelimiter(script: string): string {
if (script.startsWith('"')) {
const rest = script.slice(1).replace(/^\n/, '');
return `"\n${SENTRY_DISABLE_AUTO_UPLOAD_EXPORT}\n${rest}`;
}
return `${SENTRY_DISABLE_AUTO_UPLOAD_EXPORT}\n${script}`;
}

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');
});

it('Does not add shouldSentryAutoUploadGeneral override when disableAutoUpload is false', () => {
const result = modifyAppBuildGradle(buildGradleWithOutSentry, false);
expect(result).not.toContain('shouldSentryAutoUploadGeneral');

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

View check run for this annotation

@sentry/warden / warden: find-bugs

[CVS-2BB] `disableAutoUpload: false` does not remove the override injected by a prior `disableAutoUpload: true` run (additional location)

Once `expo prebuild` is run with `disableAutoUpload: true`, the `shouldSentryAutoUploadGeneral = { -> return false }` line is permanently baked into `build.gradle`. Re-running prebuild with `disableAutoUpload: false` silently does nothing โ€” uploads remain disabled, violating user expectations.
});

it('Adds override to already-configured build.gradle on re-prebuild', () => {
const result = modifyAppBuildGradle(buildGradleWithSentry, true);
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);
});
});
144 changes: 143 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 {
addDisableAutoUploadToExistingScript,

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

View check run for this annotation

@sentry/warden / warden: find-bugs

[CVS-2BB] `disableAutoUpload: false` does not remove the override injected by a prior `disableAutoUpload: true` run (additional location)

Once `expo prebuild` is run with `disableAutoUpload: true`, the `shouldSentryAutoUploadGeneral = { -> return false }` line is permanently baked into `build.gradle`. Re-running prebuild with `disableAutoUpload: false` silently does nothing โ€” uploads remain disabled, violating user expectations.

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

View check run for this annotation

@sentry/warden / warden: find-bugs

[MVS-QQ9] `export SENTRY_DISABLE_AUTO_UPLOAD=true` is never removed from Xcode build phases when `disableAutoUpload` toggles back to `false` (additional location)

After running prebuild with `disableAutoUpload: true`, changing to `disableAutoUpload: false` and re-running prebuild silently keeps `export SENTRY_DISABLE_AUTO_UPLOAD=true` in both Xcode build phases, so auto-upload remains disabled.
addSentryWithBundledScriptsToBundleShellScript,
modifyExistingXcodeBuildScript,
} from '../../plugin/src/withSentryIOS';

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

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

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).toContain('export SENTRY_DISABLE_AUTO_UPLOAD=true');
expect(parsed).toContain('sentry-xcode.sh');
expect(parsed).toMatch(/^"/);
expect(parsed).toMatch(/"$/);
});

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(/^"\nexport 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 137 in packages/core/test/expo-plugin/modifyXcodeProject.test.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

[MVS-QQ9] `export SENTRY_DISABLE_AUTO_UPLOAD=true` is never removed from Xcode build phases when `disableAutoUpload` toggles back to `false` (additional location)

After running prebuild with `disableAutoUpload: true`, changing to `disableAutoUpload: false` and re-running prebuild silently keeps `export SENTRY_DISABLE_AUTO_UPLOAD=true` in both Xcode build phases, so auto-upload remains disabled.
});

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');
});

it('Fresh-prebuild and re-prebuild both place export inside delimiters', () => {
const freshScript = Object.assign({}, buildScriptWithoutSentry);
modifyExistingXcodeBuildScript(freshScript, true);
const freshParsed = JSON.parse(freshScript.shellScript);

const rePrebuildScript = Object.assign({}, buildScriptWithSentry);
modifyExistingXcodeBuildScript(rePrebuildScript, true);
const rePrebuildParsed = JSON.parse(rePrebuildScript.shellScript);

for (const parsed of [freshParsed, rePrebuildParsed]) {
expect(parsed).toMatch(/^"/);
expect(parsed).toMatch(/"$/);
expect(parsed).toContain('export SENTRY_DISABLE_AUTO_UPLOAD=true');
expect(parsed).toContain('sentry-xcode.sh');
}
});
});

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(/^"\nexport 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