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.
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: 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